The hooks · Claude Code
A convention nobody has to remember.
A hook is a shell command the tool fires on an event — a prompt arriving, a tool call about to run, a session opening or closing. There are 58 of them across 9 events, and the reason there are that many is one idea: a rule that lives only on a checklist gets missed, and the more carefully the checklist is written the more it feels like a control. So each rule worth keeping is moved into the command that already runs.
Grouped here by event, because that is the useful axis: what runs before the model reads a message, what refuses an action outright, what inspects the result, and what has to happen at the boundaries of a session so nothing is left stranded on one machine.
One session, start to end — the hooks firing
The injectors
UserPromptSubmit 6 hooks - What it does
- Before the model reads my message, 6 hooks add what the turn needs: which delegation lane fits, the intent gate for a build, the closing structure the answer has to end in, and where notes for me have to go.
- Why
- A rule stated once at the top of a long session is a rule the middle of that session has forgotten. Re-stating it every turn costs a few hundred tokens and removes the whole class of drift.
The guards, before the action
PreToolUse 20 hooks - What it does
- Refuses the action rather than reporting it afterwards: a plan that has not settled its intent, a question that hides jargon in an option label, a file about to land outside the folder this session started in, a shell command whose final target cannot be resolved before it runs.
- Why
- A guard that fires AFTER the write has only told you what happened. These sit in front of the tool call, so the bad state is never reached — which is the difference between a warning and a control.
The checks, after it lands
PostToolUse 8 hooks - What it does
- Reads what the action actually did — the house conventions for a generated tool, the writing rules for anything shipped, and the estate impact of a change that touches shared machinery.
- Why
- Some faults only exist once the output does. Checking the intent before a write cannot see them, so this is the half that has to run afterwards.
Mostly watching the watchers
SessionStart 14 hooks - What it does
- Pulls the doctrine and skills, loads the memory for this folder, then reports on the machinery itself: whether the gates are still fast enough to be run, whether delegation is drifting from its own table, whether a scheduled job has gone quiet, and whether the current model matches what the setup assumes.
- Why
- Every one of those was a failure that had already happened once and shown nothing at the time. A silent gate, a stalled job and a stale mirror all look identical to a healthy estate until something reports on them.
So nothing is stranded
SessionEnd 1 hook - What it does
- Scrubs anything secret-shaped from what was written, then commits and pushes the config and the skills so the next session on any machine starts from the same place.
- Why
- Work that only exists on one disk is work that ends with that disk. The scrub runs FIRST, because a push is the point of no return.
Pricing the delegation
SubagentStop 2 hooks - What it does
- Reads each finished sub-agent’s own transcript for what it actually cost and whether its lane held, and releases the plan lock it was holding.
- Why
- Delegation is easy to feel good about and hard to price. Reading the real transcript is the only way to know whether a fan-out paid for itself or just felt fast.
When the model underneath changes
PostModelSwitch 3 hooks - What it does
- Notices that the session is now running on a different model, records which one, and re-checks whether the assumptions the setup was built on still hold for it.
- Why
- Rules written for one model are not automatically right for the next. The switch is the moment that becomes true, and it is the moment nobody remembers to check.
Before the turn is handed back
Stop 3 hooks - What it does
- Harvests what the turn learned about the tool it ran inside, and checks the answer against the shape every answer here has to take.
- Why
- The end of a turn is the last point where a missing section can still be added. After it, the only fix is a correction the reader has already had to notice.
The doctrine and skills live in private repos, referred to here by role. Counts are read from the real configuration rather than typed — an earlier version of this page said “five”, then “six”, while the true number was 58, and the drift checker reported it in sync the whole time because it compares event names and never reads what a hook does.