lockstep
Updated 16 min readNaman Jain

AGENTS.md: What It Is, Example File, and What to Leave Out

AGENTS.md is a markdown file of instructions for AI coding agents. What it is, which tools read it, a complete example file, and what to leave out.

Open a repository that has lived through a year of agent-assisted development and count the instruction files.

There's an AGENTS.md at the root. There's a CLAUDE.md next to it, older, half-overlapping. There's a .cursor/rules directory from the winter somebody tried Cursor, and a .github/copilot-instructions.md that nobody remembers writing. Four files, four eras, one repository.

Now open the AGENTS.md itself and read it the way a geologist reads a cliff face. Line 14 says the project uses styled-components; the team moved to Tailwind in March, but only the newer components know that. Line 31 says don't touch the payments module; that freeze ended two months ago, and every agent since has been carefully routing around a wall that no longer exists. Line 40 documents a test command that was renamed in April. Nothing in the file is a lie, exactly. Every line was true on the day it was written. The file just has no idea what day it is.

This post is two things. First, a straight guide: what AGENTS.md is, which tools read it, a complete example you can copy, and how it relates to CLAUDE.md and your README. Second, the part the guides skip: the jobs this file cannot do no matter how well you write it, and what has to sit next to it.

What is AGENTS.md?

AGENTS.md is a plain markdown file, usually at the root of a repository, that tells AI coding agents how to work in that project: how to build and test, which conventions to follow, what never to touch. It's an open standard, not a vendor feature. README.md is for humans; AGENTS.md is for agents. There's no required schema; headings are up to you.

It was published in August 2025 by a group including OpenAI, Google, Cursor, Factory, and Sourcegraph, to replace the pile of per-tool rules files (.cursorrules, CLAUDE.md, GEMINI.md, copilot-instructions) that teams were maintaining in parallel and watching drift. It's now stewarded by the Agentic AI Foundation under the Linux Foundation, and the project site counts more than 60,000 open-source repositories using it.

Which tools read AGENTS.md

Support is now close to universal. The one nuance worth knowing is Claude Code, which reads AGENTS.md natively as of v2.1.277 but gives CLAUDE.md priority when both exist.

