CNA-VGAP-019: The HEADLESS native-SDK-free link-closure gates run in no CI job

CNA snapshot 3b43bd86  ·  Known Issues › Verification gaps  ·  source links pinned to 3b43bd86

✓

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 link-closure check reads a Ninja tree's link line, so general-tests-ci.yml evaluates its OPENGLES3 tree's gates; the NativeSdkFree_* and GraphicsNativeSdkFree gates exist only in single-renderer HEADLESS trees, which no CI job tests through ctest.

Identifier
CNA-VGAP-019
Category
Verification gap
Subsystem
Testing & evidence
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 ModuleLinkClosure_NativeSdkFree_* and ModuleLinkClosure_GraphicsNativeSdkFree CTests registered by cmake/Tests/ModuleProbes.cmake

Expected behaviour

ModuleProbes.cmake describes each probe and its ModuleLinkClosure_* partner as "turning every module's real dependency closure into a permanent contract", and check_module_link_closure.py as "a permanent, mechanically checked contract": for example probe_math may link nothing but the math archive and Sharp Runtime, and the HEADLESS tree must show that renderer-neutral graphics needs no native graphics SDK. A contract of that kind is evidence only if some routine run evaluates it.

Actual behaviour at TARGET

check_module_link_closure.py reads link.txt or, in a single-config Ninja tree, the target's final command from ninja -t commands -s, and returns 77 only when neither exists, so the unfiltered ctest of general-tests-ci.yml (Ninja, OPENGLES3) evaluates every closure gate that tree registers. ModuleProbes.cmake registers the native-SDK-free gates (ModuleLinkClosure_NativeSdkFree_*, ModuleLinkClosure_GraphicsNativeSdkFree) only when CNA_GRAPHICS_RENDERER is HEADLESS without multi-renderer. The CI jobs that configure a HEADLESS tree leave these gates out: gltf-renderer-stride-ci.yml runs ctest -L gltf-conformance, platform-ci.yml only the CnaPlatform* suites, and multi-renderer-ci.yml's single-renderer HEADLESS control builds only CnaTests and runs the binary directly.

Source locations

Evidence

Checked by reading check_module_link_closure.py, ModuleProbes.cmake and every workflow under .github/workflows for its renderer, generator and ctest selection at 3b43bd86; not executed.

Narrowed at c1c316b9: 12ab7471b (AM4-167) added ninja_link_line, so the gates no longer report SKIP in a single-config Ninja tree; CNA records 28 of 28 gates measured and passing on its Mac (plans/plan_apple_m4.md, AM4-167). A multi-config generator still gets exit 77.

Re-verified at c6dec91f: the second gate this entry tracked belonged to a renderer retired on 2026-10-13 (fe5e25994) and is gone with it; the HEADLESS gates are still selected by no CI job.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

The gates are the tests. The OPENGLES3 tree's gates (ModuleLinkClosure_probe_math, _probe_storage and the rest) run in general-tests-ci.yml; the HEADLESS gates run only where someone runs ctest by hand in such a tree.

Regression test

Add -R '^ModuleLinkClosure_' to a single-renderer HEADLESS cell (for example in gltf-renderer-stride-ci.yml), or give the gates a label one of those jobs already selects.

Blast radius

Evidence only: a native graphics SDK leaking into the renderer-neutral HEADLESS closure would not be caught by any automated run. No shipped behaviour is affected.

Workaround

Evaluate the gates in a single-renderer HEADLESS tree configured with CNA_BUILD_TESTS=ON: ctest -R '^ModuleLinkClosure_'.

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

Reference
Test targets