How a CLAUDE.md grew, then learned to shrink
I have been thinking about what a CLAUDE.md file is supposed to be.
At first glance it looks simple. It is just a markdown file with instructions for an AI coding assistant. In practice it becomes something else very quickly. It turns into a running record of everything that has gone wrong, everything that must not be forgotten, and every behavior that seemed obvious until it failed in the middle of real work.
This post is about that evolution.
Not a repository. Not a product. Just the file itself.
Summary
The interesting thing about a CLAUDE.md is that it rarely stays small for long.
It usually begins as a short list of rules: be careful, ask before making major changes, think about dependencies, keep the structure clean. Then the real work starts. A bad assumption happens. A local fix breaks another surface. A verbose agent loads too much context and becomes slower and less useful. A vague user message gets interpreted the wrong way because one missing word flipped the meaning.
Each failure leaves a scar in the file.
That is how the document grows. It becomes more specific, more procedural, and more defensive. But then a second problem appears: the file becomes so large that merely loading it at the start of a session starts to cost too much attention and too much context budget. The operating manual becomes part of the problem.
So the file has to evolve again. It has to keep the lessons, but lose the weight. That is the arc that makes this kind of document interesting.
The first version was mostly guardrails
The earliest version looked like what many people would probably write first. It described the role, laid down a few hard rules, and tried to keep the assistant from doing reckless things.
It looked like this:
## Critical Rules For Project
- Unless operator specifically asked you to make code change, do not make any
change to code.
- When running migration script or making any change to the databases, always
create a backup of original database.
- When you are making a significant alteration to any logic, ask operator if
backwards compatibility has to be maintained.
There is nothing wrong with rules like these. They are sensible. They reflect the obvious risks of letting an AI loose in a real codebase.
But they are also generic. They help prevent the most obvious mistakes, not the subtle ones. They say “be careful,” but they do not yet encode how the codebase actually fails.
That distinction matters.
Early CLAUDE.md files often read like a code of conduct. Mature ones read more
like incident response notes written by someone who has already been burned.
The second stage is where the file starts absorbing real pain
Once the assistant is used for more than a few tasks, the document stops being abstract.
The first major kind of growth usually comes from coupling. A change that looks local turns out not to be local at all. An API shape affects the UI. A workflow change affects the renderer. A backend contract affects a terminal client, a web client, and some structured configuration.
That is how you get instructions like this:
## Cross-Module Awareness
Before editing any file in these folders, read related files in OTHER modules to
understand dependencies. Never assume a change is isolated.
After completing any change, trace through the data flow across all affected
modules to verify no breaking changes were introduced.
This is the point where the file stops being “advice” and starts becoming a model of the system’s pressure points. The document is no longer saying “write good code.” It is saying “this environment punishes local thinking.”
The same thing happens with testing and verification. At some point, “I changed it” is not enough. The file starts insisting on direct verification because too many completions were being declared from intuition rather than proof.
That produced rules like:
- Test all changes directly before reporting completion.
- Have I traced through with real data showing it works?
- Have I tested the failure modes, not just the happy path?
That change in tone is important. The file is no longer trying to sound reasonable. It is trying to stop repeated failure.
Then the file got too ambitious
One of the most interesting turns in the history of a document like this is when it becomes so thorough that it starts harming the thing it was meant to help.
At one stage, the file tried to solve the problem of shallow understanding by requiring a deep read of the whole application at the start of a fresh session.
It said this:
## Steps to follow in start of brand new session
Before doing any meaningful work, you must do an in-depth read to understand the
whole application:
1. Read each of these module trees in depth and to the deepest node
2. No skipping is allowed
3. Files must be read in depth. This is non-negotiable.
On paper, this looks rigorous. In reality, it creates a new failure mode.
If the operating manual requires an AI instance to front-load the entire world before doing useful work, then the file becomes a context tax. The assistant starts a session by spending a large portion of its budget reloading material that may not matter for the task at hand. The intention is safety. The result is bloat, weaker focus, and eventually worse performance after long sessions or compaction.
This is the moment where the document becomes self-revealing. It is not just teaching the assistant something about the codebase. It is teaching the human something about the limits of the assistant.
There is a real difference between “be aware of the whole system” and “reload the whole system every time.” The file had to learn that difference the hard way.
The best change was not adding more rules, but changing the loading strategy
The most meaningful improvement was the shift away from total upfront loading and toward task-driven context loading.
Instead of demanding a complete read of everything, the file started asking the assistant to load context based on the actual area of work.
That version looked like this:
## Steps to follow in start of brand new session
At the start of each session, use task-driven context loading to balance
understanding with context efficiency:
1. Ask the operator: "What area will you be working on this session?"
2. Load context based on the answer
3. For questions about OTHER modules during work: use focused exploration rather
than loading everything upfront
This is a much better rule, and not because it is shorter.
It is better because it captures a more mature understanding of the medium. A
good CLAUDE.md should not merely accumulate caution. It should allocate
attention well. It should preserve the important lessons while leaving enough
room for the actual task.
That was the moment the document stopped behaving like an ever-growing checklist and started behaving more like an interface contract between human and model.
The most human section is the one about operator mistakes
The section I find most revealing is not about architecture or commits or testing. It is the note about the operator.
At some point the file gained a rule that small missing words could completely reverse intent, and that the assistant should treat those contradictions as a higher priority than answering.
It looked like this:
**User behavior note (critical)**:
The user has a known issue where small missing words (e.g., not, never, don't,
can't, is/isn't) can unintentionally reverse the intended meaning.
Your primary task:
- Actively check whether the written message contains internal contradictions,
logic reversals, or missing negations that could flip meaning.
- If detected, interrupt immediately and ask for clarification before
proceeding.
This is a fascinating addition because it changes the role of the file.
Up to that point, most of the document is about technical safety: do not assume, check dependencies, verify behavior, commit clearly, preserve history. This rule is different. It is about conversational safety. It recognizes that the failure surface is not only code. Sometimes the dangerous ambiguity enters through the prompt itself.
That is one of the most useful insights in the whole evolution of the file. If an AI assistant is going to be useful in real work, it has to defend not only against software bugs but also against language bugs.
The file also became more explicit about process, not just behavior
Another notable shift is that later versions stopped focusing only on what the assistant should think and started focusing more on what it should leave behind.
That shows up in the addition of revision rules for architecture and issue documents, and in the explicit commit-message section added on the last update.
The final version includes language like this:
## Commit Rule
All commit messages must clearly describe what the change entailed.
Required:
- Short imperative title
- What changed
- Why the change was made
- Impact
This matters because it acknowledges that AI work is not just about producing
the right diff. It is also about producing a trail that another human can trust
later. The CLAUDE.md stopped being only a set of restrictions and became a
document about legibility.
That is a healthy change. It means the file has moved beyond “prevent damage” and into “leave the system understandable.”
The architecture and issue rules reveal a second purpose
One of the best clues about where the file ended up is that it started prescribing not just coding behavior, but documentation behavior.
At some point it became very explicit that design work and bug analysis should not be thrown into ad hoc markdown notes. They needed structure, revision history, and a clear boundary between assistant-authored content and operator feedback.
The file eventually carried rules like this:
architecture/{date}_{feature_name}/
r1.md
r2.md
...
issues/{date}_{issue_name}/
r1.md
r2.md
...
And also this:
### Revision Rules
1. First revision: Always start with `r1.md`
2. After operator feedback: That revision is locked
3. New revisions: Create `r{n+1}.md`
4. Never edit locked revisions
5. Each revision is standalone, not just a diff
That is not a small detail. It means the file was no longer concerned only with getting the right answer in the moment. It was trying to preserve the history of how an answer changed over time.
That is a very human concern. It reflects a workflow where collaboration is not
finished when the first draft appears. The file assumes iteration, review, and
the need to compare versions without losing earlier reasoning. In other words,
the CLAUDE.md was beginning to describe a working method, not just a behavior
filter.
I think that is an important part of the story, because it shows the document becoming more mature in two directions at once. It got better at constraining the assistant, and it got better at shaping the artifacts the assistant leaves behind.
What I think a good CLAUDE.md really is
Looking back at the whole arc, I do not think a good CLAUDE.md is a perfect
list of rules.
It is a compression algorithm for hard-earned lessons.
If it is too thin, it fails to encode the real risks. If it is too heavy, it consumes the very working space the assistant needs in order to be useful. The best version is not the longest one. It is the one that captures the deepest constraints with the least waste.
That is why the growth and the later trimming are both necessary parts of the story. The file had to grow in order to discover what mattered. Then it had to shrink in order to remain usable.
Closing thought
I used to think the interesting part of a CLAUDE.md was the list of rules it
contained.
Now I think the interesting part is the shape of the revisions.
You can watch the file learn what kind of mistakes are common, what kinds of instructions are too vague, what kinds of rigor are worth keeping, and where the document itself begins to create friction. That makes it more than a setup file. It becomes a record of negotiation between human expectations, codebase complexity, and model limits.
That is why I think these files are worth paying attention to. They are not just instructions for a machine. They are small histories of collaboration.
If I had to reduce the final shape of the file to a sketch, it looked something like this:
# Your Role
- senior engineer
- cross-module impact first
- no shortcuts
- avoid local fixes
# Zero assumptions policy
- never assume, always verify
- research before implementing
- reuse existing infrastructure
- verify integration points
# Operator-safety rules
- detect contradictions and missing negations
- ask for clarification before acting
# Commit rule
- say what changed
- say why
- say impact
# Architecture / issue document rules
- use revision folders
- never edit locked revisions
- keep each revision standalone
# Practical working style
- load context based on the task
- test directly before claiming completion
That is not the full text, but it is the final silhouette: less a giant dump of instructions, more a compact operating manual shaped by repeated mistakes, revisions, and correction.