The Machine: Ensure we don't run Stop hook without changes#786
Conversation
There was a problem hiding this comment.
Approved
Clean, well-structured change. The four-way change detection (committed vs origin/main, unstaged, staged, untracked) correctly covers all cases where files could have been modified. The fallback to run verification when origin/main can't be resolved is the right safe default.
CLAUDE.md compliance: ✅ No issues — .sh files don't require license headers, no import boundary concerns, no domain code requiring DDD review.
No blocking issues found.
Minor suggestion (non-blocking)
- If
origin/mainhasn't been fetched recently, theHEADvsorigin/maincomparison could be stale. In practice this is fine since the fallback runs full verification, but a comment noting this assumption could help future readers.
There was a problem hiding this comment.
Adversarial Review
Critical / High
None found.
Medium
.claude/hooks/stop-verify.sh:11—git diff HEAD origin/mainfails if HEAD is unborn (empty repo with no commits)- If this script runs in a freshly
git init'd repo withorigin/mainset but no local commits,git diff --quiet HEAD origin/mainwill fail withfatal: ambiguous argument 'HEAD'because HEAD doesn't point to a valid commit. Withset -e, this would terminate the script with a non-zero exit, potentially blocking Claude from completing. - Breaking example:
git init && git remote add origin <url> && git fetch origin— noworigin/mainexists but HEAD is unborn. Therev-parse --verify origin/mainguard passes, then thegit diff HEAD origin/maincrashes. - Suggested fix: Add
git rev-parse --verify HEAD >/dev/null 2>&1to the guard clause, or put the entireelifchain inside theifblock that already validatesorigin/main. - Practical likelihood: Very low in a Claude Code session (you'd always have at least an initial commit), which is why this is Medium not High.
- If this script runs in a freshly
Low
- Stale
origin/mainref could cause unnecessary verification runs — If the localorigin/maintracking ref is behind the actual remote (no recentgit fetch),git diff HEAD origin/mainmay show spurious differences, causing verification to run unnecessarily. This is the safe direction (extra work, not skipped verification) and is inherent to any local-ref-based approach, so not actionable.
Verdict
PASS — The logic is correct for all realistic scenarios. The conditional structure properly handles the set -e interaction (conditionals are exempt), the fallback when origin/main is missing is safe (run verification), and all four change-detection checks (committed diff, unstaged, staged, untracked) cover the relevant categories. The unborn-HEAD edge case is theoretical in this context.
No description provided.