Everyone who has used Claude Code for more than a week has had this moment. You add a line to your CLAUDE.md that says do not create new files unless asked. The agent follows it beautifully. Then, forty minutes into a long session, it creates four files you did not ask for.
The instinct is to write the rule more forcefully. Bold it. Put it at the top. Add ALL CAPS. That instinct is wrong, and understanding why is the whole point of hooks.
What are Claude Code hooks?
Claude Code hooks are scripts the runtime executes automatically at fixed points in a session, such as before a tool call, when you submit a prompt, or when the agent tries to stop. Claude Code hands the hook a JSON description of the event on stdin, runs it, and reads the exit code and stdout. The model is not consulted.
That last sentence is the entire value. Everything you put in a markdown file is context competing for a model's attention against everything else in the window. Everything you put in a hook is a program. The model can skim your CLAUDE.md. It cannot skim an exit code.
A rule is a request. A hook is enforcement.
Both belong in a healthy setup, doing different jobs. CLAUDE.md explains intent, taste, and the things that need judgment. A hook carries any rule that must hold every single time, regardless of how long the session has run or how confident the model feels. Ask yourself one question about each rule: what happens if the agent ignores this once?
If the answer is "a slightly worse commit," leave it in markdown. If the answer is "it deletes a table" or "it writes four hundred lines before I could say what I wanted," that rule does not belong in prose. It belongs in code.
A hook answers in one of two ways. It exits with a code, where 2 is the blocking signal and Claude Code feeds your stderr back to the model as the reason. Or it exits 0 and prints JSON, which is how you return a real permission decision of allow, deny, or ask. The trap that catches people is that exit 1, the conventional Unix failure code, does not block anything.
The eight events, and what we wired to each
Claude Code fires hooks across a session lifecycle, not just around tool calls. kitstarter ships eight scripts across eight of those events. This is the table our installer writes into your settings.json, and it is the most honest answer we can give to "what would you actually do with hooks."
Two of those rows deserve a closer look, because they are opposites, and the difference between them is the whole design philosophy.
The one place we hard-deny, and the one place we refuse to
The clarity hook denies. On any Edit, Write, MultiEdit or NotebookEdit, it returns a permission decision of deny until you have confirmed what you actually want, then it lifts. This is a real lock, not a nudge. The agent cannot write your first file until the goal is agreed.
The safety guard refuses to block. It sits on Bash, it recognizes destructive commands, and it only warns. The reasoning is written in the file itself: a kit that hard-blocks your commands gets uninstalled. Being right about a dangerous command is worth nothing if the user rips the whole thing out a week later.
That is the rule worth stealing. Block where the cost of being wrong is high and the friction of asking is low. Warn everywhere else. A hook that blocks too much is a hook that gets deleted, and a deleted hook enforces nothing.
Both fail open. Any error inside the hook and it stays silent and lets you work. A coaching feature is never worth breaking a session over.
What hooks actually changed, measured
Every other page about Claude Code hooks explains the API. Almost none of them tell you what changes when the hooks are running, because that requires putting them into production and measuring. We ran a clean-room suite: same model, same scripted vibe-coder conversations, fresh sandbox per arm, one arm with the hooks and one without.
The last two rows matter more than the first four. Hooks are not free. On a task that was already unambiguous, the clarity engine is pure overhead: it asks a question nobody needed and you pay for the tokens. That is the honest cost of a floor, and it is the open product problem we are tuning.
Where to start with Claude Code hooks
You do not need eight. Start with one, and pick it by asking which failure has actually cost you time this month.
If your agent builds before you finish explaining, put a lock on Edit and Write. If it runs commands that scare you, warn on Bash. If it says done without checking, use Stop to make done a claim the runtime verifies. If you spawn subagents and notice they ignore rules the main agent follows, re-inject on SubagentStart. And if you simply want to see what is happening, a status line costs nothing and pays back immediately.
Write it, log first, block later. Roll out gradually: log the event without blocking, then warn on the patterns you recognize, and only block the things that have genuinely caused damage. A hook you trust is worth ten you disabled.
None of this requires a kit. Hooks are a Claude Code feature and the docs are good. What a kit gives you is the part that took us months: knowing which events are worth wiring, which rules deserve enforcement instead of prose, and where blocking backfires. If you would rather not assemble that yourself, we shipped ours, and you can read exactly what it does before you install it.
Put the rules where the agent cannot skim them
kitstarter wires eight hooks into Claude Code, Codex, and Antigravity so they ask before they build, stay lean, and do not look AI-made.
