Skip to content

hook: hook-freshness warns when the checkout behind the hooks is stale - #290

Open
EdbertChan wants to merge 1 commit into
mainfrom
stack/EdbertChan/reflect/ui-input-guard-hook-freshness-20260908/hook-freshness-warns-checkout-behind-hooks-stale--e2558c7a
Open

hook: hook-freshness warns when the checkout behind the hooks is stale#290
EdbertChan wants to merge 1 commit into
mainfrom
stack/EdbertChan/reflect/ui-input-guard-hook-freshness-20260908/hook-freshness-warns-checkout-behind-hooks-stale--e2558c7a

Conversation

@EdbertChan

@EdbertChanEdbertChan commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

The installed hooks are only as new as the checkout behind them. install.sh symlinks ~/.claude/hooks/<name> at a catstack checkout, so a hook fix merged on origin/main does nothing on a machine whose checkout has drifted.

That is not hypothetical. The merged UNVERIFIED: prove-it block reached a machine whose checkout sat on a feature branch, 40 commits behind origin/main. The user asked why the stop hook had not forced a verification. It was never installed.

This adds one advisory line per session naming the branch, the distance from trunk, and the two commands that fix it.

Review Claim

A stale hooks checkout announces itself once per session instead of silently disabling merged hook fixes.

Review Lane

behavior

Review Unit

tooling-policy

Safety Invariant

Advisory only: the hook returns additionalContext and never blocks a prompt. It makes no network call unless CATSTACK_HOOK_FRESHNESS_FETCH=1, times git out, and fails open on a missing symlink, a detached HEAD, a missing remote, or any subprocess error. CATSTACK_HOOK_FRESHNESS=0 silences it.

Slice Rationale

The hook ships with its own installer wiring, because the repo's install test requires every hook entrypoint to be wired in the commit that adds it. Splitting the wiring into a later slice left this one red on its own.

Non-goals

Does not fetch by default, so the count can lag a remote that moved since the last fetch. Does not check other harnesses' hook directories, and does not run install.sh for the user.

Test Plan

Test Plan
  • python3 -m unittest discover -s engine/hooks/hook-freshness/tests — 13 tests, OK
  • python3 scripts/check_hook_test_coverage.py — OK (23 hooks)
  • python3 -m unittest tests.test_install — 59 tests, OK (links the hook and asserts its UserPromptSubmit wiring)
  • python3 scripts/check_no_dated_provenance.py --base origin/main — ok

Revert Plan

Revert Plan
  • Safe to revert? Yes
  • Revert command: git revert <sha>
  • Post-revert steps: rerun ./install.sh (drops the settings.json entry), then rm -rf ~/.claude/hooks/hook-freshness
  • Data migration? No

🤖 Generated with Claude Code

https://claude.ai/code/session_01KU2pPKob4MJ1NqjsfTNyYJ

@EdbertChan

EdbertChan commented Sep 9, 2026

Copy link
Copy Markdown
OwnerAuthor

This pull request is part of a Mergify stack:

#Pull RequestLink
1hook: hook-freshness warns when the checkout behind the hooks is stale#290👈
2hook: ui-input-guard blocks synthetic input at the user's live session#291
3docs: prove UI work on a disposable surface, not the user's session#292
4hook(wrong-check-reflect): catch a concession that the user found the miss#298
5gate: an unchecked file is not a clean file#296

@cursor

cursorBot commented Sep 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot 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_6075ebf6-a809-48cd-9271-bddd8bfedfbd)

install.sh symlinks ~/.claude/hooks at a catstack checkout, so a merged hook
or skill fix is inert on a machine whose checkout sits on a feature branch or
behind origin/main. One advisory line per session names the branch, the
distance from trunk, and the two commands that fix it.
Advisory only, no network unless CATSTACK_HOOK_FRESHNESS_FETCH=1, fail-open.
Ships with its own installer wiring, since the repo's install test requires
every hook entrypoint to be wired in the commit that adds it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KU2pPKob4MJ1NqjsfTNyYJ
Change-Id: Ie2558c7af1ea3a88f5e39811340a628ccf9f7c39
@EdbertChan
EdbertChanforce-pushed the stack/EdbertChan/reflect/ui-input-guard-hook-freshness-20260908/hook-freshness-warns-checkout-behind-hooks-stale--e2558c7a branch from 817ee2a to 2d1bff8CompareSeptember 9, 2026 06:22
@cursor

cursorBot commented Sep 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot 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_10bac660-3242-40a6-8e1d-ae3756bc5811)

@EdbertChan

Copy link
Copy Markdown
OwnerAuthor

Revision history

#TypeChangesReasonDate
1initial817ee2a2026-09-09 06:22 UTC
2content817ee2a → 2d1bff8 (raw)2026-09-09 06:22 UTC

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@EdbertChan