If you've spent time customizing Claude Code, you've probably written a line like this in your CLAUDE.md
: "always run the formatter after editing a file" or "never touch .env
or any .pem
/.key
file." It works — until a long session, a big diff, or a context window full of other instructions makes that one line easy to deprioritize. The model isn't being careless; a system prompt is advisory. Every instruction in it competes with everything else in context for attention, and instructions written early tend to fade as the conversation grows.
That's a structural limit, not a prompting mistake. And it means anything you actually need to happen every single time — not "usually," not "when the model remembers to" — doesn't belong in a prompt at all.
Claude Code hooks are shell commands wired to specific points in the tool's lifecycle: after a file edit, before a tool runs, when Claude finishes responding, when it needs your permission, at the start of a session. They execute as code, deterministically, regardless of what's in the conversation or what the model "decided" to prioritize that turn. The model doesn't get a vote — the hook just runs.
That distinction matters more than it sounds. A CLAUDE.md rule is a request you're hoping gets honored. A hook is a guarantee, because it's not the model doing the enforcing.
Not everything belongs in a hook. The useful split is:
Getting this backwards is the common failure mode: people write increasingly elaborate CLAUDE.md instructions trying to force deterministic behavior out of a probabilistic system, when a five-line shell hook would have made the question moot.
A statusline doesn't enforce anything — it's just a line under your prompt showing which model, which directory, which git branch you're currently in. It matters for a much smaller reason: once you're running more than one Claude Code session in parallel (a common outcome of subagents and worktrees), "which one is this again" becomes a real source of mistakes. Cheap to add, easy to forget you need until you're context-switching between four terminals.
Before adding another paragraph to your CLAUDE.md, ask whether what you actually want is a rule the model should weigh, or a guarantee that shouldn't depend on it weighing anything at all. If it's the latter, write a hook instead.
(Written with AI assistance.)
A working set of these — auto-format on edit, a secret-file guard that blocks writes to .env
/*.pem
/*.key
before they happen, run-tests-on-stop, desktop notifications, and session logging — plus 12 slash commands, 6 subagents, and a git-aware statusline, is packaged as the Claude Code Power Pack (copy-paste into .claude/
, €29): https://vincentdu2a.gumroad.com/l/bqndfi. It's an independent, unofficial project — not affiliated with, endorsed by, or sponsored by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic.