why Claude Code ignores rules in your CLAUDE.md

Claude Code ignores your CLAUDE.md rules because CLAUDE.md isn’t configuration. Anthropic’s own docs call it context, “not enforced configuration,” delivered as a user message after the system prompt. Claude reads it and tries to comply. Nothing makes it. If a rule has to hold every time, it needs a hook, not a stronger sentence.
The failure mode has a perfect specimen. On September 29, 2026, someone filed issue #98025: Claude pushed a change straight to production despite a standing “never touch production without confirmation” rule sitting in both CLAUDE.md and persistent memory. Then, asked to write the incident into memory so it wouldn’t recur, Claude mislabeled which port belonged to which app, inside the paragraph describing how it had mislabeled which port belonged to which app.
does CLAUDE.md do anything at all?
A lot, actually. The one published factorial study on this, Damon McMillan’s arXiv 2605.10039 from May 11, 2026, ran 1,650 Claude Code CLI sessions and 16,050 function-level observations, measuring whether Claude applied a specific annotation to every function it wrote.
With no CLAUDE.md, the baseline produced 0 compliant functions out of 524 across 50 runs. Not a low rate. Zero, with a 95% upper bound of 0.73%. With the same instruction sitting in a 250-line CLAUDE.md, the matched condition hit 67.7% (χ² = 534.27).
That’s the whole ballgame right there, and it’s also the bad news. Across every file size tested, compliance landed between 60.0% and 67.7%. Enormous next to nothing, useless next to a config file. A linter that enforced your rules two times in three would be uninstalled by lunch.
does shortening CLAUDE.md fix it?
The docs say yes: “target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence.”
The study says no. McMillan varied four things and measured each:
| what he changed | versions tested | effect on compliance |
|---|---|---|
| file length | 25, 100, 250, 500 lines | none detected |
| rule position | top, quarter, middle, three-quarters, bottom | none detected |
| file architecture | single file, plus AGENTS.md, plus nested per-directory | none detected |
| self-contradiction | clean vs. deliberately contradictory | none detected |
None of the four produced a detectable contrast after multiple-testing correction. The file being deliberately self-contradictory didn’t move the number either, which is the finding that should bother you most.
Two of those nulls are stronger than the other two. Size and conflict carry affirmative-null Bayes factors (BF10 between 0.05 and 0.10), meaning the data actively support “no effect.” Position and architecture only failed to reject, which is a weaker claim.
Caveats, stated plainly: one study, single-turn only, one rule, two TypeScript codebases. The paper says so itself: “The single-turn –print harness is a meaningful constraint on external validity.” It is not the last word. But it’s the only public measurement anyone has run, and it points the opposite way from the advice everyone repeats.
Keep the file short anyway. It’s cheaper in context, and context cost is real whether or not adherence moves. Just stop expecting the trim to be the fix.
why does Claude follow the rule early and forget it later?
Here the study did find things that move. Two of them:
- Session length. Each additional function the agent generates carries roughly 5.6% lower odds of compliance (OR = 0.944). The decay is non-monotonic, not a clean per-step slide, and McMillan found it during analysis rather than predicting it up front. It did reproduce on a second codebase and on a second model.
- The task itself. Compliance ran from 45.1% to 84.4% across the five coding tasks. The sharpest comparable pair: refactoring an existing layout component at 45.1% against a greenfield dashboard build at 71.3%. That 26.2-point gap is wider than anything the file structure produced.
Resist the obvious conclusion on the second one. McMillan does: the two tasks differ in domain, helper ratios and file count, not only in modify-versus-write, and he calls it a single-contrast observation rather than a finding. What holds up is the ranking. Which task you’re running predicts adherence better than anything you can do to the file, and a long session is worse than a short one.
how do I make a rule actually stick?
In order of how much good it does:
- Write it as a hook, if it must never break. A
PreToolUsehook runs as a shell command at a fixed lifecycle event and applies regardless of what Claude decides.permissions.denyblocks tools and paths outright. These are client-enforced. CLAUDE.md is not, and the docs say it in as many words: “To block an action regardless of what Claude decides, use a PreToolUse hook instead.” - Check the file even loaded. Run
/contextand look under Memory files. AnAGENTS.mdsilently loses to anyCLAUDE.mdin your working directory or above it. A rule that isn’t in context isn’t being ignored, it’s absent. - Be specific enough to verify. “Use 2-space indentation” beats “format code properly.” Writing MANDATORY in caps is not a mechanism.
- Use path-scoped rules, not imports. Files in
.claude/rules/with apaths:frontmatter glob load only when Claude touches matching files.@pathimports don’t do this, and the docs are blunt about it: splitting “helps organization but doesn’t reduce context, since imported files load at launch.” - Hunt for conflicts.
/doctor prompt-auditreads your CLAUDE.md, rules, skills and subagents and reports contradictions. If two rules disagree, “Claude may pick one arbitrarily.” Your commit-message rule may also be losing to Claude Code’s own built-in git instructions, which you can switch off withincludeGitInstructions. - Push it up a level.
--append-system-promptputs text in the system prompt proper, where CLAUDE.md never goes. It’s a launch flag, so it fits scripts better than interactive work.
is Anthropic fixing this?
Issue #2544, “CLAUDE.md Mandatory Rules Consistently Ignored Across Multiple Repositories,” was opened June 24, 2025. It carries the labels bug, has repro, area:core and memory, has 24 comments and 45 reactions, and is still open fifteen months later.
Issue #64319, filed May 31, 2026, describes Claude bundling a staging deploy and a production deploy into a single SSH command against explicit memory rules forbidding exactly that. It got two comments from a passing stranger and one from a bot closing it for inactivity. No maintainer ever replied.
Read the docs as a confession rather than a manual and the whole thing lands: “Claude treats them as context, not enforced configuration.” That isn’t a bug report waiting on a fix. It’s the design, written down. Your CLAUDE.md is a very polite note on the fridge, and the roommate is a 67.7% kind of guy.