/t · guide · pruning the file

How to prune dead rules from your CLAUDE.md

M
Matthew Diakonov
6 min read

The common advice for a bloated CLAUDE.md is "ruthlessly prune" — Claude ignores half of a long file, so cut it down. True, but it skips the part that actually matters: most lines worth cleaning up should be rewritten, not deleted, and if you cut a line that was doing real work you have made the file worse. Pruning is the narrower job. It is the deletion of rules that are genuinely dead, and dead has a precise meaning.

ccmd's analyzer lives at src/lib/analyzer.ts. It emits one finding per problem line, and every finding carries a suggestion string. The verb in that string is the whole game.

The sort: rewrite verbs vs delete verbs

The analyzer has seven finding kinds. Four of them hand you a rewrite verb — the rule is fine, the line is badly shaped. Three hand you a delete verb — the rule is dead. Read the suggestion, not the severity, and the file sorts itself into two piles.

Rewrite — keep the rule
  • bloat — line over 28 words. Verb: split.
  • vague — no testable meaning. Verb: replace.
  • aspirational — absolute, no escape clause. Verb: add "unless X".
  • missing_why — prohibition, no reason. Verb: add a Why:.
Delete — the rule is dead
  • duplicate — same text as an earlier line. Verb: delete this copy.
  • cache_bust — session timestamp near the top. Verb: remove entirely.
  • conflict — two rules that cannot both hold. Verb: pick one.

The delete pile is your prune list. The three species below are what land in it.

Species 1: the duplicate

The same rule, pasted into two sections. It happens when a file grows by accretion: a rule gets added under ## Style, and three months later someone adds the same thought under ## Notes without checking. The second copy changes nothing the first copy did not already say. It just costs tokens on every turn.

src/lib/analyzer.ts

The detector trims and lowercases each line, ignores anything under 10 characters, and remembers the first line each piece of text appeared on. A second occurrence fires a finding that points back at the original and sets tokenSavings to the entire line, not a fraction — because deleting a duplicate loses exactly nothing. One caveat the code is honest about: it matches verbatim text only. Two lines that mean the same thing in different words are still two strings, so a paraphrased duplicate is a human catch. When you spot one, it is the same dead rule: keep the clearest phrasing, delete the rest.

Species 2: the timestamp, and why it is the expensive one

A line like Today is 2026-05-12, mid-sprint on the refund flow is dead the moment the session ends. It is not an instruction, it is a sticky note, and it goes stale on a timer. The cache_bust detector flags any date or session phrase in the first 20 lines of the file and lists its savings as the line's own tokens — 13, in our example.

That 13 is a lie of omission. Your CLAUDE.md sits near the front of the context window, inside the cached prefix. Anthropic's prompt caching works on a hierarchy — tools, then system, then messages — and a change at any level invalidates that level and everything after it. A timestamp that changes every session means the cached prefix never matches the next session's prefix. So you do not pay 13 tokens. You pay the full uncached input price for the whole file, and anything cached below it, every session, forever. That is why a high-severity cache_bust finding is the first thing to cut. Move volatile context out of the file entirely — it belongs in the session, not the contract.

Species 3: the contradiction

Two rules that cannot both be obeyed. Never use comments on one line and Add comments to every public function on another. The model has no resolution path, so it picks one per turn and silently drops the other — and which one it drops is not predictable. One of those two lines is always dead; you just do not get to know which until you decide. The analyzer ships a conflict detector with the comments case built in; any pair of absolutes that cannot both hold is the same species. The fix: pick the rule you actually want, delete the loser, or scope both by context so they stop competing.

A prune pass on a real file

Here is a small, deliberately messy CLAUDE.md. Seventeen lines, 78 tokens. Three of those lines are dead.

CLAUDE.md

Pasting it into the analyzer returns nine findings. Sorted by the suggestion verb, four of them land in the delete pile:

ccmd · findings, sorted by verb

Line 12 and line 16 both repeat line 10 — two duplicates, 7 tokens each. Line 4 is a session timestamp — 13 tokens, plus the cache miss it forces. Line 1 flags the comments contradiction. Delete lines 4, 12, and 16 outright, then resolve the conflict by cutting one of the two comment rules. The analyzer's potentialSavingsTokens for this file is 27 — that is 27 tokens off every turn of every session, for deleting three lines and not one rule that was doing work. The five rewrite findings stay; that is a different job.

The pass, in four steps

  1. 1

    Paste

    Drop your CLAUDE.md, AGENTS.md, .cursorrules, or .grokrules into ccmd.dev. It runs in the browser, no signup.

  2. 2

    Sort by verb

    Read each finding's suggestion. delete / remove / pick one go in the prune pile. split / replace / add go in the rewrite pile.

  3. 3

    Cut the prune pile

    Delete duplicates and timestamps outright. For each conflict, keep the rule you want and delete the loser, or scope both.

  4. 4

    Re-run

    Paste the trimmed file back. The delete-class findings drop to zero and your token count falls by the prune budget.

