Repository navigation
Make the verdict-review-gate and claude-lane tests hermetic against global git hooks - #204
Merged
seathatflowsinourveins merged 1 commit intoSep 24, 2026
Conversation
…lobal git hooks On a host with a global core.hooksPath and ignore file (a managed ~/.config/git), clean main failed locally: 46 errors in tests.test_verdict_review_gate and 1 failure in tests.test_claude_lane. CI runners have no global git config and stayed green. GateFixture.git and the read tracer dropped every inherited GIT_* variable, including the GIT_CONFIG_GLOBAL and GIT_CONFIG_NOSYSTEM that #181 sets. So fixture commits ran the global gitleaks pre-commit hook, which flagged synthetic fixture digests as generic-api-key. The gate's own git_environment() drops them as well, so its head worktree ran the global post-checkout hook. The claude-lane failure is not a hook. Git reads $XDG_CONFIG_HOME/git/ignore as the default core.excludesFile whatever GIT_CONFIG_GLOBAL says. The managed ignore file lists .claude/settings.local.json, which hid the test's local settings file from claude_lane.py's git status check. tests/__init__.py now sets core.excludesFile and core.attributesFile to /dev/null in the hermetic global file. It also provides hermetic_git_environment(), which drops inherited GIT_* routing variables but keeps the hermetic configuration. The gate tests use it for their helpers and patch gate.git_environment with it. Production code and the global hooks are unchanged. test_hermetic_git gains a reusable hostile HOME (hooks that all exit 1, an ignore file matching everything, a hostile attributes file) and a non-vacuous control. It runs the gate's head-worktree test and the claude-lane BIND-R4-8 test under that HOME. The evidence manifest records the new tests/__init__.py bytes. Refs #179, #181 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
seathatflowsinourveins
deleted the
claude/hermetic-git-review-gate-20260924
branch
September 24, 2026 17:48
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.
Summary
This finishes the job #181 started (Fixes #179 there). On a host with a global
core.hooksPathand ignore file, as the agent-ecosystem-managed~/.config/githas, cleanmainfails locally:tests.test_verdict_review_gatetests.test_claude_laneCI runners have no global git config, so CI stays green. The global hook stays strict. This PR adds no hook exemption; it fixes the tests.
Causes
test_verdict_review_gateGateFixture.gitand the read-tracer subprocess drop every inheritedGIT_*variable. That includes theGIT_CONFIG_GLOBAL/GIT_CONFIG_NOSYSTEMthat Make tests hermetic against global and system git config #181 sets.generic-api-key, for example"packet_keys_sha256"in the scratchrun-manifest.json, and blocked 46 fixture commits.git_environment()drops those variables too. Sogate.main --headalso ran the globalpost-checkouthook in its head worktree; a failing hook there failsgit worktree add.test_claude_lane: not a hook.$XDG_CONFIG_HOME/git/ignore(~/.config/git/ignore) as the defaultcore.excludesFile, andGIT_CONFIG_GLOBALdoes not change that..claude/settings.local.json. Soclaude_lane.py'sgit status --porcelain -- .claude …did not see the test's local settings file and returned 0 instead of 2.Changes
tests/__init__.pycore.excludesFileandcore.attributesFileto/dev/null. These are the two XDG defaults thatGIT_CONFIG_GLOBALdoes not replace.hermetic_git_environment():os.environwithout inheritedGIT_*routing variables, with the hermetic configuration applied again.tests/test_verdict_review_gate.pyGateFixture.gitandtrace()usehermetic_git_environment().GateFixture.setUppatchesgate.git_environmentwith it, so the gate's own git calls on the scratch repository are hermetic too, includingworktree add. Routing variables are still dropped.scripts/verdict_review_gate.py,claude_lane.py) is unchanged.tests/test_hermetic_git.pyhostile_home()fixture: every hook exits 1 via~/.gitconfigand$XDG_CONFIG_HOME/git/config, the ignore file is*, and the attributes file is* hostile.hermetic_git_environment()dropsGIT_DIR/GIT_INDEX_FILEand keeps the hermetic config.test_head_revision_is_checked_in_a_temporary_worktreeand the claude-lane BIND-R4-8 test under the hostile HOME.manifests/evidence.json: new sha256 and byte count fortests/__init__.pyonly.Local reproduction
Environment: macOS arm64, Apple Git 2.50.1, Python 3.13.15. Command:
uv run --no-project --python 3.13 python -m unittest tests.test_verdict_review_gate tests.test_claude_lane tests.test_hermetic_git3699012~/.config/git/hooks/*exits 1, ignore*The two new module-level hostile tests fail against main's
tests/__init__.pyand gate test module, and pass on this branch:git initis aborted by the hostilereference-transactionhook.Other checks, all local:
scripts/validate.pypassed..gitleaks.tomloverorigin/main..HEAD: no leaks. The commit also passed the strict global pre-commit guard.python -m unitteston this branch (rebased on149940a): 4324 tests, 522 skipped, 1 failure. The failure istest_adoption_bootstrap_macos…test_install_path_with_shell_syntax_is_data_in_the_wrapper. It fails the same way with main'stests/__init__.py: SIP stripsDYLD_LIBRARY_PATHthrough/bin/shon this Mac, so it predates and is unrelated to this change.Follow-ups (not in this PR)
claude_lane.py's BIND-R4-8 check (git status --porcelain -- .claude CLAUDE.md AGENTS.md) honours the operator's global excludes. On a host whose~/.config/git/ignorelists.claude/settings.local.json, a local settings file in the agent-lab checkout is therefore not reported. The check may want--ignored, or an explicitcore.excludesFile.tests/test_workflow_hardening.pyandtests/test_osv_lockfile_coverage.pyuse the sameGIT_*-stripping idiom and pass here. They can adopthermetic_git_environment()separately.Refs #179, #181
🤖 Generated with Claude Code