guard: ci_gate_runability verdicts are location-independent (removes surviving temp-dir fail-open) - #726
Open
matt82198 wants to merge 5 commits into
Open
guard: ci_gate_runability verdicts are location-independent (removes surviving temp-dir fail-open)#726matt82198 wants to merge 5 commits into
matt82198 wants to merge 5 commits into
Conversation
check_workflow() carried a second copy of the Windows temp-dir exemption that 6afb94b deleted from find_file_on_disk(): the missing-file check (c) ran only when the resolved repo root did NOT contain both 'AppData' and 'Temp'. Two byte-identical fixtures therefore produced different verdicts -- [OK] rc0 under a temp-shaped path, "references missing file" rc1 outside it -- and any runner whose workspace lives under such a path silently lost file-existence checking entirely. The file's own comment at find_file_on_disk() forbids exactly this. The exemption originally existed because tests/test_ci_gate_runability.py built workflow fixtures in temp dirs that cited tools/*.py the fixture never created. 6afb94b already solved that correctly on the test side: the fixture harness stubs every tools/*.py its workflow references. No CWD/path sniffing and no new skip flag is needed -- a skip flag would just re-introduce the fail-open. TDD: TestCIGateRunabilityLocationIndependence reproduces first. Roots are built at <tmp>/AppData/Temp/repo (trigger-shaped on every OS, so the repro is red on Linux CI too, not only Windows) and <tmp>/ordinary/workspace/repo, and the tests assert identical verdicts, that a missing file is flagged under a temp-shaped root, and that a present file stays clean (no inverted false positive). A static scan of the module source fails on any future copy of the path sniff. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…: lines #751 moved the per-tool index out of tools/CLAUDE.md into each tool's own INDEX: header line, from which tools/INDEX.md is generated, because the inline list was the top merge-queue conflict surface. This branch was cut before that and still carried its documentation update as an edit to the old inline list. Resolved by taking main's 33-line tools/CLAUDE.md and porting this branch's updated description(s) into the tool's own INDEX: line, then regenerating tools/INDEX.md: ci_gate_runability.py No documentation content lost; only the obsolete inline index lines are gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dir-failopen # Conflicts: # tools/INDEX.md
…-sniff scan The extracted INDEX: docstring line quoted the removed temp-dir sniff verbatim, so the tool's own static no-path-sniffing guard flagged its documentation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (VERIFIED P1, regression lens)
tools/ci_gate_runability.pycarried a second copy of the Windows temp-dir exemption that commit6afb94baclaims to have deleted.6afb94baremoved it fromfind_file_on_disk()but missed the copy incheck_workflow():The gate's verdict therefore depended on where the checkout lives on disk, not on what it contains. Byte-identical fixtures:
C:\Users\...\AppData\Local\Temp\tmpXXXX[OK] All CI gates are runnable on PR events— rc 0C:\Users\...\aesop-repro-nontemp... references missing file: tools/verify_definitely_missing.py— rc 1find_file_on_disk()'s own comment (:253-259) forbids exactly this. The gate is a blocking step inci.yml, so this is fail-open on any runner whose workspace sits under a temp-shaped path — the "green can mean never ran" incident class this Guardrail (G2.5) exists to prevent.Why the exemption existed, and the correct replacement
Test fixtures built workflow YAML in temp dirs citing
tools/*.pythe fixture never created, so check (c) reported them missing. The exemption made the gate recognise its own fixtures.6afb94baalready fixed this correctly on the test side: the fixture harness stubs everytools/*.pyits workflow references (tests/test_ci_gate_runability.py:38-47). So the right replacement was already on disk — the surviving copy is pure dead fail-open. No--rootchange and no new skip flag is needed; a skip flag would just re-introduce the hole.TDD
Reproduced first —
TestCIGateRunabilityLocationIndependencewas RED on 2 of 4 before the fix:Roots are built at
<tmp>/AppData/Temp/repo— trigger-shaped on every OS, so the repro is red on Linux CI too, not just Windows — and at<tmp>/ordinary/workspace/repo. The four tests assert:Verification
tests.test_ci_gate_runability: 23/23 OKnode --testIPC flake (fleet-cli.test.mjs: "Unable to deserialize cloned data"); isolated re-run 7/7, rc 0ci_gate_runability(real repo clean),verify_test_suite_count --check,claudemd_lint,claudemd_contract,claudemd_sync_gate --check,encoding_lint,watcher_linter --check,verify_test_coverage --check,spec_contract_validator --check,workflow_model_linter --check,subprocess_guard --check --baseline .subprocess-guard-baseline.jsonsecret_scan --stagedrc 0; pre-push gates greentools/CLAUDE.mdalso corrects a stale claim on the same entry ("staged (wire into ci.yml after #596)" — it is wired,ci.yml:148) and records the location-independence invariant.🤖 Generated with Claude Code