Skip to content

AGENTS.md and CLAUDE.md — concise repository context

Repository context for coding agents is one short, versioned AGENTS.md that states the project layout, the exact build and test commands, the boundaries, and the proof required before work counts as done. Claude Code, Codex and Cursor discover instruction files differently, so a working setup also includes a check that shows which files each tool actually loaded.

You changed the test command from npm test to pnpm test:unit last sprint. CLAUDE.md got the edit, AGENTS.md did not, and today a Codex session ran the old command, saw it fail, and “fixed” the failure by rewriting a test. Nobody can say which file each agent read, because nobody ever checked.

This page is for the developer who owns a repository’s agent setup, and for the tech lead who scores it. It answers question 9 of the Developer Scorecard. Team-wide governance of the same files is the job of shared agent rules.

What a verified repository context gives you

Section titled “What a verified repository context gives you”
  • A root AGENTS.md of about 40 lines that every agent and every new teammate can trust.
  • A one-line CLAUDE.md adapter and a Cursor fallback, with no copied policy to drift.
  • Path-scoped rules for the two or three directories that need them, and nothing else always loaded.
  • A 20-line script that fails when Codex stops loading your rules, plus the Claude Code views that show the same for Claude.
  • Four copy-paste prompts: draft the core from evidence, probe discovery, probe a scoped rule, and audit for drift.

What belongs in the root AGENTS.md, and what does not?

Section titled “What belongs in the root AGENTS.md, and what does not?”

Put a line in the always-loaded core only when it is true for every task in the repository and an agent could not discover it by reading the code. Everything else goes to a layer that loads only when it is needed.

ContentWhere it goesWhy
Layout, exact commands, boundaries, completion evidenceRoot AGENTS.mdEvery session needs it
Conventions for one directory (src/billing/, infra/)Path-scoped rule or nested AGENTS.mdLoads only near that code
Multi-step procedures (release, migration, incident)A skillLoads on demand
“Never” rules that must holdHooks, permissions and sandboxing, CI, branch protectionInstructions steer; they do not enforce
Current task stateintent.md, spec.md, plan.md in the artifact chainExpires when the task ends
Personal preferences~/.claude/CLAUDE.md, CLAUDE.local.md, or your Codex user fileNot everyone’s truth

A core that fits this table looks like this, for a TypeScript monorepo on pnpm:

AGENTS.md
# Repository contract
<!-- Owner: @platform-team · reviewed monthly · last review 2026-09-26 -->
## Layout
- Web app: `apps/web/` (Next.js). API: `apps/api/` (Fastify). Shared code: `packages/`.
- Database migrations: `apps/api/migrations/`, one file per change, never edited after merge.
## Commands (run from the repository root)
- Install: `pnpm install --frozen-lockfile`
- Unit tests: `pnpm test:unit` · one package: `pnpm --filter @acme/api test:unit`
- Types: `pnpm typecheck` · Lint: `pnpm lint` · E2E: `pnpm test:e2e` (needs `pnpm dev` running)
## Boundaries
- Do not run commands that reach production, and do not read `.env.production`.
- Ask before adding a dependency or changing an exported API in `packages/`.
## Done means
- `pnpm typecheck`, `pnpm lint` and `pnpm test:unit` pass; report the commands and their results.
- List changed files and anything you could not verify.

Every line names a path, a command or a checkable condition. “Write clean code” and “test thoroughly” fail that test: no reviewer and no agent can tell whether they were followed. Anthropic’s memory documentation gives the same advice (“Run npm test before committing” instead of “Test your changes”) and a size target of under 200 lines per CLAUDE.md file (Claude Code memory docs, checked 2026-09-26).

How do Claude Code, Codex and Cursor find the core?

Section titled “How do Claude Code, Codex and Cursor find the core?”

The three tools discover instruction files differently, so the adapter differs per tool. Keep the policy in AGENTS.md and give each tool the thinnest adapter that makes it load that file.

Claude Code reads CLAUDE.md or .claude/CLAUDE.md from the working directory and every directory above it at launch, and nested CLAUDE.md files when it reads files in their directory. Since v2.1.277 it also reads AGENTS.md directly, but only when no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in the working directory or above it. The stable npm channel reached v2.1.280 on 2026-09-30, so a teammate on an older stable build does not get the direct read yet.

Use an import, which works on both channels and never loads the file twice:

CLAUDE.md
@AGENTS.md
## Claude Code only
- Use plan mode before changing anything under `apps/api/migrations/`.

