Every guard, and
where it is wired.
Reference for the hooks. Each one is a Node ESM script that Claude Code runs as a subprocess when a lifecycle event fires, and what the script writes back decides whether the pending tool call may go ahead. The roster below is derived from the files on disk and their wiring in settings.json, so a hook added to the directory shows up here without an edit to this page.
Lifecycle events
Seven events carry hooks. If a hook is wired on PreToolUse it sees the call before it runs and may stop it; on PostToolUse the call has already happened, so the hook can only report on what it produced. The remaining five fire at points in the session itself (at start, at a stop, before a compaction), where there is no pending call to gate.
20 hooks
3 hooks
1 hook
1 hook
3 hooks
1 hook
1 hook
Those counts add up to 30, which is more than the 27 scripts under .claude/hooks/. One script, notify, is wired on three events and counts once in each; it also lives outside that directory. Every other hook runs on exactly one event.
The roster
27 hooks in alphabetical order. Each cell leads with what the hook makes true for you, then how it does it, then the event it is wired on and the Article it enforces. Article VIII of CLAUDE.md is the record; if this table and the constitution ever disagree, the table is the drift.
A spec or intake missing its required sections never lands.
Block artifact writes missing required `##` sections
PreToolUse · Art. IV
Work cannot start on a release branch under PR discipline.
Deny `workflow.json` creation on a release branch under `github-flow`; fail-open otherwise
PreToolUse · Art. IV, VII
Claude cannot forge your consent.
Detect consent commands in user input and write the gate marker, OUTSIDE Claude's tool boundary
UserPromptSubmit · Art. IV gates A/B/C, Art. VII
A catastrophic command never reaches your shell.
Hard-block catastrophic commands; ask on risky. Also closes the Bash surface of consent: writes to a consent path, and epic `approved` flips.
PreToolUse · Art. IV, VII
Claude cannot approve its own direction.
Allow direction-approval token write only on fresh marker; block self-approval + marker writes; opt-in provenance-anchor arm. (annex)
PreToolUse · Art. IV gate A
Your .env files stay untouched.
Block writes to `.env*` (allows `.env.example`)
PreToolUse · Art. VII
An epic cannot mark itself approved.
Allow an epic-state `approved: true` flip only when the matching `spec_approvals/<slug>.approval` token exists; other writes pass. (annex)
PreToolUse · Art. IV (§18.9)
Claude cannot rewrite published history, or commit on a protected branch without consent.
Branch-aware consent; hard-block forbidden flags; gate consent writes; hard-block a closing commit whose staged `backlog.md` lacks the `source_backlog_keys` closure stamp. (annex)
PreToolUse · Art. IV gate C, Art. VII
A file you told git to ignore cannot be staged into a commit.
Hard-block a commit staging a must-ignore path. Fail-closed on an inspection error; fail-open on missing baseline data.
PreToolUse · Art. VII
A workflow interrupted mid-flow picks itself back up.
Disjunctive gate: Path A re-fires `Skill(harness)` when the loop stopped mid-flow, Path B resumes after a consent command. Silent on `parked` and `done`; never writes consent. (annex)
Stop · Art. V
Lint runs on every code change once the project is configured.
Run `lint.cmd` on code changes (guide mode until configured); `exit 2` on failure
PostToolUse · Art. VI
A compaction cannot lose your place.
Capture resume snapshot before context compaction
PreCompact · Art. IX
A new session starts knowing what the last one learned.
Inject memory index + resume snapshot at session start
SessionStart · Art. III, IX
What you decide in conversation is captured before the session ends.
Auto-extract memory candidates each turn-end
Stop · Art. IX
You can see where a workflow spent its time.
Observe-only; stamps per-phase timing on `completed[]` growth, incl. Bash-driven `workflow.json` writes. Never blocks or mutates.
PostToolUse · Art. V
You learn a diagram is broken at the boundary when strict checking is on.
Advisory by default (no JVM); strict `java -checkonly` only when `plantuml.strict_syntax_check` true.
PreToolUse · Art. IV phase 4
You see what this project already learned about a command before you run it.
Advisory. Bash leg surfaces process-management entries by category and key; write leg carries three triggers — phase-scoped, path-governed, and corpus location. Never blocks. (annex)
PreToolUse · Art. IX
You can evaluate the baseline without configuring it first.
Advisory reminder when `configured: false` (rate-limited). Never blocks.
PreToolUse · Art. III
A UI spec cannot ship without naming what it designs against.
Block UI specs whose `## Design calls` rows lack a Reference target/Quality criteria
PreToolUse · Art. XI.2
A spec cannot skip a diagram it is required to draw.
Block specs missing required diagram kinds
PreToolUse · Art. IV phase 4
A subagent cannot widen what it is allowed to do next.
Deny a subagent write to `.claude/state/**` on both the Bash and edit-tool boundaries; reads and the main session pass
PreToolUse · Art. II
Parallel dispatch waits until you authorize it.
Allow swarm-approval write only on fresh marker; block marker writes
PreToolUse · Art. IV gate B
A parallel worker cannot write outside the files it was given.
Enforce write_set discipline whenever a wave is active (both isolation modes)
PreToolUse · Art. IV phase 6c
No source file appears without a test.
Require test before new source file
PreToolUse · Art. VI.4
Tests run on every code change once the project is configured.
Run `test.cmd` on code changes (guide mode until configured); `exit 2` on failure
PostToolUse · Art. VI
A phase cannot run before the phase it depends on.
Enforce 11-phase ordering for workflow artifacts
PreToolUse · Art. IV
A failing test suite cannot be written up as passing.
Block writing PASS to verify artifacts when truth source says FAIL
PreToolUse · Art. V, VI
Hook outcomes
A PreToolUse hook writes its decision to standard output as JSON, or it exits 0 to say nothing and let the call through. Three decisions are available.
The tool call never runs. Claude gets the guard's reason back in place of a result.
The call waits for you to decide before it goes ahead.
The call goes ahead. Advisory hooks add context here and always allow.
If lint_runner or test_runner finds a problem it exits 2, and that failure reaches Claude as feedback on the edit it just made. Neither one can stop the write, because a PostToolUse hook only fires once the call has already run.
Amendment procedure
To change a hook, disable one, or work around one, Claude needs your explicit approval first. The amendment then lands in docs/init/seed.md §4.1 before the matching edit to .claude/settings.json, because the genesis spec governs the implementation rather than the other way round.
The hook count is itself part of the constitution, so it cannot drift quietly. On every build audit-baseline re-derives the count from disk and checks it against both the genesis spec and the shipped manifest; should those three ever disagree, CI will fail rather than warn.