My CLAUDE.md Is a Router, Not a Manual: 6 Rules From Three of My Repos

Almost every line should send the agent to another file. These are the places where mine did not, and what went stale.
On the morning of 2026-03-23, I made the CLAUDE.md in mirae, my Flutter alarm app, as helpful as I could.
It had the package structure, the flavors, the Riverpod codegen rules, a TDD protocol, a "What not to do" section, and a whole inventory of derry commands.
That came to 250 lines, which is a small manual.
It lasted a little over a day.
At 12:25 the next afternoon, a commit titled "centralizes operational guidance and streamlines agent docs" cut the file to 27 lines and moved the rules into AGENTS.md, scripts/AGENTS.md, and a new CONTRIBUTING.md.
(Same author, same repo, about 26 hours apart. I argued with myself and lost.)
Today, the whole "Start here" section is three lines:
- Read `AGENTS.md` first.
- Use `PLAN.md` as the execution queue unless the user explicitly redirects scope.
- Use `docs/core/PRODUCT.md` for product intent and `CONTRIBUTING.md` for contributor workflow.
That file is no longer a manual. It is a router, because nearly every line in it points the agent at some other file. Here are the six rules I follow now. Each one comes from something that went stale, or that I misread, in three of my own repositories.
1. Give the agent a "working on → read" table instead of the docs
minimal-git-explorer is one of my VS Code extensions.
Its CLAUDE.md has a "Documentation Map" section that starts with "Read only what the task requires:" and then gives a two-column table.
The left column says what you are working on, and the right column names one file.
Medium can't render tables, so here are the current rows as a list:
- VS Code view/command contribution →
docs/specs/git-explorer-spec.md - Git data types / parsers →
docs/specs/git-data-contract.md - Why git CLI (not VS Code git API) →
docs/notes/adr-001-git-cli-only.md - Why esbuild →
docs/notes/adr-002-esbuild-bundler.md - Why parsers are pure functions →
docs/notes/adr-003-parser-isolation.md - Initial release history →
PLAN.md,docs/plans/phase-*.md
The table was never the problem. The text around it was. Until a docs commit on 2026-08-13, the same file also told the agent the story of the project:
**Current state:** Scaffold only (`helloWorld` command stub). Nothing from the planned architecture is implemented yet.
It also kept a section called "Planned source layout (from PLAN.md)". The 2026-08-13 commit message says it reconciled the contributor guide "with the six-view implementation." So for some period, the file the agent always reads first was describing a scaffold that no longer existed.
The spec and ADR rows came through that commit unchanged. Only the narration had gone bad. The fix merged five per-phase rows and a "Full product spec" row into the single "Initial release history" row, and replaced the story with three facts in the present tense.
2. Say which end of each route holds authority
The first version of that map, from 2026-05-30, ended with this note:
> Do not read `PLAN.md` for implementation details — use the `docs/` files above. `PLAN.md` is the product source-of-truth; the `docs/` files are the implementation-ready distillations.
By August, that note was backwards.
The plan described a 0.1.0 that had already shipped, and the specs described the actual code.
The same 2026-08-13 commit swapped the note for two lines:
`PLAN.md` and the numbered phase plans are historical `0.1.0` planning artifacts.
Current behavior and contracts live in `docs/specs/` and the production source.
The routes barely changed. What flipped was the authority. A router that sends the agent to the right files but names the wrong winner is arguably worse than no router at all, because the agent follows it with confidence.
3. Keep commands next to the scripts that run them
The 250-line mirae manual mentioned Derry 24 times: derry test ("All tests with coverage"), derry format, derry bootstrap, derry hard, derry loco-sync, and more.
On 2026-04-02, the command runner was renamed from Derry to Merry.
That rename touched 44 files, including AGENTS.md and scripts/AGENTS.md.
CLAUDE.md was not one of them, because by then it had nothing left to rename.
In place of the command list, it has this line:
Do not duplicate command inventories here; `scripts/AGENTS.md` is the command source of truth.
Later that same day, another commit split coverage out of the test task.
scripts/AGENTS.md now says merry test runs "Flutter tests without coverage" and merry test-coverage runs them "with coverage".
So the old manual would have been wrong twice in one day: once on the tool's name, and once on what test does.
4. Expect files to move, and keep the cost to one line
On 2026-04-25, docs/documents/ was renamed to docs/core/ in a documentation restructure that touched 27 files.
This was the entire CLAUDE.md part of that diff:
-- Use `docs/documents/PRODUCT.md` for product intent and `CONTRIBUTING.md` for contributor workflow.
+- Use `docs/core/PRODUCT.md` for product intent and `CONTRIBUTING.md` for contributor workflow.
That is what a router costs you when the tree moves: the path changes and the route stays. It is also the only change the file has had since the March rewrite.
5. Route by directory, but read "nearest wins" carefully
mirae has 28 tracked AGENTS.md files.
There is one at the root, and others in lib/, ios/, scripts/, test/, docs/, and further down, as deep as lib/presentation/screens/alarm_ring/.
CLAUDE.md sends the agent into that tree with a single rule:
- When editing files under a directory with its own `AGENTS.md`, follow the nearest file.
If you read that quickly, it sounds like an override: the closest file wins and the root loses.
The repository does not say that.
The root AGENTS.md has its own rule about the tree:
- Subdirectory `AGENTS.md` files extend this file and should only document local deviations.
The nested files also write out their own inheritance chains.
Right under its title, lib/services/alarm/AGENTS.md says "Inherit AGENTS.md, lib/AGENTS.md, and lib/services/AGENTS.md first."
So "nearest" tells the agent which file to open first for the file it is editing. It does not tell the agent which files it may skip.
It only changes what the agent does where a subtree adds a rule the root never mentions, such as "Preserve UUID↔int mapping stability" in the alarm service directory.
6. Even the smallest router needs a sign on the door
peak-fanout takes this the furthest.
Its first commit, the one that initialized the Expo project, already had a one-line CLAUDE.md:
@AGENTS.md
That one line routes everything.
What it does not say is where a new rule belongs, and a CLAUDE.md is exactly the file where someone (or some agent) will paste one. The 250-line version at the top of this post shows where that leads.
The 2026-09-11 rewrite kept the import and added the sign:
All project guidance lives in `AGENTS.md` so that Claude Code and Codex read the same rules.
Do not add rules here. Edit `AGENTS.md` instead.
@AGENTS.md
That makes eight lines, and only the last one routes anything. The rest is there so the next editor doesn't turn the file back into a manual.
What I Took Away
- Narration goes stale first. A sentence like "Scaffold only" in a file the agent always reads stays true only until somebody ships.
- A route costs less to maintain than a copy. A 44-file rename cost this
CLAUDE.mdnothing, and a 27-file move cost it one line. - Write down who wins, not just where things are. The map in item 2 still pointed at the right files after its note about who wins had gone backwards.
- Nested files add to the root; "nearest" only sets the reading order. If a subtree file needs to contradict the root, the root is the file to fix.
Here is a small exercise.
Open your own CLAUDE.md and count two kinds of lines: the ones that send the agent to another file, and the ones that repeat what another file already owns.
If the second count is bigger, you have a manual. If my history is anything to go by, it is also a stale one.
I'd like to hear what your counts are, and which of your lines went stale first.
Get the next post.
If you made it to the end, meet the next post in your inbox or RSS reader.