Scoped detail goes in .claude/rules/*.md. A rule with paths frontmatter loads only when Claude reads a matching file; paths is the only frontmatter key Claude Code reads there (checked in Claude Code v2.1.285 on 2026-09-30).

.claude/rules/billing.md
---
paths:
- "apps/api/src/billing/**"
---
- Money is integer cents (`number`), never floats. Use `formatCents()` for display.
- Every billing change needs a test in `apps/api/test/billing/`.

.claude/rules/ is Claude-only: Codex never reads it. And with the @AGENTS.md import in place, Claude Code does not load a nested AGENTS.md either, because its default “Project instructions” mode (claude-md-or-agents-md) uses AGENTS.md only in a project that has no CLAUDE.md of its own. So put a scoped rule that both tools must follow in the nested AGENTS.md, and give Claude a nested CLAUDE.md beside it that contains only @AGENTS.md; Claude loads it when it reads a file in that directory:

apps/api/src/billing/CLAUDE.md
@AGENTS.md

The alternative is to set “Project instructions” in /config to claude-md-and-agents-md, which loads AGENTS.md files beside CLAUDE.md and skips a file that CLAUDE.md already imports (checked in Claude Code v2.1.285 on 2026-09-30). Keep .claude/rules/*.md for scoped detail that only Claude needs.

Two details from the memory docs matter here: imports organise a long file but do not reduce its context cost, because imported files load at launch, and block-level HTML comments are stripped before the content reaches the model, so the owner line in the template above costs no tokens.

  1. Draft from evidence, not memory. Run /init in Claude Code or Codex for a first draft, or paste the drafting prompt below. In Claude Code, /init also reads existing .cursor/rules/, .cursorrules and .github/copilot-instructions.md and folds their important parts into the draft, and suggests improvements when a CLAUDE.md already exists instead of overwriting it.

  2. Cut every line that fails the table above. Delete anything the agent can read from package.json, the directory tree or the linter config. Delete adjectives. Keep commands, paths and boundaries.

  3. Run every command in the file in a clean checkout. A command that has not run successfully does not go in the core. This is also the moment to find the pnpm test:e2e that silently needs a dev server.

  4. Move scoped detail out. For each directory that has real local conventions, write one nested AGENTS.md and a one-line CLAUDE.md beside it that imports it, as the Claude Code tab shows. Use a .claude/rules/<topic>.md with paths only for detail that Claude alone needs. Two or three scoped files are typical; twenty means the core is being split rather than trimmed.

  5. Wire the adapters from the tabs above: CLAUDE.md with @AGENTS.md, nothing for Codex, a probe and possibly a pointer rule for Cursor.

  6. Assign an owner and a gate. Add AGENTS.md, CLAUDE.md, .claude/rules/ and .cursor/rules/ to CODEOWNERS, and run the load check from the next section in CI (pinned CLI, see the Codex tab). The owner signs off on every change to the core, the same way they would on a CI config change.

How do you prove each agent loaded the rules?

Section titled “How do you prove each agent loaded the rules?”

Two kinds of proof work without anyone reading the files line by line: a load check that shows which files reached the model, and a behaviour probe that shows the agent can state and apply them.

Load check, per tool.

Run /context in a new session and check the list under Memory files; /memory lists the same files and opens them. For a record you can inspect later, log every load with an InstructionsLoaded hook in your personal .claude/settings.local.json (the command needs jq):

.claude/settings.local.json
{
"hooks": {
"InstructionsLoaded": [
{
"hooks": [
{
"type": "command",
"command": "jq -c '{file_path, load_reason}' >> \"$CLAUDE_PROJECT_DIR/.claude/instructions-loaded.log\""
}
]
}
]
}
}

Open a file under apps/api/src/billing/ and the log gains a path_glob_match line for billing.md. The hook fires for CLAUDE.md, rules and imports (load_reason: "include"). The log may not show an AGENTS.md that Claude reads directly without a CLAUDE.md, because that path runs through the built-in agents-md plugin; the import makes the load visible. The hook is observability only; it cannot block a load. Add the log file to .gitignore.

/doctor prompt-audit (checked in Claude Code v2.1.285 on 2026-09-30) audits the instruction files that load in this project. It runs through the bundled claude-api skill, so it is unavailable when bundled skills are disabled in settings. Review its findings before you accept any fix.

Behaviour probe, in every tool. Paste these into a fresh session after any change to the instruction files. The expected answers go in the pull request description; a wrong answer blocks the merge.

The second question is the useful one: an agent that answers “integer cents, 1999” has applied the rule, not only listed it.

When should a rule be added, and when deleted?

Section titled “When should a rule be added, and when deleted?”

Add a line only after the same mistake happens twice in separate sessions, and only when you can phrase the fix as something checkable. That is the “two-strike” part of the top Scorecard answer. The other half is deletion: a rule that no probe or failure has needed in months is context you pay for in every session. The ablation protocol for pruning context files removes lines one at a time and restores only what breaks.

What breaks with AGENTS.md and CLAUDE.md, and how do you recover?

Section titled “What breaks with AGENTS.md and CLAUDE.md, and how do you recover?”
SymptomCauseRecovery
Claude Code ignores AGENTS.md after you add a personal CLAUDE.local.mdAny CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md stops the direct AGENTS.md readAdd @AGENTS.md to a CLAUDE.md, or set Project instructions in /config to claude-md-and-agents-md
A teammate’s Claude Code never sees AGENTS.mdThey are on a build before v2.1.277 (the stable channel reached v2.1.280 on 2026-09-30), a Bedrock, Google Cloud, Microsoft Foundry, LLM-gateway or telemetry-off session before v2.1.281, or the built-in agents-md plugin is offThe @AGENTS.md import works on every version
Codex follows the root rules but not the ones at the end of a nested fileThe combined files exceed project_doc_max_bytes (32 KiB); later files are cut firstShorten the core, or move procedures to skills; raise the limit only as a stopgap
Codex ignores your AGENTS.md edits in one directoryAn AGENTS.override.md in the same directory replaces itDelete the override or merge it; the load-check script shows which one reached the model
Codex loads no project instructions at allThe project is untrustedTrust the project when Codex asks; confirm with codex debug prompt-input
On a Windows clone, CLAUDE.md contains only the text AGENTS.mdA committed symlink checks out as a text file unless core.symlinks is onReplace the symlink with an @AGENTS.md import
The agent follows a rule inconsistentlyTwo files contradict each other, and the model may pick eitherRun the drift audit prompt, or /doctor prompt-audit in Claude Code, and keep one source
An agent ran a command the file forbidsInstruction files guide the model; they are not a security boundaryMove the boundary to a deny rule, a hook or CI, and keep the sentence only as an explanation
An access token appears in a rules fileA personal note was committedRotate the token first, then remove it from history; keep secrets in environment variables