What looks dead but is not

Pruning goes wrong when "this line looks like junk" gets treated as "this line is dead." A few traps:

  • A long line is not a dead line. A 40-word stack paragraph reads like bloat, but the stack facts inside it are live context. That is a bloat finding — verb split, not delete.
  • A rule Claude already follows is not redundant. A security prohibition the model "always obeys anyway" is there for the edge case where it would not. Keep it; if it is a bare prohibition, the fix is a Why:, not a deletion.
  • A vague line is a rewrite, not a prune. "Write clean code" is weak, but the intent is real. Replace it with something testable rather than dropping the standard entirely.

The discipline is the sort. Cut the delete pile without hesitation, because by definition nothing is lost. Touch the rewrite pile with care, because those rules are alive. The whole reason the analyzer attaches a verb to every finding is so you never have to guess which pile a line belongs in.

Want a second read before you cut?

15 minutes, free. Walk through your CLAUDE.md together and leave with a marked-up file: the delete pile sorted from the rewrite pile, line by line.

Frequently asked questions

What makes a CLAUDE.md rule 'dead'?

A dead rule is one where the only honest fix is the delete key, not a rewrite. ccmd's analyzer attaches a suggestion string to every finding, and the verb in that string is the tell. Three finding kinds carry a delete verb: duplicate ('delete this copy.'), cache_bust ('move volatile text to the bottom or remove entirely'), and conflict ('pick one'). The other four kinds — bloat, vague, aspirational, missing_why — carry rewrite verbs (split, replace, add). So 'dead' is mechanical, not a judgement call: a rule is dead if cutting the line loses you nothing, because the rule was a duplicate, a stale timestamp, or one side of a contradiction the model could never satisfy anyway.

Should I delete a rule that Claude keeps ignoring?

Not automatically. Ignored is not the same as dead. A rule that genuinely matters — a security prohibition, a stack constraint — can still get skipped because of how the line is written, and the fix there is to reshape it, not cut it. See our companion guide on why Claude skips rules. A rule is only dead if it is structurally redundant: an exact duplicate, a stale timestamp, or a contradiction. Pruning is the subset of cleanup where deletion is correct; reshaping is the rest.

Why is a timestamp near the top the most expensive dead rule?

The analyzer lists the cache_bust finding's savings as the line's own tokens (13 in our example file). That number understates it. CLAUDE.md sits near the front of the context, inside the cached prefix. Anthropic's prompt caching works on a hierarchy — tools, then system, then messages — and a change at any level invalidates that level and everything after it. A 'Today is 2026-05-12' line that changes every session means the cached prefix never matches, so you re-pay the uncached input price for the whole file (and anything cached after it) on every single session. The 13 tokens are not the cost. The cache miss on everything below them is.

How does the analyzer decide a rule is a duplicate?

It trims and lowercases every line, skips lines under 10 characters, and keeps a Map of text to first-seen line number. The second time the exact same text appears, it emits a duplicate finding pointing back at the original line, with tokenSavings set to the whole line. It catches verbatim copies — the same sentence pasted into two sections. It does not catch paraphrases ('write clean code' vs 'keep code clean'); those two lines are different strings, so a human still has to spot them. When you do, the rule is the same dead rule: keep one phrasing, delete the rest.

Does pruning dead rules actually make Claude follow the rest better?

Yes, and the official Claude Code best-practices doc says the same thing in plain terms: keep CLAUDE.md concise, because it gets injected into context every time, and a file that is too long dilutes the rules that matter. Every dead rule you carry is noise the model has to read past to reach a live rule. Cutting duplicates, stale timestamps, and contradictions raises the signal-to-noise ratio of the file without touching a single instruction that was doing real work.

Won't deleting rules make Claude do the wrong thing?

Only if you delete a live rule. A dead rule is, by definition, not gating behavior — a duplicate is already covered by its original, a timestamp is not an instruction, and one half of a contradiction was being silently dropped already. The actual risk is mis-sorting: deleting something that looked redundant but was load-bearing. That is the entire point of splitting findings into a delete pile and a rewrite pile. Cut the delete pile with confidence. Reshape the rewrite pile. Never blind-cut a long line just because it is long.

How do I run this on my own file?

Paste your CLAUDE.md into the textarea on ccmd.dev. The analyzer runs entirely in your browser — no upload, no signup. You get total tokens, the line-by-line findings, and the suggestion verb for each one. Sort the findings by that verb: the delete-class ones are your prune list. The same detectors run on AGENTS.md, .cursorrules, and .grokrules; detection is by file content, not filename.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.