CNA-VGAP-013: No gate checks include reachability or compiles each public C++ header alone
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.
No CMake test or workflow checks that a module's includes stay inside its declared module graph or compiles each framework public C++ header in isolation; the two unwired campaign scripts written for this were removed with their archive.
- Identifier
CNA-VGAP-013- Category
- Verification gap
- Subsystem
- Build & CI
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
3b43bd86(3b43bd8687ed46523d873f9bec4b32bd8481dcb5) - Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- The physical module include contract (docs/physical-modules.md) and the self-containment of the public C++ headers
Expected behaviour
CNA's physical module split declares which module may include which (every #include "CNA/..." in a module TU should resolve through the declared module graph). A header self-containment check (each public header compiles alone against its module's include closure) is the compile-side complement of the link probes, which do exist.
Actual behaviour at TARGET
The Validators section of physical-modules.md lists the source-partition validator, the module link probes with their closure gates and the renderer-identity pin; nothing checks the include side. The two scripts written for it, check_include_reachability.py and check_header_self_containment.py, hard-coded the August 2026 module graph and were called by no CMake file or workflow; ce74063e6 (2026-10-11) removed them with the rest of the modularization/ archive, and the document no longer names them.
The only compile-side header gates that exist are narrower: ContractIsSdlFreeTests.cpp compiles all platform contract headers together in one TU, and CApiHeaderCompatibility compiles only the C headers.
Source locations
docs/physical-modules.md— Validators list: partition validator, link probes, renderer-identity pin; no include-side gatemodules/platform/tests/CNA/Platform/ContractIsSdlFreeTests.cpp— one TU including every platform contract headercmake/Tests/ModuleProbes.cmake— link probes and the CApiHeaderCompatibility registration (C headers only)
Evidence
Checked by reading physical-modules.md, ModuleProbes.cmake and the workflows at 3b43bd86 and searching cmake/, .github/workflows/, scripts/ and tools/ for an include-reachability or per-header compile gate (none). Nothing was built or executed.
Narrowed at c6dec91f: the stale-script half of this entry is gone with the scripts (ce74063e6); the missing gate is unchanged.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
Link-side closure is covered by ModuleProbes.cmake (with the caveat in CNA-VGAP-019). Nothing checks include-side reachability or per-header self-containment for the C++ surface.
Regression test
Generate the module include graph from the CMake target graph (or a configure-time export) and register a CTest case that fails when a module TU includes an undeclared module's header, plus one that compiles each public header alone; a planted violating header must fail them.
Blast radius
Any change that adds an undeclared include edge between modules, or a public header that compiles only after another include. Consumers that include a single CNA header first are the ones who would see the failure.
Workaround
No workaround is known.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Internals
- Module graph
- Known issues
- Verification gap index