Hooks: Make Standards Non-Negotiable
Telling an agent to always run the linter is a suggestion it can forget. A hook is a guarantee. Hooks are shell commands the harness runs automatically at defined points in the agent's lifecycle, so your standards execute deterministically instead of depending on the model's good behavior.
Step 1: Pick the right lifecycle event
Common events include after a file edit, before a command runs, and when the agent finishes. A formatter on every edit and a test run before the agent declares victory are the two highest-value hooks.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npm run format -- $CLAUDE_FILE" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "npm test && npm run typecheck" }
]
}
]
}
}Step 2: Let a failing hook block completion
When a hook exits non-zero, the harness feeds the failure back to the agent, which must fix it before finishing. The agent cannot mark a task done while tests are red, no matter how confident it is.
Step 3: Guard dangerous actions
Use a PreToolUse hook to inspect commands before they run and reject the dangerous ones (a destructive database drop, a force push to main). This is a deterministic safety net that does not rely on the model's judgment.