CNA-BUG-058: LIMITATIONS.md omits the 468 planned C API symbols 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 009d40f5; 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 8,887 of the 9,355 declarations it counts and never mentions the 468 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
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - 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 9,355 declarations, then partitions Fully mapped 8,363, Partially mapped 15 and No C form 509: 8,887. The 468 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: “468 public symbols are still unmapped” (planned) and “509 unmapped in 83 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 the planned backlog as 134 + 3 + 1 + 5 + 5 (CBIND-125) + 320 (CBIND-127) = 468; 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 9,355.
Source locations
docs/c-api/LIMITATIONS.md— The shape of it table and the 9,355 sentencetools/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 (468 planned) and the content-pipeline exclusion
Evidence
Checked by reading LIMITATIONS.md, RELEASE_GATE.md, generate_limitations.py and plan_binding.md at 009d40f5. Not executed: the generators cannot run at this snapshot (CNA-BUG-062), so the arithmetic is taken from the committed documents. 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. Separate entries cover the same document's “Four of the 49 renderers” row and the “0.1.0” labels in FEATURE_MATRIX.md and README.md.
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