What belongs in CLAUDE.md — and the far longer list of what does not
By the end you can
- Apply the four documented triggers for adding a line to CLAUDE.md
- Sort candidate instructions into the include and exclude columns
- Route a would-be rule to a skill, a scoped rule, or a hook instead
- Choose the scope a line belongs at — personal, project, local, or organization
- Write an instruction concrete enough to verify rather than open to interpretation
- Say what CLAUDE.md cannot do, and what to reach for when you need a guarantee
You have typed the same correction into chat three sessions running, and someone
tells you to put it in CLAUDE.md. They are right. That advice is also where
most CLAUDE.md files go wrong, because the file is the obvious home for
everything and everything is exactly what must not go in it.
Lesson 6.1 established which files load and in what order. This lesson is the editorial decision: what earns a line, and where the rest of it goes instead.
The four triggers
The documentation does not leave this to taste. It names the purpose, then the moments:
Treat CLAUDE.md as the place you write down what you'd otherwise re-explain. — How Claude remembers your project
Add to it when:
- Claude makes the same mistake a second time
- A code review catches something Claude should have known about this codebase
- You type the same correction or clarification into chat that you typed last session
- A new teammate would need the same context to be productive
Three of the four are repetition detectors: something has already gone wrong, or already been typed, at least twice. The fourth is deliberately not — it is the test you can apply before anything has gone wrong at all:
CLAUDE.md works well for the kinds of guidance you'd give a new teammate, such as project conventions, build commands, and where files belong. — Debug your configuration
So the file is not purely a residue of corrections; /init drafts one from your
project structure on day one, which is Lesson 6.5. But once it exists, the
documented reason to add a new line is nearly always that the thing happened
twice.
The second occurrence is the signal, and the docs are explicit that the fix is a file edit rather than another sentence in chat:
A repeated mistake or a recurring review comment is a CLAUDE.md edit, not a one-off correction in chat. — Extend Claude Code
The two columns
The best-practices guide prints the sorting directly — the closest thing to a specification you will get (Best practices):
| Include | Exclude |
|---|---|
| Bash commands Claude can't guess | Anything Claude can figure out by reading code |
| Code style rules that differ from defaults | Standard language conventions Claude already knows |
| Testing instructions and preferred test runners | Detailed API documentation (link to docs instead) |
| Repository etiquette (branch naming, PR conventions) | Information that changes frequently |
| Architectural decisions specific to your project | Long explanations or tutorials |
| Developer environment quirks (required env vars) | File-by-file descriptions of the codebase |
| Common gotchas or non-obvious behaviors | Self-evident practices like "write clean code" |
Most of the sorting is the first exclude row: content Claude can derive from the
code it is already reading. A required environment variable that appears in no
committed file is a left-column fact; a file-by-file tour of src/api/ is a
right-column one, because src/api/ is right there. Two exclusions are not about
derivability at all — "information that changes frequently" and "long
explanations or tutorials" stay out either way. For anything the table does not
name, the same page gives you the test, one line at a time: would removing this
cause Claude to make mistakes? If not, cut it. Lesson 6.6 runs that test to its
conclusion, on a file that has already gone wrong.
Specific enough to check
Passing the include test is not enough. The docs put the bar at verifiability and give paired rewrites:
| Instead of | Write |
|---|---|
| "Format code properly" | "Use 2-space indentation" |
| "Test your changes" | "Run npm test before committing" |
| "Keep files organized" | "API handlers live in src/api/handlers/" |
The right column has a property the left one lacks: you can look at a diff and say whether it complied. An instruction you cannot check is one you cannot debug, and it will read as "Claude ignores my CLAUDE.md" when the real problem is that nobody, human or model, could tell what it asked for.
Two companions to specificity, from the same section:
- Structure. Markdown headers and bullets group related instructions; organized sections are easier to follow than dense paragraphs.
- Consistency. If two rules contradict each other, Claude may pick one arbitrarily.
That second one is the sharp edge of Lesson 6.1. Memory files do not overwrite each other:
All discovered files are concatenated into context rather than overriding each other. — How Claude remembers your project
So a stale rule in ~/.claude/CLAUDE.md and the project rule contradicting it
both arrive, in full. What happens next is described twice: Claude "uses judgment
to reconcile them, with more specific instructions typically taking precedence"
(Extend Claude Code), and
Claude "may pick one arbitrarily". Typically and arbitrarily are the
load-bearing words. Unlike settings, where a documented stack names the winning
file, nothing here promises an outcome you can predict — which is why the docs
tell you to review your memory files periodically and remove the conflict rather
than rank the files.
Guidance is not enforcement
This is the sentence that decides half the routing:
Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a PreToolUse hook instead. — How Claude remembers your project
Lesson 6.1 explained the mechanism: the file arrives as a user message after the
system prompt, and Claude "reads it and tries to follow it, but there's no
guarantee of strict compliance." The consequence for authoring is that "never
do X" in CLAUDE.md is a strong convention, not a lock. If X is embarrassing,
write it down. If X is unrecoverable, write the PreToolUse hook the quote above
names — you wired a Stop hook in Lesson 5.2, so the settings file already looks
familiar.
The one-line version:
Use CLAUDE.md for "we do it this way here." Use permissions or hooks for security boundaries and anything that must never happen, where you need a guarantee instead of guidance. — Debug your configuration
Where the rest of it goes
Most rejected lines are not bad instructions, they are instructions in the wrong mechanism. The docs name a destination for each shape:
| The instruction is… | It belongs in | Documented because |
|---|---|---|
| A fact every session needs — build command, convention, layout, "always do X" | CLAUDE.md | "Keep it to facts Claude should hold in every session" |
| A multi-step procedure | a skill | "move it to a skill … instead" |
| Only relevant to one part of the codebase | a path-scoped rule | same sentence |
| Reference material needed sometimes — API docs, a style guide | a skill, or a link to the docs | loads on demand rather than every session |
| Something that must run at a fixed moment | a hook | "before every commit or after each file edit" |
| Something that must never happen | permissions or a hook | you need a guarantee, not guidance |
Lesson 6.3 covers .claude/rules/ and paths: globs; skill authoring is Level
7. Here you only need the decision, which reduces to one question: does every
session need this? "Only when I am doing the release" is a skill. "Only in the
frontend package" is a scoped rule. "Only in the sense that it must be true" is
a hook.
Personal, project, or organization
Once a line has earned CLAUDE.md, it still has to earn a scope, and the test is
who else should be governed by it. Lesson 6.1 builds the four scopes in full —
managed policy, user, project, local — and says where each one lives on disk; the
editorial half is choosing between them.
The project file is shared through version control, so the docs advise focusing
it "on project-level standards rather than personal preferences." Your taste in
comment style is not a project standard; it goes one level up into
~/.claude/CLAUDE.md, or into CLAUDE.local.md at the project root — the
documented home for private per-project preferences, gitignored, that should not
be checked in. The project file, by contrast, is a team artifact:
Check CLAUDE.md into git so your team can contribute. The file compounds in value over time. — Best practices
Emphasis is a budget too
The last thing people reach for when a rule is ignored is shouting, and it works
exactly once: emphasis such as IMPORTANT on one line is a signal, and on nine
lines is nothing. Emphasis is a scarce resource spent against a fixed background,
and so is the file itself, whose documented size target is under 200 lines per
CLAUDE.md. Lesson 6.6 builds both arguments in full — the emphasis budget, and
why a long file costs adherence and not merely tokens — along with what to do
once you are already past the target.
The line that earns its place
Three questions, in order. Has this been re-explained, or is it merely true? Is it already in the repository? Does every session need it, or only Tuesdays and only in one package?
A file written that way stays short without anyone pruning it, because the bar for entry was never "this is true."
Checkpoint
-
A reviewer leaves the same comment on two of Claude's pull requests: the team uses
pnpm, notnpm. Which trigger is that, and what exactly do you write — in which file?Show answerAnswer
That is the second trigger: a code review caught something Claude should have known about this codebase. It is also on its second occurrence, which is the signal the docs care about — "a repeated mistake or a recurring review comment is a CLAUDE.md edit, not a one-off correction in chat." The first time was fine to handle in the conversation; this time is a file edit.
Write it specifically enough to check against a diff, in the shape of the documented rewrites — "Run
npm testbefore committing", not "test your changes" — so a concrete line namingpnpmas the command to use, not "use the right package manager". It belongs in the projectCLAUDE.md, checked into git: this is a project-level standard the whole team is governed by, not a personal preference for~/.claude/CLAUDE.mdor a private one forCLAUDE.local.md. -
Your
CLAUDE.mdsays "never commit directly tomain". It happened anyway. Is the fix a clearer sentence, a louder sentence, or a different mechanism?Show answerAnswer
A different mechanism. Claude treats memory files as context, not enforced configuration, so "never do X" in
CLAUDE.mdis a strong convention and not a lock — the file arrives as a user message after the system prompt, with no guarantee of strict compliance. To block an action regardless of what Claude decides, the docs send you to aPreToolUsehook, and the one-line rule is plain:CLAUDE.mdfor "we do it this way here", permissions or hooks for anything that must never happen.The other two options are dead ends here. The sentence is already concrete and checkable, so rewriting it changes nothing; and emphasis is a scarce resource — IMPORTANT on one line is a signal, on nine lines it is nothing. The real question is which kind of X this is: if committing to
mainis embarrassing, writing it down was the right call and it will mostly work. If it is unrecoverable, you needed a guarantee all along. -
You want to add a fifteen-line database-migration checklist that matters about once a month. Sort it: which column, which mechanism, and what does putting it in
CLAUDE.mdcost you on the days you are not migrating anything?Show answerAnswer
Exclude column, and the mechanism is a skill. It is a multi-step procedure, which the routing table sends to a skill by name, and the exclude side of the include/exclude table already rejects long explanations and tutorials. Run the decision question — does every session need this? — and the answer is no: "only when I am doing the migration" is exactly the shape that loads on demand rather than every session.
The cost on the other days is that all fifteen lines are in the window anyway, spent in every session by every teammate who pulled the repo, crowding out the three rules that would actually change behaviour and pushing the file toward the documented under-200-line target for nothing. That is not merely tokens: Lesson 6.6 is the argument that a longer file costs adherence to the rules you kept.