CNA-GAP-062: The C ABI has no route for 631 public C++ declarations that the coverage inventory records as planned

CNA snapshot c1c316b9  ·  Known Issues › Functional gaps  ·  source links pinned to c1c316b9

✓

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 c1c316b9; 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 631 in-scope public C++ declarations without a C mapping (graphics 255, content 204, graphics-ext 40 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 c1c316b9 (c1c316b9c7a846ce8002809c151fcd1af14942c9)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
CNA C ABI 0.46.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 (469 headers, 8,142 symbols: 7,053 implemented, 15 partial, 443 not applicable) records 631 planned rows: graphics 255, content 204, graphics-ext 40, input 32, gamer-services 26, math 26, runtime 19, net 14, audio 10, devices 2, storage 2, media 1. 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

Evidence

Checked by reading COVERAGE.md and plan_binding.md at c1c316b9; the module summary sums to 631, as RELEASE_GATE.md reports. The per-symbol matrix is generated on demand and was not generated here, so individual symbols were not listed. Not executed.

Independently observed as a separate finding (merged): docs/c-api/RELEASE_GATE.md records exactly one unmet criterion, 'No public C++ symbol is unaccounted for', with 631 planned public C++ declarations still lacking a C mapping, so the 0.46.0 C ABI remains experimental at this snapshot.

Re-verified at c1c316b9: the committed snapshot moved to 631 planned rows (7,053 implemented, 443 not applicable) and the ABI to 0.46.0; the release gate still reports the coverage criterion unmet. 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.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.