Documentation menu
reference

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.

hooks
27
events
7
declared in
.claude/settings.json

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.

PreToolUse

20 hooks

PostToolUse

3 hooks

UserPromptSubmit

1 hook

SessionStart

1 hook

Stop

3 hooks

Notification

1 hook

PreCompact

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.

artifact_template_guard

A spec or intake missing its required sections never lands.

Block artifact writes missing required `##` sections

PreToolUse · Art. IV

branch_guard

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

destructive_cmd_guard

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

direction_approval_guard

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

env_guard

Your .env files stay untouched.

Block writes to `.env*` (allows `.env.example`)

PreToolUse · Art. VII

epic_approval_guard

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)

git_commit_guard

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

gitignore_leak_guard

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

harness_continuation

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_runner

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

memory_pre_compact

A compaction cannot lose your place.

Capture resume snapshot before context compaction

PreCompact · Art. IX

memory_session_start

A new session starts knowing what the last one learned.

Inject memory index + resume snapshot at session start

SessionStart · Art. III, IX

memory_stop

What you decide in conversation is captured before the session ends.

Auto-extract memory candidates each turn-end

Stop · Art. IX

phase_timer

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

plantuml_syntax_guard

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

process_lifecycle_guard

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

setup_guard

You can evaluate the baseline without configuring it first.

Advisory reminder when `configured: false` (rate-limited). Never blocks.

PreToolUse · Art. III

spec_design_calls_guard

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

spec_diagram_presence_guard

A spec cannot skip a diagram it is required to draw.

Block specs missing required diagram kinds

PreToolUse · Art. IV phase 4

state_write_guard

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

swarm_approval_guard

Parallel dispatch waits until you authorize it.

Allow swarm-approval write only on fresh marker; block marker writes

PreToolUse · Art. IV gate B

swarm_boundary_guard

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

tdd_order_guard

No source file appears without a test.

Require test before new source file

PreToolUse · Art. VI.4

test_runner

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

track_guard

A phase cannot run before the phase it depends on.

Enforce 11-phase ordering for workflow artifacts

PreToolUse · Art. IV

verify_pass_guard

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.

deny

The tool call never runs. Claude gets the guard's reason back in place of a result.

ask

The call waits for you to decide before it goes ahead.

allow

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.

last updated 2026-08-25 edit on GitHub →