feat: auto-pull claude-custom main at session start #165
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/claude-custom!165
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "164-session-start-auto-pull"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
SessionStart hook now auto-pulls claude-custom main so newly merged hooks and settings.json are live without manual
git pull. Prevents the stale-hook gap that allowed two unapproved GroupMe messages (2026-03-25 incident).Changes
hooks/check-claude-custom-clean.sh-- Addedgit fetch origin main && git pull origin main --ff-onlybefore the dirty-state check. Four scenarios handled:Test Plan
Review Checklist
hooks/check-claude-custom-clean.sh)--ff-onlyto avoid merge commitsRelated
Review: LGTM
Acceptance criteria: All four met. Pull happens before dirty check, ff-only enforced, failures warn-only, existing dirty-state warning preserved.
Correctness:
set -euo pipefail+ conditional wrapping (if/if !) means non-zero git returns are handled by branching logic, not byset -e. Correct.branch --show-current, fallback to"unknown", skips pull block. Correct.BRANCHcomputed once, reused in dirty-state section. No redundant git calls.Observation (not a blocker): On main with dirty tracked files, two warnings appear: "skipping auto-pull" (line 23-27) and the file-list warning (line 48-57). This is intentional -- different information in each (skip reason vs. file list).
Scope: Single file changed, matches issue spec exactly. No unrelated changes.
No fixes needed.
PR #165 Review
DOMAIN REVIEW
Tech stack: Bash shell script (Claude Code SessionStart hook).
The script adds an auto-pull mechanism to
hooks/check-claude-custom-clean.shthat fetches and fast-forwards~/claude-customon main before the existing dirty-state check runs. Four scenarios are handled: dirty working tree (skip pull), clean main (pull), diverged main (warn), and network failure (warn). All paths exit 0 -- the session is never blocked.Shell correctness:
set -euo pipefailis present and all git commands are properly guarded:|| echo "unknown",|| true, andifconditionals prevent-efrom terminating the script on expected failures. Correct.2>/dev/nullon git commands suppresses stderr noise from network or auth failures. Appropriate for a SessionStart hook.--ff-onlyprevents accidental merge commits on main. Correct.BRANCHis computed once at the top and reused in both the auto-pull section and the dirty-state section, avoiding the previous duplication inside theifblock. Clean refactor.Fail-open design: Every error path emits a warning and continues. The
exit 0at the bottom is preserved. This matches the hook contract (warn, never block).Hook ordering observation: This hook is the second in the SessionStart array (after
session-start-context.sh). Ideally auto-pull would run first so that any merged changes to other hooks or config take effect before they execute. However, sincesettings.jsonis only parsed once at session init time, reordering within the current session would not pick up settings changes anyway. The current placement is acceptable -- the pull ensures the NEXT session gets the latest hooks. Not a blocker.BLOCKERS
None.
NITS
Dual warning on dirty main: When on main with uncommitted tracked changes, the user sees two warnings: (a) "skipping auto-pull" from the new code, then (b) the detailed file list from the existing dirty-state check. Both are useful (one explains the pull skip, the other gives the file list), but they could be consolidated into a single message. Low priority -- the current behavior is clear enough.
Fetch failure message could be more precise: The warning
"fetch failed (network issue?)"assumes network failure, but auth errors or misconfigured remotes would also hit this path. Consider"fetch failed (network or remote issue?)"for slightly better diagnostic guidance. Very minor.DIRTY_TRACKEDvsDIRTYnaming: The auto-pull section usesDIRTY_TRACKEDand the bottom section usesDIRTY, but both use the same filter (grep -v '^??') -- they are semantically identical. The naming difference suggests they differ when they do not. Consider using the same variable name, or computing it once and reusing it (for the main-branch case). Minor clarity improvement.SOP COMPLIANCE
164-session-start-auto-pullreferences #164feat: auto-pull claude-custom main at session start)PROCESS OBSERVATIONS
This PR directly addresses the stale-hook gap that allowed the GroupMe incident (#160). The change is minimal, well-scoped, and fail-safe. Deployment frequency impact: positive -- merged hook improvements propagate automatically without manual
git pull, reducing the window where a session runs stale hooks. Change failure risk: low -- all error paths are non-blocking with clear user guidance.VERDICT: APPROVED