Section 02: No-Side-Effect-Hooks Rule
Status: Not Started Goal: A hook is a pure gate. Author the rule SSOT, then convert every mutating hook (regenerate + stage at commit) to verify-only (fail-on-stale, never write).
Success Criteria:
-
.claude/rules/no-side-effect-hooks.mdSSOT defines: hooks verify→pass/reject; mutation/staging banned. - Mutating lefthook hooks (bug-tracker
render --write-back && git add,render-index) converted to fail-on-stale verify-only. - Commit-time
reviewed_field_guard.pylefthook entry removed (superseded by §01 + §04). -
STRUCTURE:hook-side-effectreviewer label + cure; audit finds zero hook-body mutation.
Context: Hooks that --write-back and git add regenerated content mutate tracked plan files as a hidden side-effect of committing — a write the user never approved. A hook must only verify and reject.
Depends on: None.
Intelligence Reconnaissance
Queries run 2026-05-26:
scripts/intel-query.sh search "lefthook hook write-back side-effect"— N/A on the Rust-only code-symbol graph; this section toucheslefthook.yml,.claude/hooks/,.claude/rules/. Recorded per plan-schema non-Rust allowance.- Direct grounding (this session):
lefthook.ymlline ~77 runspython3 -m scripts.plan_corpus.bug_tracker.render --mode=by-subsystem --split-per-section --write-back && git add bug-tracker/section-*.md; arender-indexhook regeneratesindex.mdon stagedplan.jsonchange;reviewed-field-guardrunspython3 -m scripts.plan_corpus.reviewed_field_guardat pre-commit.
Results summary [ori]: three mutating/at-commit hooks to address — bug-tracker render (--write-back && git add), render-index, reviewed_field_guard (removed, not converted — its enforcement moves to §01+§04). Verify-only conversion = run the renderer in --check mode; FAIL with “run render --write-back then re-commit” when output is stale.
02.1 Author no-side-effect-hooks rule SSOT
File(s): .claude/rules/no-side-effect-hooks.md (new)
- Author the rule: hooks (PreToolUse, pre-commit, commit-msg, any) MUST be pure gates — read state, verify, emit pass/reject + reason; NEVER write/stage/mutate. A hook needing regenerated output FAILS-on-stale with an explicit “run X to regenerate, then re-commit” message.
- Define reviewer enforcement:
STRUCTURE:hook-side-effect(severity + trigger: any hook body that writes/stages/git adds) + cure pointer. - Cross-reference:
state-discipline.md(plan file SSOT),skill-control-contract.md,workflow-ownership.md. - Subsection close-out (02.1) — MANDATORY before 02.2:
- Tasks
[x];python3 scripts/prose-lint.py .claude/rules/no-side-effect-hooks.mdexit 0. - Update subsection
status→complete. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check.
- Tasks
02.2 Convert mutating hooks to verify-only
File(s): lefthook.yml; scripts/plan_corpus/bug_tracker/render.py (add/confirm --check); the render-index hook
- Convert the bug-tracker render hook: replace
render ... --write-back && git add ...with a--checkinvocation that exits non-zero + prints the regenerate command when output is stale. No write, no stage. - Convert the
render-indexhook to--checkfail-on-stale (no write-back). - Remove the
reviewed-field-guardlefthook entry (its enforcement is §01 write-time deny + §04 read-time rejection). Note the removal in the rule’s HISTORY/cross-ref so the supersession is traceable. - Audit:
grep -nE "write-back|git add" lefthook.ymlreturns zero hook-body matches. - Subsection close-out (02.2) — MANDATORY before 02.N:
- Tasks
[x]; a deliberately-stale render FAILS the hook with the regenerate message (verified). - Update subsection
status→complete. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check.
- Tasks
02.N Completion Checklist
- 02.1–02.2
[x]and statuscomplete. -
.claude/rules/no-side-effect-hooks.mdexists; prose-lint exit 0. - No hook body mutates/stages:
grep -nE "write-back|git add" lefthook.ymlzero matches in hookrun:lines. - A stale generated artifact FAILS its hook with a regenerate instruction (manual proof).
- Plan sync — close via §06
/independent-review(bootstrap caveat); update00-overview.md+index.md. - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check.
Exit Criteria: .claude/rules/no-side-effect-hooks.md is the SSOT; the bug-tracker render + render-index hooks are verify-only (fail-on-stale, no write/stage); the commit-time reviewed_field_guard entry is removed; an audit finds zero hook-body mutation.