fix(hooks): make driftcheck a nudge and close two silent-failure modes - #70
Merged
Merged
Conversation
Closes #69, closes #67. The Stop hook blocked with exit 2 on any shebang/exec-bit inconsistency, forcing the agent to act on findings before it could finish. For a style check that is heavy-handed: a false positive (paths that drifted outside a repo's .driftcheckignore globs) pressures the agent toward the mechanical chmod +x, which can be exactly the wrong action. Drift is now reported as hook JSON on stdout with exit 0, plus human-readable lines on stderr for direct runs. Two failure modes bypassed the old exit-2 trap, both now fixed: - git ls-files failure was invisible. Process substitution hides the exit status from pipefail and the ERR trap, so a corrupt index yielded zero lines and a clean pass — all-clear having checked nothing. The listing is captured before the loop; failure exits 1. - Unset HOME tripped set -u at expansion time and terminated before the ERR trap with a bare "HOME: unbound variable". Now an explicit exit 1. Exit 1 is the new "the check could not run" signal; the ERR trap is gone, so internal errors never block a stop either. validate.sh gains four driftcheck regression tests, each verified to fail against the pre-fix hook: flags a shebang script missing its execute bit, honors .driftcheckignore (parsing a revert dropped silently once before), fails loudly on a corrupt git index, and fails deliberately with HOME unset. Co-Authored-By: Claude Opus 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.
Closes #69. Closes #67.
Both issues live in
agentic-ai/Claude/hooks/driftcheck.sh, so they're fixed together.#69 — nudge instead of block
The Stop hook exited 2 on any shebang/exec-bit inconsistency, blocking the agent from
finishing until it acted on the findings. For a style check that's heavy-handed: a false
positive (paths that drifted outside a repo's
.driftcheckignoreglobs) pressures theagent toward the mechanical
chmod +x, which for intentionally non-executable sourcedscripts is exactly the wrong action.
Findings now go out as hook JSON with exit 0, plus human-readable lines on stderr for
direct runs:
trap 'exit 2' ERRis gone, so internal script errors can't block a stop either.#67 — two failure modes bypassed the exit-2 trap
git ls-filesfailure was invisible. Process substitution hides the exit statusfrom
pipefailand theERRtrap, so a corrupt index yielded zero lines and a clean"no violations" pass — a guard reporting all-clear having checked nothing. The listing
is captured before the loop and a failure exits 1.
HOMEexited 1, not 2.set -utreats it as an expansion error andterminates before the
ERRtrap fires. Now an explicit, diagnosed exit 1.Exit 1 is the new "the check could not run" signal. This hook no longer uses exit 2 at all.
Tests
validate.shgains fourdriftcheck.shregression tests, each verified to fail againstthe pre-fix hook (the two silent-failure bugs are precisely the class that hides from a
run-it-and-see check):
The
.driftcheckignoretest covers #69's note that the ignore parsing was silentlydropped by a revert once before. The existing repo-state check now distinguishes three
outcomes: fail on non-zero exit, warn on reported drift, pass on clean.
Full
validate.shpasses;shellcheck --severity=warningclean on both changed scripts.Docs
agentic-ai/Claude/README.mdhook section, theTODO.mdmanual-check line, and adocs/CHANGELOG.mdentry.Note
~/.claude/hooks/driftcheck.shsymlinks into the working tree, so the new behavior islive on whatever branch is checked out — merging this makes it the default again.
🤖 Generated with Claude Code