baseline / docs
friedbotstudio/baseline

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.

Claude's domain above the dashed boundary; tools below; hooks fire on the boundary itself, outside Claude's reach. CLAUDE inside · claude's reach outside · hooks fire here TOOL load-bearing at the boundary

§ 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.

EventHooks
PreToolUse · Bashdestructive_cmd_guard, git_commit_guard, process_lifecycle_guard
PreToolUse · Edit / Write / MultiEditsetup_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 / MultiEditlint_runner, test_runner
UserPromptSubmitconsent_gate_grant
SessionStartmemory_session_start
Stopmemory_stop
PreCompactmemory_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.

HookArticleBehavior
setup_guardIIIAdvisory reminder when project is unconfigured (rate-limited 10 minutes). Does not block.
destructive_cmd_guardVIIHard-block catastrophic commands; ask risky.
git_commit_guardIV (gate C), VIIRequire fresh consent for git commit; block forbidden flags. Gate writes to the commit-consent marker.
env_guardVIIBlock writes to .env* files (allows .env.example).
spec_approval_guardIV (gate A)Validate fresh marker before allowing approval-token writes; block self-approval inside spec markdown.
swarm_approval_guardIV (gate B)Validate fresh marker before allowing swarm-approval writes.
verify_pass_guardV, VIBlock writing PASS to verify artifacts when truth source says FAIL.
track_guardIVEnforce 11-phase ordering for workflow artifacts.
artifact_template_guardIVBlock artifact writes missing required sections.
plantuml_syntax_guardIV (phase 4)Validate PlantUML fences in docs/specs/*.md.
spec_diagram_presence_guardIV (phase 4)Block specs missing required diagram kinds.
spec_design_calls_guardX.2Block specs whose write_set intersects tdd.ui_globs from omitting a populated ## Design calls section.
swarm_boundary_guardIV (phase 6c)Enforce write-set discipline in shared isolation mode.
tdd_order_guardVI.4Require a test before a new source file lands.
process_lifecycle_guardIXAdvisory. 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_runnerVIRun lint.cmd on code changes (guide mode until configured).
test_runnerVIRun test.cmd on code changes (guide mode until configured).
memory_session_startIII, IXInject memory index and resume snapshot at session start.
memory_stopIXAuto-extract memory candidates each turn-end.
memory_pre_compactIXCapture resume snapshot before context compaction.
consent_gate_grantIV (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

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.

Consent gates are not bypassable.

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.