ToolReads AGENTS.md?Its own instruction fileSource
OpenAI CodexYesAGENTS.md is its native formatagents.md
CursorYes, root and subdirectories.cursor/rules/*.mdcCursor docs
GitHub CopilotYes: cloud agent, code review, Copilot CLI.github/copilot-instructions.md, *.instructions.md (also reads CLAUDE.md and GEMINI.md)GitHub docs
Claude CodeYes, since v2.1.277, only when no CLAUDE.md or CLAUDE.local.md existsCLAUDE.md, .claude/rules/Claude Code docs
Gemini CLIYesGEMINI.mdagents.md
Windsurf, Jules, Devin, Zed, Aider, Junie, Amp, goose, opencode, Warp, VS Code, Roo Code, Kilo Code, Augment Code, FactoryListed as supportedVariesagents.md

Check your tool's own docs before relying on a specific behavior. "Reads AGENTS.md" can mean root only, nested files, or only when no native file is present, and those details change between releases.

What belongs in AGENTS.md

One test governs everything: will this line still be true in three months if nobody touches it? If yes, it's a candidate. If no, it does not belong in this file, and later I'll show you where it goes instead. AGENTS.md is a handbook. Handbooks hold constants.

Within that rule, the content that earns its place:

Commands, not descriptions. Agents execute; give them things to execute. pnpm test, not "we have a comprehensive test suite." Build, test, lint, migrate, in copy-paste form, with the non-obvious flags spelled out. Every command you write here is a command the agent doesn't have to guess, and guessed commands are how agents end up running your production seed script.

Invariants, the highest-value lines in the file. An invariant is a rule the code cannot state about itself. All money is integer paise, never floats. Migrations are generated, never hand-edited. The events table is append-only; corrections are new rows. These rules are invisible in any single diff, expensive when violated, and impossible for an agent to infer from reading the code, because the code merely obeys them without announcing them. Write the why alongside the what when you can. "Never call the inventory service in a loop, it rate-limits at 10 rps" lets an agent reason its way through cases you didn't anticipate; a bare prohibition doesn't.

The map. Ten lines of directory layout: where schemas live, where the API routes are, where generated code goes. Plus domain vocabulary. If your product says "organization" where the rest of the world says "workspace," write that down; vocabulary drift produces the most irritating class of agent bugs, the kind that compile perfectly.

Boundaries. What never gets logged. Which fields are PII. Which directories are machine-generated and must not be hand-edited. Which modules are off-limits without a human in the loop. These are cheap to write and catastrophic to omit.

Conventions no linter can enforce. Error responses follow problem+json. Tests sit next to the file they test. New files carry the license header. And the inverse rule: if a linter or formatter can enforce something, let it, and keep it out of this file. A rules file doing a linter's job does it with worse reliability and pays context for the privilege.

Then the discipline that keeps the file working:

Keep it brutally short. Every line is a tax on every session forever. Anthropic's own guidance for CLAUDE.md is to target under 200 lines, because longer files consume more context and reduce adherence, and the same physics applies to AGENTS.md in any tool. A focused fifty-line file outperforms a sprawling five-hundred-line one. If a line has never changed an agent's behavior, delete it.

Write it by hand. Auto-generated rules files are generic by construction, and generic instructions are the ones agents ignore first. Every line should exist because something went wrong once. A rules file is scar tissue, and you can't generate scar tissue.

Update it in the same commit as the constant it describes. If the PR that renames the test command doesn't also touch AGENTS.md, the file starts lying that day. This is the entire maintenance model, and it works precisely because constants change rarely. Which is foreshadowing.

A complete AGENTS.md example

Here's a full file for a fictional but typical product: a TypeScript monorepo with a Next.js web app, a Fastify API, and Postgres via Drizzle. Copy it, then delete every line that isn't true for your repo and add the ones that went wrong last month.

# AGENTS.md

Instructions for AI coding agents working in this repository.
Humans: see README.md. Package-specific rules live in each package's own AGENTS.md.

## Setup and commands
- Node 22, pnpm 9. Install with `pnpm install` (never npm or yarn).
- `pnpm dev` starts web (Next.js, :3000) and api (Fastify, :4000) together.
- `pnpm test` runs Vitest across all packages. Run it before every commit.
- `pnpm test --filter @acme/api` runs one package's tests.
- `pnpm lint && pnpm typecheck` must pass before a PR is opened.
- `pnpm db:generate && pnpm db:migrate` after any schema change.

## Map
- apps/web: Next.js App Router frontend
- apps/api: Fastify REST API; routes in apps/api/src/routes
- packages/db: Drizzle schema (packages/db/src/schema.ts) and migrations
- packages/ui: shared React components
- packages/generated: machine-written API client. Do not edit.

## Vocabulary
- "Workspace" in the UI is `organization` in code and the database.
- "Seat" means a billable user, not any user.

## Invariants
- Money is integer minor units (cents/paise), never floats. Use `Money` from packages/db.
- Migrations in packages/db/drizzle are generated. Never hand-edit them.
- The audit_events table is append-only. No UPDATE or DELETE; corrections are new rows.
- All timestamps are UTC ISO-8601 strings end to end.
- Never call the billing provider inside a loop; it rate-limits at 10 requests/second.

## Conventions
- API errors use RFC 9457 problem+json via `httpError()` in apps/api/src/errors.ts.
- Tests sit next to the file they test: `foo.ts` -> `foo.test.ts`.
- Server-only code imports "server-only" at the top of the file.
- Prefer small PRs: one concern per PR, with a description of why.

## Boundaries
- Never log request bodies, auth headers, or fields marked `@pii` in the schema.
- Do not modify .github/workflows or infra/ without a human reviewer.
- Do not add dependencies without saying why in the PR description.
- Ask before deleting files outside the package you're working in.

## Pull requests
- Title format: `area: short summary` (e.g. `api: add seat limit check`).
- Include the commands you ran and their results in the PR description.

Notice what's not in it: no "currently," no dates, no sprint goals, no "we're migrating to X." Nothing in that file should be stale in three months. That's the whole trick, and it's also the tell for what comes later.

Nested AGENTS.md in monorepos

The spec supports more than one file. Per agents.md, agents read the nearest AGENTS.md in the directory tree, so the closest one takes precedence and each subproject can ship its own instructions. A typical layout:

AGENTS.md                 # global: package manager, CI, PR rules, org-wide invariants
apps/web/AGENTS.md        # frontend: component patterns, accessibility rules
apps/api/AGENTS.md        # backend: error format, auth middleware, rate limits
packages/db/AGENTS.md     # schema rules, migration workflow

Rules of thumb that keep nesting from becoming its own mess:

  • Root holds what's true everywhere. Package manager, commit and PR format, security boundaries. Don't repeat these in child files.
  • Children hold only what's local. The frontend agent shouldn't carry the data pipeline's rules in its head, and vice versa.
  • Don't contradict the parent silently. If a package genuinely overrides a root rule, say so explicitly ("Unlike the root, this package uses npm because…").
  • Know how your tool loads them. Cursor applies a subdirectory's AGENTS.md when working on files there. Claude Code loads the AGENTS.md files from your working directory upward at session start, and a subdirectory's file when it reads a file in that subdirectory.

AGENTS.md vs CLAUDE.md vs README

Three files, three readers. The confusion comes from treating them as interchangeable.

README.mdAGENTS.mdCLAUDE.md
Written forHumansAny AI coding agentClaude Code specifically
Typical contentWhat the project is, how to get started, how to contributeCommands, invariants, map, boundaries, conventionsSame as AGENTS.md, plus Claude-specific instructions
Read byPeople, and agents that choose toCodex, Cursor, Copilot, Gemini CLI, Claude Code and othersClaude Code (and Copilot's agent surfaces)
ExtrasNoneNested files, nearest winsUser and org-level files, CLAUDE.local.md, .claude/rules/ path-scoped rules, @path imports
ToneExplanatoryImperative, terseImperative, terse

The practical setup for a team using more than one agent: make AGENTS.md the single shared source. If you have no Claude-specific instructions, you don't need a CLAUDE.md at all on current Claude Code. If you do, Anthropic's docs recommend a CLAUDE.md that imports the shared file and adds the extras below it:

@AGENTS.md

## Claude Code
Use plan mode for changes under src/billing/.

A symlink (ln -s AGENTS.md CLAUDE.md) also works when there's nothing Claude-specific to add. Keep the README for humans; agents can follow a link to it when they need the backstory, but it shouldn't double as their instructions.

I've gone deeper on what CLAUDE.md should hold versus agent memory, and on the full set of memory layers coding agents use.

What doesn't belong in AGENTS.md

Everything with a shelf life. The moment you type "currently," "for now," "as of," "this sprint," or a date, stop. You are writing news into a handbook.

The deprecation you shipped this morning. The endpoint rename. "Payments is frozen until the audit clears." The migration that's halfway done, so half the tables follow the new convention and half the old. These are, frustratingly, the most important things your agents need to know today, and this file is the wrong place for every single one of them.

Not because the information is wrong. Because of what happens after you write it. News expires, and a file has no way of knowing that it has. A markdown line has no status: it can't be marked superseded the way a decision record can. It can only be deleted, which erases the history, or left in place, which manufactures the sediment from the top of this post, one true-at-the-time line at a time.

And every stale line does double damage. It misleads the agent, and it spends part of a limited instruction budget doing so. Stuff enough news into the handbook and the agent gets worse at following the constants too. The news crowds out the rules.

The same shelf-life logic evicts two other tenants people keep moving in: task instructions ("today, refactor the auth module") belong in the prompt, not in a persistent file every future session must read; and full API documentation belongs at a link the agent can pull when needed, not inlined where it taxes every session whether relevant or not.

What AGENTS.md can't carry: the handbook and the standup

Let me be unambiguous before I start complaining: the standardization is good. A boring, neutral, Linux-Foundation-governed markdown file beat five proprietary formats, and the whole ecosystem is better for it. If your repo doesn't have an AGENTS.md, add one this week.

But notice precisely what got standardized. The container. Where the file lives, who reads it, what it's called. Nobody standardized, or even really asked, what a file like this can and cannot carry.

Here's the everyday version of the distinction. No software required.

Every company has an employee handbook. Values, expense policy, security rules, who to call for what. It's genuinely useful, and it's read exactly once, on day one. And no company on earth announces a fire drill by editing the handbook and hoping everyone rereads it. News travels through different machinery entirely: the standup, the announcements channel, a manager saying it out loud. Two channels, two jobs. Constants go in the handbook. State moves through the standup. No one confuses them, because with humans the confusion is impossible; you can feel that editing a PDF is not communication.

With agents, we have somehow talked ourselves into exactly that confusion. AGENTS.md is a handbook, and for most teams it's also the only channel that exists, so the news gets stuffed into it, and the sediment builds. If you want it in restaurant terms: the menu is laminated for a reason, and "we're out of the sea bass" travels by mouth. Nobody reprints the menu mid-service.

The reasons a file can't run the standup are structural. Better writing doesn't fix them. A file is read at session start, so the decision made at 2:00pm never reaches the agent session that began at 1:55 and will run for three more hours. A file is pull, not push: it informs whoever happens to read it and notifies no one. A file broadcasts: every reader gets everything, with no way to say "this concerns exactly the two services that consume this endpoint." A file collects no acknowledgments: you cannot know whether the mobile agent saw the deprecation before it spent the afternoon building against the old route. And a file is trapped inside its repository, while the decisions that hurt most are the ones that span three of them.

I made the long version of this argument about ADRs, and the physics is identical. A static record fails at exactly the moment a fresh decision needs to travel.

"Just have the agent update it"

The obvious fix, and I hear it every time: if decisions keep changing, have the agent append them to AGENTS.md and commit. The file stays current, git distributes it, problem solved.

Walk through what actually happens. The update reaches nobody. Your teammate's agent learns about it at its next session start, if a pull happened first; the three sessions currently mid-flight never learn at all. The single file becomes a write hotspot, and five agents appending decisions produce merge conflicts on the coordination file itself, which is a small poem about the whole situation. The context tax compounds, because appended decisions accumulate and every future session pays for every past decision forever; markdown has no supersede semantics, so the file grows until a human prunes it by hand and destroys the very history the appending was supposed to preserve. There is still no acknowledgment, no notion of a decision being binding on anyone, no targeting. And it all dies at the repo boundary anyway.

Follow the fix far enough and you notice what you're doing: rebuilding a coordination system inside a markdown file. Statuses, owners, ordering, acknowledgments, scopes. Markdown has none of those primitives, and no amount of convention will add them. Files hold state. They don't move it.

Where Lockstep fits

So the division of labor I'm arguing for is simple. Keep AGENTS.md as the handbook, written by hand, brutally short, all constants. And give the news its own machinery. That machinery is what I'm building with Lockstep.

The demand for it is already filed. An engineering manager running two teams (fourteen engineers) asked Anthropic for shared team memory across Claude Code sessions, calling the gap "the single biggest efficiency bottleneck for teams adopting Claude Code seriously." Context dies at the boundary between one person's sessions and another's. That's a standup problem. No handbook fixes it.

In Lockstep, a decision is a record with an owner and a status, not a line in a file. Lockstep captures decisions where they're actually made (Slack is the most mature source; Notion, Jira, Confluence, Google Docs, and GitHub PRs are supported too), and the owner approves each one with one click before any agent sees it. Approved decisions then brief engineers and coding agents: Claude Code, Cursor, or any MCP agent can call get_product_context to get the decisions relevant to the code it's about to touch. And at review time, a PR check flags changes that may conflict with an approved decision. It warns by default; blocking is opt-in.

It speaks MCP, so it doesn't care whether your agent reads AGENTS.md, CLAUDE.md, or something proprietary. It's open source (Apache-2.0) and self-hostable, and it's early stage.

Go back to the sediment file from the top. Every line true on the day it was written; the file with no idea what day it is. That was never a maintenance failure. It was a category error: a handbook asked to run the standup.

The industry spent a year standardizing the handbook, and it was a year well spent. I wrote a while ago that value migrates from the record to the feed that reads across it. AGENTS.md is the record, finally standardized, deservedly won. The feed is still missing.

Write the handbook. Keep it short. Stop asking it to run the standup.

Frequently asked questions

What is AGENTS.md?
AGENTS.md is an open-standard markdown file, usually at the repository root, that gives AI coding agents project instructions: commands, conventions, boundaries. README.md is for humans; AGENTS.md is for agents. It is stewarded by the Agentic AI Foundation under the Linux Foundation and read by most coding agents.
What should go in AGENTS.md?
Constants, meaning things still true in three months if nobody touches them: copy-paste commands, invariants the code can't state about itself, a short map of the codebase, boundaries (PII, generated directories), and conventions no linter can enforce. Keep it brutally short.
What should not go in AGENTS.md?
Anything with a shelf life: deprecations, freezes, half-done migrations, task instructions, and full API docs. News expires and a static file can't mark a line superseded; it just becomes misleading sediment.
Does Claude Code read AGENTS.md?
Yes, since v2.1.277, but by default only when the repo has no CLAUDE.md or CLAUDE.local.md in the working directory or above. If you keep both, put @AGENTS.md at the top of CLAUDE.md, or change the Project instructions setting in /config to read both.
What is the difference between AGENTS.md and CLAUDE.md?
AGENTS.md is the vendor-neutral file most agents read. CLAUDE.md is Claude Code's own instruction file, with extras like user-level and org-level files and path-scoped rules. Most teams keep AGENTS.md as the shared source and make CLAUDE.md import it.
Can I have more than one AGENTS.md?
Yes. In a monorepo, put shared rules in the root file and package-specific rules in an AGENTS.md inside each package. Per the spec, agents read the nearest file in the directory tree, so the closest one takes precedence.

Keep reading