Blog
Claude Keeps Ignoring Your CLAUDE.md — And a Correct File Still Gets Overridden
10 min read
You wrote the rules down. Use the repository pattern. Never edit the generated client. Always run the formatter before you finish. You put them in CLAUDE.md, Claude read them, Claude agreed — and then three turns later it edited the generated file directly and skipped the formatter. The maddening part is that the file is not wrong. The rule is right there, in plain English, and the model still did the opposite.
This is a different failure from drift. Drift is when the file becomes inaccurate. This is when the file is accurate and still ignored. Understanding why means being honest about what CLAUDE.md actually is inside the model: not a contract, not a config, but suggestion text dropped into a context window where it has to compete with everything else — and frequently loses.
CLAUDE.md is not enforced — it is loaded
There is no mechanism that makes Claude obey CLAUDE.md. The file is prepended to the system prompt as text, and the model treats it the way it treats all text: as one more set of tokens to weigh against the rest. There is no validator that rejects an action because it violated a line in the file. Nothing fails. The instruction is advisory by construction.
What competes with CLAUDE.md in the context window
System prompt
-> CLAUDE.md text (your rules)
-> tool definitions, harness instructions
The actual conversation
-> your latest message ("just fix the bug")
-> the files Claude just read (concrete, specific, recent)
-> the diff it is staring at right now
Recency and specificity win. A general rule from the top of
the prompt loses to the concrete code in front of the model.When you ask Claude to "just make the type match," the file it is actively editing is the most concrete, most recent, most specific thing in the window. A general standing rule from 20,000 tokens back is none of those things. The model is not being disobedient. It is doing what language models do — weighting recent, specific, on-screen context above a general reminder it saw at the start of a long session.
The longer the session, the weaker the rule
A rule's influence is strongest right after it is read and decays as the conversation fills with newer, more concrete material. This is the same effect behind context rot: the useful signal gets buried under thousands of tokens of files, diffs, and back-and-forth, and the model's attention spreads thin across all of it.
Why a correct rule still gets dropped
CLAUDE.md says: "Never edit generated/ files. Edit the source schema."
Turn 1 -> Claude follows it. Great.
Turn 6 -> long thread, three files open, user says "make the
type match" — the generated file is the one on screen.
Result -> Claude edits generated/types.ts directly.
The rule did not change. Its weight did. It is one sentence,
20k tokens back, against a file the model is actively editing.Teams respond by making the rules louder — ALL CAPS, "CRITICAL:", repeating the same instruction three times. It helps marginally and makes the file longer, which dilutes every other rule. You are now trading one rule's obedience against the rest, and the file keeps growing toward the point where it gets skimmed instead of read.
Generic rules can't carry specific facts
The rules that get ignored most are the ones that need a concrete fact to be actionable. "Never edit generated files" only works if the model knows which files are generated. If that mapping is not in front of it at the moment it is editing, the rule is an abstraction with nothing to attach to. The model sees a.ts file that needs a change and changes it.
A standing instruction cannot encode the thousands of specific facts — which files are generated, which module owns which boundary, which helper is deprecated — that make the instruction enforceable. Put them all in and the file is too long to follow. Leave them out and the rule has no teeth. This is the same wall described in why context windows will never be enough: you cannot solve a retrieval problem by stuffing more standing text into the prompt.
What actually changes the model's behavior
The reliable way to make the model respect a constraint is not to remind it louder — it is to put the relevant, specific, current fact in front of it at the moment it matters. That is what retrieved context does and a static file cannot:
Suggestion text vs. enforced context
CLAUDE.md (static):
-> loaded once, competes with everything, weight decays over a thread
-> "please remember to" — advisory, easily overridden
-> same text every turn whether relevant or not
Retrieved semantic context (on demand):
-> the right facts surface for THIS query, freshly
-> "generated/ is produced by codegen from schema.prisma"
arrives as concrete current fact, not a standing reminder
-> relevance, not recency, decides what the model seesWhen the grounding is retrieved per query rather than loaded once, relevance decides what the model sees. The fact that generated/ comes from codegen surfaces precisely when the model is about to touch it — as a concrete current fact, not a rule it has to remember to apply. This is the difference between real context grounding and a list of good intentions sitting at the top of the prompt.
Where Kognita fits
Kognita maintains a semantic index of your repositories and serves the relevant slice of it to the agent on demand through MCP. Instead of one static block of rules competing for attention every turn, the agent retrieves the specific, current facts about the code it is working on right now — the real module boundaries, the actual generated paths, the conventions as they exist in the source today. The constraint arrives attached to the fact that makes it enforceable, at the moment it is relevant, rather than as a reminder that decays over a long session. Keep CLAUDE.md for genuinely global norms; let retrieval carry the specifics it was never able to.
Final take
If Claude keeps ignoring your CLAUDE.md, the file probably is not broken. It is doing exactly what a block of advisory text in a crowded context window does: losing to whatever is newer, more specific, and on screen. Making it louder buys a little obedience and a lot of bloat.
You cannot make a rule stick by repeating it. You make it stick by putting the specific, current fact behind it in front of the model exactly when it acts — which is retrieval, not a static file.