CNA-BUG-058: LIMITATIONS.md omits the 633 planned public C++ declarations and RELEASE_GATE.md still attributes 654 declarations to CBIND-117
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 3b43bd86; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
The generated C API limitations document partitions 7,501 of the 8,134 declarations it counts and never mentions the 633 planned ones, and the release-gate note still says the Content Pipeline task owns 654 declarations where the plan records 134.
- Identifier
CNA-BUG-058- Category
- Bug
- Subsystem
- Documentation & release tooling
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
3b43bd86(3b43bd8687ed46523d873f9bec4b32bd8481dcb5) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- docs/c-api/LIMITATIONS.md (generated by tools/c-api/generate_limitations.py) and docs/c-api/RELEASE_GATE.md (generated from tools/c-api/release_gate.json)
Expected behaviour
LIMITATIONS.md is “the document a consumer reads to decide whether to adopt the ABI at all” (release_gate.json) and says it records every declaration that “did not become a callable C route”. Its counts should add up to the inventory total, and the release-gate note should name the live owners of the unmapped backlog as the plan and inventory record them.
Actual behaviour at TARGET
LIMITATIONS.mdsays the full matrix records 8,134 declarations, then partitions Fully mapped 7,033, Partially mapped 15 and No C form 453: 7,501. The 633 planned declarations, which have no C route either, appear nowhere, becausegenerate_limitations.pyread_rows()keeps only partial and not-applicable rows.RELEASE_GATE.mduses “unmapped” for two different sets in adjacent rows: “633 public symbols are still unmapped” (planned) and “453 unmapped in 89 groups” (not applicable).- The release note (from
release_gate.json) says “Content Pipeline continuation records 654 public C++ build-time declarations under openCBIND-117” and names CBIND-120, -121 and -122.plans/plan_binding.mdrecords CBIND-117 as still owning 134 rows after the CBIND-126 scope decision moved the pipeline out of scope (COVERAGE.mdlistsmodules/content-pipelineas excluded), and its open rows as 134 + 3 + 1 + 5 + 5 (CBIND-125) + 320 (CBIND-127) = 468, whileCOVERAGE.mdnow counts 633 planned rows; the note omits CBIND-125 and CBIND-127.
Fixed since first recorded: the total is no longer a hand-written 6,415. analyze() takes it from the inventory and render() prints it, so LIMITATIONS.md and COVERAGE.md now state the same 8,134.
Source locations
docs/c-api/LIMITATIONS.md— The shape of it table and the full-matrix totaltools/c-api/generate_limitations.py— read_rows drops planned rows; analyze and render take the total from the inventorydocs/c-api/RELEASE_GATE.md— release note and the two 'unmapped' criterion rowstools/c-api/release_gate.json— release.note with the 654 figureplans/plan_binding.md— row counts of CBIND-117, CBIND-120, CBIND-121, CBIND-122, CBIND-125, CBIND-127docs/c-api/COVERAGE.md— module table (625 planned) and the content-pipeline exclusion
Evidence
Checked by reading LIMITATIONS.md, RELEASE_GATE.md, generate_limitations.py and plan_binding.md at 3b43bd86. Not executed; the arithmetic is taken from the committed generated documents (COVERAGE.md snapshot: 466 headers, 8,134 symbols, 7,033 implemented, 15 partial, 633 planned, 453 not applicable). Whether leaving planned rows out was intended is not recorded; the generator's docstring speaks of collapsing “partially mapped and unmapped symbols”, where “unmapped” means not applicable, while the document's first paragraph promises every declaration that did not become a route.
Re-verified at c6dec91f: the committed counts moved again (7,032 implemented, 625 planned, 453 not applicable), but read_rows() still drops planned rows and the release note in release_gate.json still says 654 under CBIND-117. Not executed.
Re-verified at 3b43bd86: the committed counts moved again (8,134 symbols, 7,033 implemented, 633 planned: two more graphics and six more math rows, the XmlSerializer hooks and the two new renderer features of this snapshot, planned under CBIND-127); generate_limitations.py and release_gate.json are unchanged, so planned rows are still dropped and the note still says 654 under CBIND-117. Not executed.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
CApiLimitations (generate_limitations.py --check) proves the document matches its generator and enforces themes, live owners and inventory-derived counts; no rule requires the partition to sum to the total or planned rows to be listed. CApiReleaseGate checks that RELEASE_GATE.md renders from release_gate.json, not that its prose note matches the plan.
Regression test
In generate_limitations.py, add a “Planned” row (with its owning tasks) and assert that the shape table sums to inventory_symbols; in check_release_gate.py, derive the backlog sentence from the plan's row counts instead of prose.
Blast radius
Readers deciding whether to adopt the C ABI; no behaviour is affected.
Workaround
Use COVERAGE.md's module table for the planned backlog and plans/plan_binding.md for its owners.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- C API: limits · C API: measured coverage
- Maintainer workflow
- Update the C API: the coverage inventory
- Known issues
- Bug index