Blocks every cpp/** PR in milestone #63. All three open Wave 1 PRs (#2807, #2809, #2816) fail the same check, C++ Integration Tests (STX), and none of them for a reason related to their changes — the build never reaches compilation.
Symptom
CMake Error: Could not find CMAKE_ROOT !!!
CMake has most likely not been installed correctly.
Modules directory not found in
C:/Windows/Temp/cmake/cmake-3.31.4-windows-x86_64/share/cmake-3.31
CMake Error: Error executing cmake::LoadCache(). Aborting.
Root cause
.github/workflows/build_cpp.yml:196-221. The job caches CMake under $env:TEMP and decides whether to re-download with:
$cmakeCached = "$env:TEMP\cmake\cmake-${cmakeVer}-windows-x86_64\bin"
...
} elseif (Test-Path "$cmakeCached\cmake.exe") {
echo "$cmakeCached" >> $env:GITHUB_PATH
}
if (-not (Get-Command cmake ...) -and -not (Test-Path "$cmakeCached\cmake.exe")) {
# download + Expand-Archive
}
The validity check tests the wrong artifact. It confirms bin/cmake.exe exists but never confirms share/cmake-3.31/Modules/ — which is what CMAKE_ROOT actually resolves to. On this self-hosted runner Windows Temp cleanup (or a partial extraction) removed share/ and left bin/. The guard therefore sees a healthy cache, skips the re-download, prepends a broken CMake to PATH, and every subsequent run fails identically until somebody clears the temp directory by hand.
This is the failure mode CLAUDE.md's no-silent-fallbacks rule exists for: a cache-validity shortcut that silently substitutes a broken tool instead of failing loudly or repairing itself.
Fix
- Validate what you actually depend on. Replace the
cmake.exe-only check with a real probe — assert share/cmake-<major.minor>/Modules exists, and/or run cmake --version and require exit 0. If either fails, treat the cache as absent and re-extract.
- Make re-extraction self-healing — remove the stale directory before
Expand-Archive so a partial extraction cannot persist across runs.
- Do not cache into
$env:TEMP on a self-hosted runner. Temp is subject to OS cleanup that will keep re-creating this. Use a runner-persistent tools directory the job controls.
- Consider
lukka/get-cmake or an equivalent pinned action rather than hand-rolled download/extract logic.
Acceptance
Found during the milestone #63 orchestration sweep. Plan: docs/plans/cpp-framework-parity.md
Blocks every
cpp/**PR in milestone #63. All three open Wave 1 PRs (#2807, #2809, #2816) fail the same check,C++ Integration Tests (STX), and none of them for a reason related to their changes — the build never reaches compilation.Symptom
Root cause
.github/workflows/build_cpp.yml:196-221. The job caches CMake under$env:TEMPand decides whether to re-download with:The validity check tests the wrong artifact. It confirms
bin/cmake.exeexists but never confirmsshare/cmake-3.31/Modules/— which is whatCMAKE_ROOTactually resolves to. On this self-hosted runner Windows Temp cleanup (or a partial extraction) removedshare/and leftbin/. The guard therefore sees a healthy cache, skips the re-download, prepends a broken CMake toPATH, and every subsequent run fails identically until somebody clears the temp directory by hand.This is the failure mode CLAUDE.md's no-silent-fallbacks rule exists for: a cache-validity shortcut that silently substitutes a broken tool instead of failing loudly or repairing itself.
Fix
cmake.exe-only check with a real probe — assertshare/cmake-<major.minor>/Modulesexists, and/or runcmake --versionand require exit 0. If either fails, treat the cache as absent and re-extract.Expand-Archiveso a partial extraction cannot persist across runs.$env:TEMPon a self-hosted runner. Temp is subject to OS cleanup that will keep re-creating this. Use a runner-persistent tools directory the job controls.lukka/get-cmakeor an equivalent pinned action rather than hand-rolled download/extract logic.Acceptance
share/deleted butbin/cmake.exepresent, the job detects the broken cache and repairs it instead of failing.Modules/— otherwise the next person simplifies it back toTest-Path cmake.exe.Found during the milestone #63 orchestration sweep. Plan:
docs/plans/cpp-framework-parity.md