/t · guide · the audit, in 7 checks

CLAUDE.md line firing audit: the 7 checks, with source line numbers.

M
Matthew Diakonov
6 min read

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":

src/lib/analyzer.ts

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 turn

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:

FeatureGeneric CLAUDE.md adviceccmd line firing audit
What gets flaggedvague advice ('trim your file')7 named kinds; each one has a fixed rule
Why a long line failsfeels longmore than 28 words; the back half is ignored
When a timestamp mattersany timestamp is badonly on lines 1 to 20; line 21+ is fine
How 'never use any' gets gradedgood rulemissing_why if there is no 'because' within 4 lines
How to score the auditsubjectivesum of tokenSavings per finding; rubric pass count 0 to 12
Lines that fire every turnthe ones the agent looks attotalTokens (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

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.