Hooks: Lifecycle & Control
Deterministic automation at every stage of a Claude session. Hooks are shell commands the harness runs at lifecycle events — they don't go through the model, so behavior is reliable.
Walkthrough: blocking
rm -rf1Claude wants to run
rm -rf /tmp/build2PreToolUse fires — JSON sent to hook
3Matcher:
"Bash" ✓ If: Bash(rm *) ✓4Script detects
rm -rf in command✗ DENIED — Tool call blocked
Hook config in
.claude/settings.json// .claude/settings.json{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "if": "Bash(rm *)", "command": "./hooks/block-rm.sh" } ] } ] }}
Exit codes:
0 = allow · 2 = block · other = warn but continueHook types: command, http, prompt, agent
Why use hooks?
Use hooks when you need deterministic safety: blocking destructive
commands, running linters/tests after edits, validating commits before push.
The model can't talk its way out of an exit code 2.