CHAPTER III / ENGINEERING
2026-07-09 · 5 min read
One Rule File, Thin Adapters
Open a repository that several people have used with AI coding tools and you will often find the same quiet mess: a CLAUDE.md, a .cursor rules file, a Copilot instructions file, maybe a GEMINI.md, each with its own slightly different version of the same project rules. They started as copies of one another. They did not stay copies. One got a new convention, another got a correction, a third got a rule nobody remembers adding, and now the project has four answers to the same question and no way to tell which one is current.
This is a small problem that scales badly. Every tool a teammate adopts is a new file that claims authority over how agents should behave in your codebase, and every claim is a chance to disagree with the others.
The instinct that causes it
The trap is reasonable. Each tool documents its own config file, so when you adopt the tool you create the file it asks for, and you fill it with your rules. Do that four times and you have four sources of truth. Nobody chose to fragment the rules. The tooling nudged everyone into it, one onboarding at a time.
The failure mode is not that any single file is wrong. It is that there is no canonical one. When rules live in four places, updating them means updating four places, which means in practice updating one and letting the rest rot. An agent then reads whichever file its tool happens to prefer, and behaves according to whichever copy last got attention. You debug behavior by guessing which file won.
One file owns the rules
The fix is to decide, on purpose, that exactly one file owns your agent rules, and that everything else points at it.
AGENTS.md is the natural choice for that file. It has become a shared cross-tool convention rather than one vendor's format, and most modern agents read it directly. But the specific filename matters less than the principle: pick one canonical rule surface, put the real content there, and never let a second file hold a competing copy.
Then every tool-specific file becomes an adapter, and an adapter is a pointer, not a copy. Three lines that say "read the canonical file." If a tool reads AGENTS.md natively, it needs no adapter at all. If a tool insists on its own path, its file exists only to redirect to the real one. The moment an adapter grows actual content, that is your signal: the content does not belong in the adapter, it belongs in the canonical file, and it should move there.
This is the whole discipline. Rules live in one place. Tool files are thin redirects. You update one file and every tool sees the change, because none of them holds a private version of the truth.
Narrow, do not contradict
Real repositories are not flat, and a single rule file cannot say everything about every corner of a large codebase. So there is a second rule that keeps the first one from breaking: scoped rules may narrow the canonical rules, but they may never contradict them.
A subdirectory with genuinely different conventions can carry its own nested rules once the code actually justifies it. A frontend package might add constraints a backend service does not have. That is fine, as long as the nested file tightens the shared rules for its own scope rather than overriding them with a different answer. The moment a scoped file contradicts the root, you are back to two sources of truth wearing a trench coat, and an agent working across both will get whiplash.
The test is easy to apply. Read the scoped rule and ask: is this adding a constraint, or is it disagreeing with the root. Adding is allowed. Disagreeing means one of the two files is wrong and you need to fix the conflict at its source, not paper over it with local exceptions.
Give the reader a front door
There is one more thing that separates a repository an agent can work in from one it flails in, and it is not a rule at all. It is a front door.
A large codebase is easy to get lost in, for a person and for a machine. If an agent has to crawl the whole tree to reconstruct what the project is and what state it is in, it will burn effort and still guess. So point at a small, fixed set of files that answer the first questions: what is this project trying to do, what is actually true and working right now, what is in progress. Three files, always the same three, always current. The agent loads those and starts from real context instead of from a scan.
This costs almost nothing to maintain and changes the quality of the help you get. An agent that starts oriented makes narrower, more correct changes. An agent that starts lost makes confident, sprawling ones. The difference between the two is often just whether someone left a door where the reader could find it.
Why now
Cross-tool rule files used to be a nice-to-have because most teams standardized on one assistant. That is over. Editors, terminals, and CI systems are all shipping agents, and people mix them freely: one developer in one tool, another in a second, an automated agent in a third, all in the same repo on the same day. Every one of them wants to know how to behave in your codebase, and every one of them will read whatever authoritative-looking file it finds.
That is exactly the condition under which fragmented rules do the most damage. When readers were homogeneous, drift was a slow annoyance. When every contributor might be using a different agent, a single canonical rule surface stops being tidy and starts being the thing that keeps your automated help consistent.
The short version
If your project has more than one file telling agents how to behave, you probably have more than one answer, and you cannot tell which is live. Collapse it. Put the real rules in one canonical file, make every tool-specific file a thin pointer to it, let scoped rules narrow but never contradict the root, and leave a small front door of current context so any reader starts oriented. It is a modest amount of structure, and it is the difference between AI tooling that compounds and AI tooling that quietly works against itself.