Your rules file only grows. Here's how to find the rules that do nothing
This is part 3 of a series on project rules for AI coding agents. Part 1 covered how Cursor, Claude Code, and Codex load your rules. Part 2 covered enforcing rules with hooks. This one covers the part almost nobody does: figuring out which of your rules are dead weight.
The append-only problem
Nearly every long-lived rules file I've seen has the same life story. It starts as five lines. An agent does something annoying, someone adds a rule. A bug slips through, someone adds a rule. Six months later it's 40 rules, and nobody can tell you which ones still matter.
The reason is an asymmetry in how it feels: deleting a rule feels risky, keeping it feels free. But keeping isn't free:
- Context cost. Rules ship with every request. In Claude Code,
CLAUDE.mdis loaded into context each session; in Cursor,alwaysApplyrules ride along on everything. Tokens spent on dead rules are tokens not spent on your actual code. - Dilution. Agents don't weight 40 instructions equally. Every low-value rule competes for attention with the rules that actually prevent incidents. A short file is not just cheaper - it's followed better.
- Rot. Rules encode assumptions about tool behavior at the time of writing. Tools change monthly. A rule that references behavior that no longer exists is worse than noise: it teaches the agent (and new teammates) something false.
So the file needs an audit loop. The question is what signal to audit on.
"Did it fire?" is the wrong question
The obvious instinct is to count how often each rule fires - how often it gets attached to a request. Cursor even shows you which rules attached, so this feels measurable. After part 1 of this series, a reader (@dipankar_sarkar) pushed on exactly this point, and his framing is the right one: count outcomes-changed, not matches.
A rule that attached to 200 requests but never changed what the agent did is indistinguishable from a comment. Attachment tells you the rule was present, not that it was load-bearing.
The catch is that "outcomes-changed" is a counterfactual. To measure it directly you'd need to know what the agent would have done without the rule - and you can't observe that during normal operation. You can't A/B test every rule on every request without doubling your workload. But there's a cheap approximation.
Deletion testing: the cheap counterfactual
If you can't simulate the world without the rule, create it - briefly.
- Pick candidates. Rules you can't remember "saving" you in the last month. Rules everyone has stopped reading. Rules that duplicate what the base model already does well.
- Quarantine, don't delete. Move them out of the loaded file entirely - into a
rules-quarantine.mdthat no tool loads (for Cursor rules, flipalwaysApplyoff or move the file out of.cursor/rules/). Git keeps the history either way; this is reversible by design. One trap to avoid: don't just mark a section "ignore this" insideCLAUDE.md. The agent still reads every token of the loaded file, so the rule is still in context - and your test measures nothing. - Work normally for a week or two. No special test harness. Your regular code review is the harness.
- Watch what you correct. If you never once re-correct the agent for the thing a quarantined rule prescribed - the rule was dead weight. Either the model internalized that behavior long ago, or another rule already covers it. Delete it for real.
- If the failure comes back, restore the rule - and now you know something valuable: it's load-bearing and it's prose. Part 2 of this series argued that load-bearing rules deserve mechanical enforcement (hooks, linters, CI), not just prose. A rule that failed a deletion test in the wrong direction is your best candidate for promotion to a hook.
What makes this safe is the asymmetry of the two failure modes. A regression from a wrongly-deleted rule is visible and cheap - it shows up in a diff you were reviewing anyway, and git revert fixes it. A dead rule you keep is invisible and permanently costly - it taxes every request forever and nobody ever notices. In a workflow where you review agent output anyway, deletion is much safer than it feels.
Your correction log is the audit signal
Between deletion tests, the day-to-day signal is simpler: what do you keep correcting? Every time you fix agent output by hand, that correction lands in one of three buckets, and each bucket has a different action:
- You corrected something a rule already covers. The rule is load-bearing but under-enforced. Prose has failed; stop rewording it and enforce it mechanically (part 2).
- You corrected something no rule covers. Missing rule. Add it - this is the legitimate way the file grows.
- A rule never shows up in your corrections at all - you never violate it, the agent never violates it. That's your next deletion-test candidate.
That's the whole triage. Every rule ends up in one of four states: enforce (promote to hook), keep (observed saves), add (correction with no rule), delete-test (no evidence either way).
The 20-minute quarterly audit
Concretely, once a quarter (or every N sessions if you move fast):
- Read the file top to bottom. For each rule, ask: when did this last save us? If nobody can answer with a concrete incident, mark it.
- Quarantine the bottom 20% by that measure.
- Note the date in the quarantine file (and drop a one-line pointer in your team changelog), so the test is visible to the whole team.
- Two weeks later: delete what stayed silent, restore (and consider hook-ifying) what didn't.
- Track one number over time: net line count. If it's flat or falling while your correction rate also falls, the file is getting denser. If lines only go up, you're accumulating, not curating.
The uncomfortable conclusion
The end state of a well-audited rules file is short. Models absorb more conventions with every release - a rule that genuinely earned its place in January may be base-model behavior by June. The rules that survive repeated deletion testing are the ones encoding things models can't know: your architecture decisions, your team's non-obvious constraints, your definition of done.
Treat rules like dependencies, not like law: audit them, upgrade them, and remove the ones that no longer do anything. The file you end up with is smaller, cheaper, and - because every surviving rule is there for a reason someone can name - actually trusted by the people and agents who read it.
I maintain Rulestack - rule packs for Cursor, Claude Code, and Codex, audited against current tool behavior, so you start from rules that earn their place. Feedback welcome on Bluesky @ai-shop.bsky.social.
Comments
No comments yet. Start the discussion.