AGENTS.md and the repository that explains itself
A convention nobody standardized became standard anyway. Here's what belongs in it and what doesn't.
Over the last year, essentially every coding agent converged on the same mechanism: a markdown file in the repository root telling the agent how to work in this codebase.
The names varied — AGENTS.md, CLAUDE.md, .cursorrules, .github/copilot-instructions.md — and the format did not. It is prose. The model reads it. That is the whole protocol.
A convention that emerges independently in five products in one year is telling you something about the shape of the problem.
what actually belongs in it#
I have written and rewritten these a dozen times. The version that works is shorter than you think and more specific than you want.
Commands. The exact invocations. Not "run the tests" — the command, including the flags, including how to run one test file.
## commands
- install: `pnpm install --frozen-lockfile`
- test: `pnpm vitest run`
- test one file: `pnpm vitest run src/foo.test.ts`
- typecheck: `pnpm tsc --noEmit`
- lint: `pnpm biome check --write .`
- dev server: `pnpm dev` (port 5173)This section alone eliminates most wasted agent turns. Without it, the agent guesses, guesses wrong, and spends four tool calls discovering your test runner.
Non-obvious structure. Where things live, when it is not inferable. "Database migrations are in db/migrations and must be created with pnpm db:new, never by hand." "The legacy/ directory is frozen — do not modify it."
Conventions that a linter does not enforce. If your linter catches it, do not write it down; the linter will tell the agent. Write down the things that are policy rather than syntax: "prefer composition over inheritance in src/domain", "all public functions in api/ need a docstring", "we do not use default exports".
Things that will break. "Do not run pnpm build — it takes 12 minutes and is not needed for tests." "The integration tests require Docker; skip them if it is not running." "Never modify schema.sql directly."
Boundaries. What the agent may not touch without asking. Production configs, migration files, anything with a security review requirement.
what does not belong#
Your entire architecture document. The agent reads this every session. A three-thousand-word essay costs tokens on every single request and dilutes attention across a lot of text that is irrelevant to most tasks.
Keep it under about 200 lines. If you need more, put it in a separate document and reference it: "for the event pipeline design, read docs/events.md before changing anything in src/events/."
Anything the code already says. Do not restate the type signatures. The agent can read.
Aspirations. "We value clean code" is not an instruction. "Functions over 40 lines get split" is.
Rules you do not actually follow. If the codebase contradicts the file, the codebase wins in the model's attention, and now your instructions are noise.
the part I did not expect#
Writing these has improved my documentation for humans.
The discipline of writing "here is exactly how to run the tests, here are the things that will surprise you, here is what not to touch" is precisely what a new engineer needs on day one, and it is precisely what most onboarding documents fail to contain because they were written by someone who already knew.
An agent is an infinitely patient new hire who will follow instructions literally and never ask a clarifying question out of politeness. That turns out to be an excellent test of whether your instructions are any good.
Several teams I know have merged their onboarding doc and their agent file into one. That is the correct end state.
the standardization question#
There is an ongoing effort to consolidate on AGENTS.md as the common name, with tools reading it as a fallback. That would be good and it is a coordination problem, which means it will take longer than it should.
In the meantime: write one file, symlink the rest. It costs nothing.
ln -s AGENTS.md CLAUDE.md— Dom, January 4, 2026