Reference
Hooks.
The 22 hooks are the structural enforcement layer of the baseline. Each runs at a tool boundary or lifecycle event, outside Claude's control.
§ I
Why hooks
The baseline ships 22 hooks wired into Claude Code's PreToolUse, PostToolUse, UserPromptSubmit, and lifecycle events. They form the part of the constitution that cannot be overridden by memory or prompt text alone.
A hook runs outside Claude's tool boundary. When a hook blocks a write, Claude never executes the tool call. This matters because Claude cannot forge a consent marker (written by consent_gate_grant on the UserPromptSubmit path) by invoking a tool: the block happens before Claude gets the chance. Memory is helpful, prompts are helpful, hooks are load-bearing.
§ II
Hooks by tool boundary
Most hooks run on Write, Edit, MultiEdit, or Bash before the tool fires. A small set runs on the surrounding session lifecycle.
| Event | Hooks |
|---|---|
| PreToolUse · Bash | destructive_cmd_guard, git_commit_guard, process_lifecycle_guard |
| PreToolUse · Edit / Write / MultiEdit | setup_guard, env_guard, git_commit_guard, spec_approval_guard, swarm_approval_guard, verify_pass_guard, track_guard, artifact_template_guard, plantuml_syntax_guard, spec_diagram_presence_guard, spec_design_calls_guard, swarm_boundary_guard, tdd_order_guard |
| PostToolUse · Edit / Write / MultiEdit | lint_runner, test_runner |
| UserPromptSubmit | consent_gate_grant |
| SessionStart | memory_session_start |
| Stop | memory_stop |
| PreCompact | memory_pre_compact |
§ III
What each hook enforces
The constitution maps each hook to the article it backs. Modifying or disabling a hook requires user approval and a corresponding amendment in seed.md.
| Hook | Article | Behavior |
|---|---|---|
| setup_guard | III | Advisory reminder when project is unconfigured (rate-limited 10 minutes). Does not block. |
| destructive_cmd_guard | VII | Hard-block catastrophic commands; ask risky. |
| git_commit_guard | IV (gate C), VII | Require fresh consent for git commit; block forbidden flags. Gate writes to the commit-consent marker. |
| env_guard | VII | Block writes to .env* files (allows .env.example). |
| spec_approval_guard | IV (gate A) | Validate fresh marker before allowing approval-token writes; block self-approval inside spec markdown. |
| swarm_approval_guard | IV (gate B) | Validate fresh marker before allowing swarm-approval writes. |
| verify_pass_guard | V, VI | Block writing PASS to verify artifacts when truth source says FAIL. |
| track_guard | IV | Enforce 11-phase ordering for workflow artifacts. |
| artifact_template_guard | IV | Block artifact writes missing required sections. |
| plantuml_syntax_guard | IV (phase 4) | Validate PlantUML fences in docs/specs/*.md. |
| spec_diagram_presence_guard | IV (phase 4) | Block specs missing required diagram kinds. |
| spec_design_calls_guard | X.2 | Block specs whose write_set intersects tdd.ui_globs from omitting a populated ## Design calls section. |
| swarm_boundary_guard | IV (phase 6c) | Enforce write-set discipline in shared isolation mode. |
| tdd_order_guard | VI.4 | Require a test before a new source file lands. |
| process_lifecycle_guard | IX | Advisory. Surfaces relevant memory entries (e.g. landmines.md → lsof-port-kill-takes-firefox-with-it, conventions.md → dev-server-ownership) verbatim before any kill, lsof, or serve Bash. Never blocks. |
| lint_runner | VI | Run lint.cmd on code changes (guide mode until configured). |
| test_runner | VI | Run test.cmd on code changes (guide mode until configured). |
| memory_session_start | III, IX | Inject memory index and resume snapshot at session start. |
| memory_stop | IX | Auto-extract memory candidates each turn-end. |
| memory_pre_compact | IX | Capture resume snapshot before context compaction. |
| consent_gate_grant | IV (gates A / B / C), VII (push gate) | Detect the four slash commands (/approve-spec, /approve-swarm, /grant-commit, /grant-push) in user input and write the gate-specific consent marker. Runs outside Claude's tool boundary. |
§ IV
Why consent gates are unforgeable
Each gate is a slash command the user types. Three are workflow-phase gates (/approve-spec, /approve-swarm, /grant-commit). The fourth, /grant-push, is a runtime gate for protected-branch pushes (Article VII). UserPromptSubmit runs outside Claude's tool boundary, so Claude has no way to write the marker.
The consent_gate_grant hook runs on UserPromptSubmit, before Claude sees the prompt. It writes a short-lived marker that the matching PreToolUse guard validates. Markers expire after two minutes by default (consent.gate_marker_ttl_seconds) and are deleted on use, so the same gate cannot be replayed.
The PreToolUse guard then allows Claude's slash-command-body write of the approval token only if the marker is present, fresh, and slug-matched. The marker is single-use and deleted on the allowed write.
§ V
Modifying or disabling a hook
Disabling, modifying, or bypassing a hook requires explicit user approval and a corresponding amendment in seed.md (the genesis prompt). The order of precedence is seed.md > CLAUDE.md > implementation.
Hooks are the implementation layer: they cannot be loosened by a memory entry or a CLAUDE.md amendment alone.
For a one-shot exception inside a workflow, use the exceptions array in .claude/state/workflow.json, written only by /triage. Exceptions are surfaced in every phase log so the audit trail records which phases ran and which were waived.