CNA-GAP-062: The C ABI has no route for 633 public C++ declarations that the coverage inventory records as planned
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.
COVERAGE.md records 633 in-scope public C++ declarations without a C mapping (graphics 252, content 203, graphics-ext 36 and smaller tails in nine other modules), which is why the C ABI release gate reads Not ready.
- Identifier
CNA-GAP-062- Category
- Functional gap
- Subsystem
- C API & bindings
- Status
- Open
- Verified against
- CNA
3b43bd86(3b43bd8687ed46523d873f9bec4b32bd8481dcb5) - Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- CNA C ABI 0.50.0 (modules/c-api/include/CNA/C) against the public C++ surface of the modules it links
Expected behaviour
The release gate's coverage-closed criterion: every in-scope public C++ declaration has a C route, an owner-approved partial mapping, or a recorded reason for having no C form.
Actual behaviour at TARGET
COVERAGE.md (466 headers, 8,134 symbols: 7,033 implemented, 15 partial, 453 not applicable) records 633 planned rows: graphics 252, content 203, graphics-ext 36, input 32, math 32, gamer-services 28, runtime 19, net 14, audio 11, devices 2, media 2, storage 2. owner_task in generate_coverage_inventory.py names an open task for every row: CBIND-127 (runtime surface that grew after the binding campaign closed) by default, and CBIND-117, CBIND-120, CBIND-121, CBIND-122 and CBIND-125 for the slices and symbols they own. The per-task counts in plans/plan_binding.md predate the later GamerServices/Net and graphics work and no longer sum to the measured figure. A C caller cannot reach these declarations through the ABI; the C++ API provides them.
Source locations
docs/c-api/COVERAGE.md— Snapshot line and module summary tableplans/plan_binding.md— rows of CBIND-117, CBIND-120, CBIND-121, CBIND-122, CBIND-125, CBIND-127docs/c-api/RELEASE_GATE.md— the coverage-closed criterion, not mettools/c-api/generate_coverage_inventory.py— owner_task and planned_mappingtools/c-api/check_release_gate.py— check_coverage_has_no_planned_rows
Evidence
Checked by reading COVERAGE.md, RELEASE_GATE.md and plan_binding.md at 3b43bd86; the module summary sums to 633, as RELEASE_GATE.md reports (“633 public symbols are still unmapped”, its one unmet criterion). The per-symbol matrix is generated on demand and was not generated here, so individual symbols were not listed. Not executed.
Re-verified at c6dec91f: the committed snapshot moved from 631 to 625 planned rows (graphics 255 to 250, content 204 to 203, graphics-ext 40 to 36; gamer-services, audio and media each grew by one or two) and the ABI from 0.46.0 to 0.50.0; the release gate still reports the coverage criterion unmet. Not executed.
Re-verified at 3b43bd86: the snapshot moved from 625 to 633 planned rows (graphics 250 to 252, math 26 to 32: the XmlSerializer<Color|Rectangle|Point> hooks and RendererFeature::MultiSampleMask/RenderTargetReadback, owned by CBIND-127); the release gate still reports the coverage criterion unmet and the C ABI is still 0.50.0. Not executed.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
CApiCoverageMatrix and CApiReleaseGate measure the backlog; .github/workflows/c-api-coverage-gate.yml runs the coverage --check.
Regression test
Each owning task closes with pure-C tests for its routes (the route-test ratchet already requires a caller), and the release gate's coverage-closed criterion turns met.
Blast radius
C and binding consumers that need any unbound declaration (for example ShaderPackageEXT/ShaderCodeEXT, CNB Model-v2 decoding or the smaller seams); the bound XNA-shaped surface is unaffected.
Workaround
Use the C++ API for those declarations, or generate build/c-api/COVERAGE_FULL.md with generate_coverage_inventory.py --write to see the exact rows.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- C API: measured coverage · C API: status
- Maintainer workflow
- Update the C API: the coverage inventory
- Known issues
- Functional gap index