The over-specified CLAUDE.md: how a long file makes results worse
By the end you can
- Tell the three adherence symptoms apart — too long, too vague, contradicted
- Explain why adding a rule can lower adherence to the rules you already had
- Apply the per-line deletion test and route each cut line to its right home
- Reject the fixes that only look like fixes — imports, more emphasis, a louder rule
- Set a review habit so the file shrinks as often as it grows
Your CLAUDE.md is somewhere north of three hundred lines. It got there the way
these things do: every line was added on a real day, in response to a real
mistake, and none of them was wrong. And Claude is still committing straight to
main, even though line 214 says not to.
The reflex is to make line 214 louder. This lesson is about why that is the one move that makes it worse.
The named failure
This is not an inference. It is one of five failure patterns the best-practices guide names outright, and the only one whose cause is a file you wrote:
The over-specified CLAUDE.md. If your CLAUDE.md is too long, Claude ignores half of it because important rules get lost in the noise.
Fix: Ruthlessly prune. If Claude already does something correctly without the instruction, delete it or convert it to a hook. — Best practices
Read the fix twice. It has two halves, and the second is the one nobody applies: a rule Claude already follows without being told is not free, it is a line of noise around the rules that are doing work.
Three symptoms, three different repairs
Before you cut anything, work out which failure you actually have. The docs distinguish them, and they take different treatments:
| What you observe | Documented diagnosis | What changes |
|---|---|---|
| Claude keeps doing something you have a rule against | The file is probably too long and the rule is getting lost | Cut other lines |
Claude asks you something CLAUDE.md already answers | The phrasing might be ambiguous | Rewrite that one line |
| Two files give different direction on the same behaviour | Claude may pick one arbitrarily | Remove one of the two instructions |
The third row is the one that hides in a long file: a rule you wrote in March and the rule that contradicts it from July are both in the window, and nothing arbitrates. The debug guide collapses all three causes into one sentence:
Adherence drops when an instruction is vague enough to interpret multiple ways, when two files give conflicting direction, or when the file has grown long enough that individual rules get less attention. — Debug your configuration
Three causes, three different repairs. Rewriting a rule that was being ignored for length fixes nothing, and adding a rule that was being ignored for ambiguity makes the length worse.
Why length costs adherence, not just tokens
Lesson 3.1 established that the window is not empty when you arrive, and
CLAUDE.md is one of the things already in it. That is the token cost, the one
people can picture. The adherence cost is separate, and worse:
Size: target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence. — Memory
Two costs in one sentence — consume more context and reduce adherence — and
they are not the same claim. The memory page states the second on its own terms
too: shorter files produce better adherence. There is a hard ceiling as well,
nowhere near where you are — Claude Code loads a CLAUDE.md of up to 4 MiB in
full and skips a larger file. You will feel the adherence cost long before then.
The mechanism is the one Lesson 6.1 named: loaded CLAUDE.md content arrives as
a user message after the system prompt, not as part of the system prompt itself,
and there is no guarantee of strict compliance. Instructions, not configuration.
The token cost, meanwhile, is paid on days that have nothing to do with the rule:
If it contains detailed instructions for specific workflows (like PR reviews or database migrations), those tokens are present even when you're doing unrelated work. — Manage costs
The per-line test
There is exactly one question, and it is applied per line rather than per section:
Keep it concise. For each line, ask: "Would removing this cause Claude to make mistakes?" If not, cut it. Bloated CLAUDE.md files cause Claude to ignore your actual instructions! — Best practices
The test is brutal on purpose, because the honest answer is usually no. Run it against a fragment:
## Architecture
The app is a Next.js frontend in app/ with API routes under app/api/.
Shared types live in packages/types.
## Style
- Write clean, readable code.
- Use 2-space indentation.
- IMPORTANT: never commit directly to main; open a PR.
## Testing
Run `pnpm test:integration` — it needs a local Postgres on port 5433.Would removing it cause a mistake? The architecture paragraph: no — Claude opens
app/ and sees it. "Write clean, readable code": no, and Lesson 6.2 put that in
the exclude column by name. The indentation rule: only if it differs from what
the tooling already enforces. The main rule and the Postgres port: yes, both —
one is repository etiquette Claude cannot guess, the other an environment quirk
invisible in the code.
Roughly half survives, and that is the whole exercise: the cuts are not the rules you regret, they are the paragraphs you were proud of.
The three fixes that are not fixes
Each of these feels like progress and buys nothing.
Splitting the file into @ imports. The most common one, because the root
file visibly shrinks.
Splitting into
@pathimports helps organization but doesn't reduce context, since imported files load at launch. — Memory
Lesson 6.1 made this point as mechanism; here it is as diagnosis. Ten tidy files that all load at launch are the same three hundred lines, now harder to audit.
Adding emphasis. Emphasis is real, and it is a single-use resource:
If Claude keeps skipping one instruction, add emphasis such as "IMPORTANT" to that line alone. If you emphasize many lines, none of them stands out. — Best practices
A file with nine IMPORTANTs has no important lines. If you cannot remember whether you already used it, you have.
Adding one more, louder rule. This is the trap, and it is the exact opposite of the documented fix. Put the two sentences together: a file that is too long means important rules get lost in the noise, and longer files reduce adherence. A rule added to a file that is already too long lands in the noise beside the rule it was meant to reinforce, and lengthens the file that is losing both.
Where each cut line goes
Cutting is not deleting everything. Most cut lines have a home where they cost nothing until needed. Lesson 6.2 taught this routing decision; here it is applied in the pruning direction:
| The line is… | Send it to | Because |
|---|---|---|
| Something Claude already does correctly | Deletion | The documented fix says delete it or convert it |
| Something that must happen at a fixed moment | A hook | Hooks apply "regardless of what Claude decides to do" |
| A multi-step workflow you use sometimes | A skill | Detailed workflow instructions are paid for during unrelated work |
| Relevant only to part of the tree | A path-scoped rule | Loads only when Claude works with matching files |
| A workaround for an older model | Deletion | It "may become overhead once a newer model handles the case" |
The memory page names the two real remedies together — path-scoped rules, or trimming content not needed in every session. Everything else on that list is a variant of one of them.
One caution on each middle row. Convert a rule to a hook because you need a
guarantee rather than guidance (Level 5), not merely to shorten the file. And a
path-scoped rule is not a free lunch: Lesson 3.2 showed it is summarised away by
compaction and returns only when a matching file is read again, so a constraint
that must always hold does not belong behind a paths: glob (Lesson 6.3).
For a checked-in file you do not have to do the first pass yourself: the
/doctor trim check proposes the cuts, keeping pitfalls, rationale, and
conventions that differ from tool defaults — the shape of a good file in one
clause. It arrived in v2.1.206; Lesson 6.5 covers running it, and why a silent
/doctor is not by itself a verdict on your file. The per-line test above needs
no version at all.
Reviewing it like code
The habit that keeps the file from regrowing is in one sentence:
Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude's behavior actually shifts. — Best practices
Test changes by observing whether behaviour actually shifts is what turns this
from tidying into engineering: a rule you added and never checked is a rule you
do not know is working. The large-codebases guide gives three ways to schedule
the review rather than wait for an incident — review CLAUDE.md edits in pull
requests like any other documentation change; revisit the file after major model
releases, since a rule that worked around an older model's limitation "may
become overhead once a newer model handles the case on its own"; and add a
Stop hook, which receives the path to the session transcript when Claude
finishes responding, so a script can review the session and propose updates
while the gap that exposed them is fresh. You built that third one in Lesson 5.2
for a different purpose.
The level in one line
A CLAUDE.md is not documentation and it is not a wish list. It is the standing
cost of every session in the project, and the only lines that earn it are the
ones whose removal would cause a mistake. Add readily. Delete more readily.
Checkpoint
-
Claude has ignored your "always run the linter before committing" line three sessions running. The line is unambiguous and no other file contradicts it. What does the documented diagnosis say the problem is, and what is your first edit?
Show answerAnswer
The file is too long and the rule is getting lost in the noise. You have ruled out the other two documented causes yourself — the instruction is not vague enough to interpret multiple ways, and no second file gives conflicting direction — which leaves the third: a file grown long enough that individual rules get less attention. That is the top row of the symptom table, and the treatment it names is to cut other lines.
So your first edit is to delete ten lines elsewhere, not to touch the linter line. Run the per-line test over the rest of the file — "would removing this cause Claude to make mistakes?" — and cut everything that fails it, starting with the rules Claude already follows without being told. What you must not do is restate it louder or add an eleventh rule: that lengthens the file that is losing the rule. And note the second half of the documented fix, which fits this line exactly — something that must happen at a fixed moment is a candidate for a hook rather than a sentence.
-
Your 320-line
CLAUDE.mdbecomes a 40-line root file plus seven@imports. How much context did you save, and what did you actually gain?Show answerAnswer
Nothing, and possibly less than nothing. Splitting into
@pathimports helps organization but does not reduce context, since imported files load at launch — eight tidy files that all load at launch are the same 320 lines, now harder to audit. The root file visibly shrank, which is why this is the most common of the three fixes that are not fixes.The adherence problem is untouched too: the same volume of instruction is in the window, so the important rules are still lost in the same noise. The remedies the memory page actually names are path-scoped rules and trimming content not needed in every session — that is, the per-line deletion test, and routing what survives to a hook, a skill or a scoped rule.
-
You are about to add "IMPORTANT: never edit files under generated/". You already have two IMPORTANT lines. Name two destinations for this instruction that are not a third IMPORTANT line in
CLAUDE.md, and say which one gives you a guarantee.Show answerAnswer
A hook and a path-scoped rule. The hook is the one that gives you a guarantee: hooks apply "regardless of what Claude decides to do", which is the documented reason to convert a rule into one — not merely that it shortens the file. A path-scoped rule loads only when Claude works with matching files, so it costs nothing in the sessions that go nowhere near
generated/, but it is still guidance, and it is summarised away by compaction and returns only when a matching file is read again — so it is the wrong home for a constraint that must always hold. A third option, if Claude already avoidsgenerated/without being told: delete the line and write nothing.On the IMPORTANT itself: emphasis works on one line alone, and if you emphasize many lines none of them stands out. With two already in the file you are spending a resource you have largely spent, and adding a third makes the existing two weaker.