Stop Stuffing CLAUDE.md: The 7 Controls Claude Code Gives You
Anthropic's own engineering post admits a prompted "never do this" can fail under pressure. Here's my map of the seven ways to steer Claude Code — when each one enters the context, how hard it's enforced, and the rule I use to decide where an instruction belongs.
- #claude-code
- #hooks
- #skills
- #subagents
- #context-engineering
The most useful line in Anthropic's post on steering Claude Code is not a feature — it's a confession. A "never do this" written in your CLAUDE.md is not a guardrail: in a long session or an ambiguous situation, the model can drift right past a prompted rule. If an instruction absolutely must hold, it has to be code that runs, not prose the model reads. That one idea reorganizes how you use all seven controls.
The mental model I took from the post: every control differs on two axes — when it enters the context window and how strictly it's enforced. Pick the control by those axes, not by habit.
The 7 controls, on those two axes
CLAUDE.md— enters at session start, every line, every session, relevant or not. Anthropic's guidance: keep it under 200 lines. Best for what's always true — stack, build commands, conventions. Worst place for procedures and hard constraints.- Rules (
.claude/rules/*.md) — constraints that can be path-scoped withpaths:frontmatter (say,src/api/**), so they enter the context only when Claude touches matching files. Best for "in this corner of the codebase, always X" without taxing every session. - Skills (
.claude/skills/<name>/SKILL.md) — only the name and a short description load up front; the full playbook enters when invoked. Best for repeatable procedures: release checklists, review passes. If yourCLAUDE.mdcontains step-by-step logic, that's a skill living in the wrong file. - Subagents (
.claude/agents/*.md) — run in an isolated context window and return only the final answer; they can nest up to five levels deep. Best for messy side investigations (log digging, dependency audits) whose intermediate noise you never want in your main thread. - Hooks (
settings.json) — real commands that fire deterministically on lifecycle events. APreToolUsehook that exits with code 2 blocks the tool call, full stop. This is the only item on the list that is enforcement rather than persuasion. - Output styles (
.claude/output-styles/*.md) — injected into the system prompt itself, so they carry the highest adherence of any prompt-level control. The trap: a custom style replaces Claude Code's default coding instructions unless you setkeep-coding-instructions: true. --append-system-prompt— session-only additions on top of the default role. Handy for one-offs, but Anthropic flags diminishing returns: the more you stack here, the weaker each instruction gets.
The EM angle
On a team, this is an onboarding and risk question, not a personal-productivity trick. A repo where hard constraints live in hooks, procedures live in skills, and CLAUDE.md stays a lean map is a repo where the new hire's agent behaves like the senior's agent on day one. And in interviews with international companies, explaining why a rule belongs in a hook instead of a prompt is exactly the kind of judgment that reads as senior.
Today: open your CLAUDE.md and audit it line by line. Anything phrased as "never" or "always" that would actually hurt if ignored → move it to a PreToolUse hook. Any step-by-step procedure → extract it into a skill. What remains should fit comfortably under 200 lines.
Sources
Keep reading
More guides like this one.
To Stop Babysitting Claude, Give It a Failing Test
Autonomy is not a permissions problem, it is a verification problem. Claude can already run unattended — what is missing is a check it cannot talk its way past. Here are the three you can wire up today.
Your Rules Expire at Compaction. Here's Exactly Which Ones.
When a long session compacts, some of your instructions come back from disk and some silently do not. The split is documented and almost nobody knows it — which is why Claude "forgets your rules" three hours in.
The Claude Code Commands You Skip Are All the Same Command
There are over 60 built-in slash commands. Most people use four. Sort the ones you are missing by what they actually do and a pattern appears — almost all of them exist to manage one resource, and it is the one quietly wrecking your long sessions.