DEV Community

Cover image for Half Your CLAUDE.md Is Decoration. The AI Reads It Once.
René Zander
René Zander

Posted on • Originally published at renezander.com

Half Your CLAUDE.md Is Decoration. The AI Reads It Once.

Some of the rules in your CLAUDE.md should not be rules at all.

Not because they are wrong. Because you have written the things you cannot afford to lose into a file the model reads once and then slowly forgets. A preference survives that. A constraint does not.

A month ago I posted ten CLAUDE.md rules. The most common reply was not "add an eleventh." It was quieter than that: the rules stop getting followed. Forty thousand tokens into a session, the model edits the file you told it never to touch, or commits straight to main after you wrote, in bold, that it never should. Maybe half of what is in my own file is decoration. The half that is not decoration is the half that scares me.

The File Is Read Once. Your Session Isn't.

Claude Code reads CLAUDE.md once, at the start of a session. The instructions then sit in the context window and compete with everything else for the model's attention. As the session grows, the rules near the bottom lose weight. The model is not disobeying. The instruction stopped being load-bearing.

That is the part nobody demos. The screenshot of a clean CLAUDE.md at token zero tells you nothing about token ninety thousand, which is where you actually live when the work gets hard.

The First Instinct Is to Write the Rule Louder

So you do what I did. ALL CAPS. "IMPORTANT." "You MUST." A box of warning emojis.

It works. For a while. A louder line holds attention longer than a quiet one. Then the session gets long and busy, the diff gets large, the model is three tool calls deep into a refactor, and the loud line is now buried under ten thousand tokens of its own output. It decays anyway. You bought yourself an hour.

The instinct is right about one thing and wrong about the rest. It is right that some rules cannot be allowed to fail. It is wrong that emphasis is how you stop them failing.

Stop Writing Constraints as Sentences

So here is the move I opened with, made concrete. Open your CLAUDE.md and split every line into two piles.

Pile one: preferences. Naming style. Comment density. Which library you like. If the model misses one of these at token ninety thousand, you shrug and fix it. These belong in CLAUDE.md. A suggestion is exactly the right shape for them.

Pile two: the lines where a single miss is expensive. Never commit to main. Always run the formatter before claiming done. Never touch the production config. These are not preferences. They are constraints. And a constraint written as a sentence in a file is a hope.

Move pile two into hooks.

A hook is code the harness runs around tool calls. It fires whether the model remembers the rule or not. "Never commit to main" as a CLAUDE.md line survives until it doesn't. As a pre-commit hook, the commit is blocked, by code, at token five and at token two hundred thousand, on a good day and a bad one. The model cannot decay past it because it was never asking the model.

The One That Gets Through

The line in my file said never run the migration without confirming first. It sat there for weeks, doing its job, because nothing pushed against it. Then one long debugging session, deep in a chain of tool calls, the model ran it. The rule was still in the file. It had scrolled out of reach an hour earlier.

That is the shape of the cost. An expensive rule left as a suggestion works ninety-nine sessions. The hundredth is the one you tell people about. A hook would have refused the call and moved on, and I would have nothing to tell.

The rules I actually depend on are now a short list, and not one of them lives in CLAUDE.md anymore. They live in code that does not get tired.

Read Your Own File Back

I build agent setups that hold at token two hundred thousand. The screenshot that looks clean at token zero was never the hard part.

So read your own file back. For each line, ask: if the model ignored this ninety thousand tokens from now, would I notice, and would it cost me?

The lines where the answer is yes were never rules. They were hopes wearing bold text. Which of yours are suggestions, and which are actually enforced?


I write field notes from real builds: AI integration, cron-driven automation, and the parts that break in production. New posts every two weeks. If this one was useful, the human-in-the-loop approval playbook is the companion download.

Top comments (2)

Collapse
 
uzoma_uche_3ec83974b4a8a5 profile image
Echo

The "preferences vs constraints" split is the right move, and the bit I want to add is that the kind of constraint determines the right enforcement shape. There are at least three:

  • Compile-time constraints: a pre-commit hook that refuses a commit to main is a constraint the file system can enforce. The model never has to remember it because the gate is in the loop, not in the prompt.
  • Format / style constraints: a Prettier/ESLint/black-on-save hook means the model does not have to remember to format — the editor formats on save. The CLAUDE.md line about formatting is decoration because the tool already does it.
  • Domain constraints that cannot be hooked: "never undo the rate limiter" or "always keep the audit log line that mentions the actor". These are the lines that must stay in CLAUDE.md, and the trick is to make them small and high-signal so the model still sees them at token 90k.

The hard part is figuring out which of the three categories any given rule is in. Most teams default to "write a louder rule" because the third category is small and the second category is rare in a fresh repo. The first one — pre-commit, pre-push, CI — is where almost all enforcement should live, and most projects have it half-built.

A 30-minute audit: list every line in CLAUDE.md, mark each one "hook exists / can hook / no hook possible", and rewrite the file down to just the third column. The file will shrink by 80%. The model will start following it 100% of the time, because the rules that survive are the ones that genuinely need to be in the conversation.

Collapse
 
reneza profile image
René Zander • Edited

Yes! When I write software I put linters and fast running unit tests in the pre hook, with success. For more complex skills, a dozen or more gates, I write a single reusable CLI per skill first und enforce it to be reusable. That doesn't work from the start so I keep asking the model to get back in line for a couple of times and then the machine runs well:)