[Hooks Cannot See] (1) Teach two hooks the checks they could not see - #518
Open
EdbertChan wants to merge 1 commit into
Conversation
narrow-the-scope fired four times in one session and was wrong all four. Its VERIFY_RE knew pytest, npm test, tsc and friends, but nothing about `bash scripts/test-foo.sh` or `docker build` -- so a shell-and-container project looks exactly like an edit streak with no verification in it, and the reminder becomes noise. A detector that cries wolf trains the reader to skip it, so this adds those patterns plus one more reset rule: a Bash command naming the basename of a file in the current streak clears that file, because running the script you just edited is how this kind of work gets checked and no regex can enumerate every project's entry point. tests/fixtures/shell_verified_streak_2026-09-11.json is the verbatim sequence from that session, silent with the verification row and firing without it. hook-freshness watched the checkout behind ~/.claude/hooks for staleness but never checked that the registered hook scripts still resolve. In that same session ~/.claude/hooks/split-scope pointed into a deleted worktree: the hook was registered, could not run, and said nothing for the whole session, which is "a check that could not run is not a pass" breaking on the gates themselves. The sweep reads settings.json, expands the paths, and names every one that does not resolve. It returns three outcomes, not two -- an unreadable or unparseable settings.json reports unchecked rather than clean, which the first draft of this change got wrong until explicit-failures caught it. install.sh warns when it is linking out of a git worktree, so the next dead link is announced as it is created rather than found a session later. It deliberately does not redirect to the main checkout: tests/test_install.py:290 specifies that install.sh links against its own checkout, because installing from a worktree is how a branch gets tested. An earlier draft did redirect, and that test caught it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ZqCxSQVpmM9Rx37C7irgf Change-Id: I09fda6fc2dd315cd16eca766d881cb6f2b7306e6
Owner
Author
|
This pull request is part of a Mergify stack:
|
4 tasks
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b1a3ce57-72e1-4f61-a498-820a1697df4b) |
4 tasks
Contributor
|
Tick the box to add this pull request to the merge queue (same as
|
EdbertChan
added a commit
that referenced
this pull request
Sep 13, 2026
The summary checker now fails a Summary over 150 words and tells the writer how many words to cut. The draft-pr skill says to write the Summary with the diu skill. A new CI workflow runs the same checker on each PR's live body, including edits made on GitHub, because PR #518 was published with a summary the local checker already rejected. The merge queue now requires that check to pass, next to lint and test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014uqkMWYjsKGenUSA1CqBVv Change-Id: Ie7e51550f991022ed4a5f5a40e07613f5ee6b75e
mergify Bot
pushed a commit
that referenced
this pull request
Sep 13, 2026
The summary checker now fails a Summary over 150 words and tells the writer how many words to cut. The draft-pr skill says to write the Summary with the diu skill. A new CI workflow runs the same checker on each PR's live body, including edits made on GitHub, because PR #518 was published with a summary the local checker already rejected. The merge queue now requires that check to pass, next to lint and test. Claude-Session: https://claude.ai/code/session_014uqkMWYjsKGenUSA1CqBVv Change-Id: Ie7e51550f991022ed4a5f5a40e07613f5ee6b75e Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
Author
|
Mergify repair stopped: missing required check validate |
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
Small helper scripts watch Claude while it works and nudge it when something looks off. Two of them were blind to things they should notice.
The first nudges Claude after many edits with no testing. It missed shell test scripts and container builds, so it nagged wrongly four times.
The second checks that the helpers are current. It never checked that each one still exists. One pointed at a deleted folder and did nothing all session.
Now the first knows those test commands. The second reports missing helpers, and says "unchecked" when it cannot look. The installer warns when linking from a temporary copy.
Review Claim
Approve two detector fixes and one installer warning, each with a test that fails before the change and passes after.
Review Lane
behavior
Review Unit
engine-runtime
Safety Invariant
Both hooks stay inject-only and fail-open; neither gains the ability to block. The
hook-freshnesssweep is read-only oversettings.jsonand reports three outcomes, not two: an unreadable or unparseable file says "unchecked", never "clean".install.shchanges no link target at all — it only prints a warning, which is whytests/test_install.pystill passes unmodified.Slice Rationale
The two detector fixes and the installer warning ship together because they are the same defect class: a gate that reported clean when it had not actually looked. Splitting them would separate the finding from its evidence.
install.shis in scope because it is the cause of the dead link thathook-freshnessnow detects; the detector alone would leave the source unaddressed.Non-goals
Does not make either hook able to block. Both stay advisory.
Does not change where
install.shputs its symlinks. An earlier draft redirected a worktree install to the main checkout, andtests/test_install.py:290correctly rejected it — installing from a worktree is how a branch gets tested.Does not change
corpus/. The prose rule from the same reflect pass is slice (2), split out becausedocs/ecosystem.mdforbids engine runtime and corpus lessons in one PR.Does not add the remaining findings from that pass: the
gate-blame-needs-evidencedetector defects, the pipeline-exit-status detector, and the$PIPESTATUS-is-a-no-op-in-zsh correction. Those are a separate branch.Test Plan
Test Plan
Fail-before, with the detector reverted to
origin/mainand the new tests in place:Pass-after, on the rebased branch, exit code read off each command directly rather than off a pipeline:
Whole repo suite:
python3 -m unittest discover -s engine/hooks/narrow-the-scope/testspython3 -m unittest discover -s engine/hooks/hook-freshness/testspython3 -m unittest tests.test_install_worktree_repo_dirpython3 scripts/check_hook_test_coverage.py engine/hooks/narrow-the-scopebash scripts/run_all_tests.sh— 49 directories, 0 failuresRevert Plan
Revert Plan
git revert <sha>install.shstops printing the worktree warning. No installed link changes either way.