Claude Code Hooks vs CLAUDE.md: Where Enforcement Lives
A rule the assistant must never skip belongs in a hook.
A rule the assistant should usually follow belongs near the work.
CLAUDE.md alone is the place neither one is safe.

What this covers
- CLAUDE.md is advisory text the model decides what to do with. Hooks are deterministic scripts that always run.
- PreToolUse and UserPromptSubmit are the two hooks most teams reach for first: PreToolUse for gating tool calls, UserPromptSubmit for injecting context.
- Hooks are the right home for must-happen rules. They are the wrong home for the long tail of folder-specific knowledge.
- Pathrule sits in the middle: path-scoped rules with explicit enforcement levels, delivered via UserPromptSubmit-style hook injection.
Before and after
| Area | CLAUDE.md only | CLAUDE.md plus hooks plus scoped routing |
|---|---|---|
| A rule that must happen every commit | Advisory text near the top of the file | PreToolUse hook that blocks the tool call when violated |
| A folder-specific schema note | Lives at the root, loaded everywhere | Pathrule memory at the schema folder, injected at hook time |
| A rule about secret handling | Hopefully not skipped this session | Strict Pathrule rule plus a PreToolUse gate for the high-risk command |
| A repeated style preference | One more line in the root file | Path-scoped rule at the surface where it applies |
Advisory and deterministic are different categories
Two things in Claude Code look similar and behave nothing alike. CLAUDE.md is text the model reads at session start. A hook is a script that runs every time, no judgment, with the power to allow, block, or modify what the assistant is about to do.
Treating them as interchangeable is the source of a lot of frustration. A team writes "never run destructive commands in production" into CLAUDE.md and is surprised when the assistant runs one anyway. The instruction was real. The enforcement was advisory.
Hooks are how a team gets enforcement. They run outside the model. They cannot be talked out of their decision by a clever prompt. They are the right home for any rule whose violation has a real cost.
PreToolUse: the gate before the action
PreToolUse fires after the assistant has chosen a tool and before the tool executes. The script can read the planned action, approve it, request user confirmation, modify the parameters, or block it outright.
This is where teams typically put their hardest rules. Block edits to a protected path. Refuse a shell command that contains a destructive flag. Require a review on changes to a security boundary. Reject a database query that touches production.
PreToolUse is also where audit trail starts to be real. Every blocked attempt is a logged event the team can review. The CLAUDE.md version of the same rule produces no such record.
UserPromptSubmit: the injection moment
UserPromptSubmit fires when the user sends a message, before the assistant starts responding. The hook can append system context to the request. Sprint priorities, on-call status, a freeze window, a current incident, or relevant path-scoped knowledge can all be injected here without the user having to retype them.
This is the hook Pathrule uses to deliver scoped memory and rules. The retrieval has already chosen the right slice for the active path. The hook injects it before the model decides anything. The slice arrives as system context, not as user prose.
The result is a session that starts with the right context for the work in front of it, every time, without anyone typing it again.
What does not belong in a hook
Hooks are powerful and that makes them tempting to overuse. Every rule that ends up as a hook is one more piece of code your team has to maintain, debug, and update when the assistant changes.
A reasonable test: if the cost of a violation is real, if the rule has to apply every time, if the rule is small and stable, it belongs in a hook. If the rule is long, contextual, advisory, or specific to one folder, it belongs in a path-scoped layer that the hook can deliver as system context.
The hooks themselves stay small. The knowledge they deliver grows in a different place where it is easier to review and easier to retire.
Why this matters for security review
Security review of AI coding workflows is usually two questions. What rules are actually being enforced when the assistant is operating? Where is the evidence that they were enforced on this change?
A CLAUDE.md only setup has no good answer to either. The team can show the file. They cannot show that the assistant respected it on a given commit. Hooks change both answers. PreToolUse provides enforcement. The audit log provides evidence.
Path-scoped rules raise the bar further. The review now has a place to point: this rule lives at this path, with this enforcement level, last updated by this person, on this date. The rule and the review surface are the same surface.
A small starting setup that actually works
A useful first version of this stack is short. Trim CLAUDE.md to conventions that really apply everywhere. Add one PreToolUse hook for the one command the team really wishes the assistant never ran. Connect a path-scoped layer for the long tail.
Open a session in one folder. Watch the slice arrive. Try to violate the gated command. Notice the block. The setup is now doing three different jobs in three different places, none of them pretending to do the other two.
Every signup gets three months of Pathrule PRO on the house. If you want to design this split together on a real repo, [email protected] is open.