CLAUDE.md line firing audit: the 7 checks, with source line numbers.
The framing matters because most advice on this topic starts in the wrong place. "Which lines are firing?" is the question every new Claude Code user asks. The answer is boring: all of them. There is no per-line gating on CLAUDE.md, AGENTS.md, .cursorrules, or .grokrules. The interesting question is the next one: which of the firing lines are deadweight?
That is what the audit is. Seven checks. Below: the source they come from, then each check with its real threshold.
The audit, from source
The audit is encoded as a TypeScript union. Seven string literals, one per check. Below them, the line that explains why an audit of "firing" lines collapses to "all lines":
The seven kind values map one-to-one to the seven checks below. Each one is implemented as a separate scan inside analyzeConfig(), and the result is a Finding[] sorted by line number.
The 7 checks, with thresholds
Skim this in any order. Each one has a real numeric or regex threshold, not a vibe. The analyzer file:line is on every card so you can verify or change it.
1. bloat
Line over 28 words. The model treats long directives as one signal and the back half gets dropped. Severity: medium. Source: analyzer.ts line 150. Token savings credited at 35% of the line's tokens.
2. vague
Words like 'appropriate', 'properly', 'carefully', 'as needed' that have no testable success condition. Severity: low. Source: VAGUE_TERMS list, analyzer.ts line 124.
3. aspirational
An absolute (always, never, must, every time) with no 'unless' or 'except' escape clause. Severity: low. Source: ASPIRATIONAL list, analyzer.ts line 130.
4. missing_why
A 'DO NOT' or 'NEVER' line where no 'because' / 'incident' / 'got burned' / 'happened' appears in the next 4 lines. The agent follows until an edge case, then guesses. Severity: medium. Source: analyzer.ts line 227.
5. duplicate
Same trimmed lowercased line appears twice in the file. The bytes get billed twice; one of them is doing nothing. Severity: medium. Source: analyzer.ts line 207.
6. conflict
Two rules that contradict (the shipping check: 'never use comments' + 'add comments'). The agent has no resolution path and will pick one at random per turn. Severity: high. Source: analyzer.ts line 242.
7. cache_bust (highest severity)
An ISO date, 'today', 'this session', or 'right now' in the FIRST 20 LINES. Position matters: the same string on line 21 is fine; on line 8 it invalidates prompt cache and costs roughly 10x more across a 30-turn session. Severity: high. Source: analyzer.ts line 194, idx < 20.
“every single API call to Claude sends the whole context, including prompts, meaning that all this extra text in CLAUDE.md is sent over and over”
caymanjim, Hacker News thread 47581701
How this audit differs from generic CLAUDE.md advice
Most write-ups on CLAUDE.md hygiene give heuristics. The audit is mechanical. Each row below is a question, with the heuristic answer on the left and the audit's answer on the right:
| Feature | Generic CLAUDE.md advice | ccmd line firing audit |
|---|---|---|
| What gets flagged | vague advice ('trim your file') | 7 named kinds; each one has a fixed rule |
| Why a long line fails | feels long | more than 28 words; the back half is ignored |
| When a timestamp matters | any timestamp is bad | only on lines 1 to 20; line 21+ is fine |
| How 'never use any' gets graded | good rule | missing_why if there is no 'because' within 4 lines |
| How to score the audit | subjective | sum of tokenSavings per finding; rubric pass count 0 to 12 |
| Lines that fire every turn | the ones the agent looks at | totalTokens (every non-blank line, hardcoded line 264) |
The reason the right column exists is that "does this line fire?" is settled by a single assignment in the analyzer source. Everything downstream is graded against fixed rules. That makes the audit repeatable across files and across people on the same team.
What you do with the result
The output is three numbers and a list. The list is the Finding[] sorted by line. The three numbers are:
- totalTokens: the size of the file, in tokens, at the chars/4 estimate every CLI uses.
- estimatedCostPerLongRunSession: totalTokens times 30 turns times Opus 4.7 input rate ($15/M). This is the cache-busted ceiling, not the typical bill.
- potentialSavingsTokens: the sum of tokenSavings across findings. Bloat credits 35% of the long line; duplicate and cache_bust credit the full line. The rest are zero because their fix is rewording, not deletion.
The audit does not tell you whether the rule itself is good. A short, specific, with-a-why rule passes all 7 checks and is still a rule the agent might ignore for other reasons (it lives on the wrong surface, it conflicts with a hook, the model is overweighting a more recent message). The 7 checks are necessary, not sufficient.
Want a second pair of eyes on your CLAUDE.md?
Bring the file and a recent rate-limit screenshot. We run the audit live and walk every finding.
FAQ
Frequently asked questions
Which lines of CLAUDE.md actually fire on every turn?
All non-blank lines. ccmd's analyzer hardcodes this in src/lib/analyzer.ts line 264: estimatedTokensFireEveryTurn = totalTokens. There is no per-line gating on CLAUDE.md, AGENTS.md, .cursorrules, or .grokrules. Every line of the file is concatenated into the system prompt at session start and re-sent on every API call. The audit is therefore not about whether lines fire. It is about which of the firing lines are deadweight.
How many checks does the audit run?
Seven. The Finding.kind union in src/lib/analyzer.ts line 7 enumerates them: bloat, vague, aspirational, conflict, duplicate, missing_why, cache_bust. Each one is implemented as a separate scan inside analyzeConfig(). Three are high severity (conflict, cache_bust, and bloat on long lines), three are medium (missing_why, duplicate, bloat), two are low (vague, aspirational). The rubric layer on top (Karpathy 12) is a separate read; the line firing audit is the 7 checks.
Why is the cache_bust check the highest severity?
Because position matters and the cost delta is roughly 10x. Anthropic caches the prefix of long system prompts and bills a cache hit at about a tenth of a fresh read. One ISO date or 'today is' line near the top busts the cache for every session. The analyzer only flags it if the line index is below 20 (analyzer.ts line 194), so 'today is 2026-05-19' on line 8 is a finding, the same string in a footer is not. On a 6,000-token file across 30 turns, that one line moves the input bill from about $0.09 to about $0.91.
What exactly counts as bloat?
A single line over 28 words, measured by whitespace split. Source: analyzer.ts line 149-150. Rule lines that long consistently get treated as one signal by the model and the back half gets ignored. The suggested fix is split into 2 to 3 shorter directives, each individually actionable. The analyzer credits 35 percent of the line's tokens as recoverable savings; the rest is the real rule that survives the split.
Do the same checks run against AGENTS.md, .cursorrules, and .grokrules?
Yes, identically. detectType() in analyzer.ts line 41 returns one of four inputType labels but the per-line scan does not branch on it. The 7 Finding.kind values fire across all four formats because the firing model (every line, every turn, no per-line gating) is the same on Codex (AGENTS.md), Cursor (.cursorrules), and Grok Build (.grokrules). The host changes; the audit does not.
Where do I run the audit?
Paste the file into the textarea on ccmd.dev. The analyzer is pure client-side TypeScript; nothing is uploaded. You get a Finding[] array sorted by line number, plus three aggregate numbers: totalTokens, estimatedCostPerLongRunSession at Opus 4.7 rates over 30 turns, and potentialSavingsTokens (the sum of tokenSavings across findings). The source of every check is open at github.com/m13v/ccmd-website in src/lib/analyzer.ts.
What is NOT covered by the line firing audit?
Three things, on purpose. (1) Whether a rule belongs on a different surface (skill, hook, MCP description); that is a separate analysis. (2) Whether the model is actually following each line; the free analyzer cannot see your session logs. (3) Coverage of the Karpathy 12 rubric, which is a separate pass that scores the file as a whole. The line firing audit is the per-line scan for the 7 deadweight kinds. The other three layers are guides on the site and the paid tier.
How long does the audit take?
Single-digit milliseconds for any file under 20k tokens. The analyzer reports durationMs in the result so you can see it. There is no streaming, no model call, no upload; it is regex + word count + map lookups in your browser tab.
Related: Do CLAUDE.md rules fire on every turn? · CLAUDE.md token cost audit · Owner audit for stale CLAUDE.md lines
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.