AGENTS.md as the Single Source of Truth
The agent-fragmentation problem shows up slowly, then all at once. A team starts with Claude Code and writes a CLAUDE.md. Someone adds Cursor and writes .cursor/rules. Codex comes in and gets AGENTS.md. GitHub Copilot gets .github/copilot-instructions.md. A few months later there are five rule files, three of them say different things about tests, and nobody knows which one is supposed to be authoritative.
This is not a documentation problem. It is a harness problem.
When two agents read different rules for the same repo, you no longer have one engineering process. You have one process per tool. One agent thinks it can edit lockfiles directly. Another agent thinks lockfiles are package-manager-owned. One agent uses pnpm test. Another uses npm test. One agent opens a PR. Another pushes to main because the rule only existed in the file it never read.
The argument for AGENTS.md as a single source of truth is simple: cross-agent project rules should live in one canonical file, and tool-specific files should either point at it or declare their deviations. The goal is not to worship a filename. The goal is to stop your repo from becoming a rule fork.
Why AGENTS.md is the right candidate
AGENTS.md has two practical advantages.
First, the name is tool-neutral. CLAUDE.md is excellent for Claude Code, but the name makes it awkward as the canonical file for Codex, Cursor, Copilot, or whatever comes next. AGENTS.md says what the file is for: agents. That matters in a multi-tool codebase because contributors should not need to know which vendor popularized a rule file before they know where the project rules live.
Second, Codex treats AGENTS.md as first-class project instructions. The current OpenAI docs describe global and project discovery, nested overrides, fallback filenames, and byte limits. That gives AGENTS.md concrete harness behavior, not just convention. It is read before work. It participates in scope and precedence. It can be layered.
This does not mean every tool reads AGENTS.md perfectly today. It means AGENTS.md is a strong canonical document to adapt from. If a tool needs a different file, generate or point from that file. Keep the content source in one place.
The consensus underneath the filename
The broader agent-harness conversation is converging on the same shape from different directions.
Mitchell Hashimoto's harness-engineering framing is operational: when the agent makes a mistake, improve the environment so the same mistake is less likely next time. That environment includes instructions, tools, checks, and feedback loops.
OpenAI's Codex harness writing makes the repository knowledge point directly: give the agent a map, not a thousand-page manual. Keep durable knowledge in the repo. Keep the instruction layer short enough to be useful.
LangChain's recent harness and memory writing pushes the same idea from the agent-framework side: the agent is not just a model; it is a system around the model, and memory/instructions are part of that system. If AGENTS.md and CLAUDE.md are both loaded into context by different harnesses, they are memory surfaces. Fragmented memory produces fragmented behavior.
The shared lesson is not "write more rules." It is "design the system that carries rules." A single source of truth is a systems decision.
What to centralize
Centralize rules that describe the project rather than the tool.
Package manager:
- Use npm only. package-lock.json is canonical.
- Do not add pnpm-lock.yaml, yarn.lock, or bun.lock.
Validation:
- Before opening a PR, run npm run lint and npm run build.
- If a test cannot run locally, say which command failed and include the error.
Repo process:
- Branch from main and open a PR. No direct pushes to main.
- One logical change per commit. Do not mix content, code, and dependency churn.
Architecture:
- Route metadata lives in src/lib/seo.ts and scripts/generate-sitemap.ts.
- Do not introduce a second routing source of truth.
- Generated dist/ files are build output and are never edited by hand.
Security:
- Never print secret values. Refer to secrets by environment variable name only.
- Do not add .env files to git.
These rules should mean the same thing to Codex, Claude Code, Cursor, and a human reviewer. If they live in five places, they will drift. If they live once and adapters point to them, the drift surface shrinks.
What stays per-tool
Do not centralize harness mechanics that only one tool understands.
Claude Code hooks and skills belong near Claude Code:
.claude/settings.json
.claude/skills/
Codex-specific discovery details belong in Codex-facing notes:
- Codex reads AGENTS.md from global and project scopes.
- Nested AGENTS.override.md files may narrow local rules.
- If instructions look stale, restart the Codex session.
Cursor rule globs belong in Cursor's rule files. Copilot-specific prompt behavior belongs in Copilot's instruction file. A single source of truth does not mean every tool-specific behavior gets flattened into AGENTS.md. It means project rules are canonical, and adapters carry only the tool-specific edge.
The boundary is important. A bloated AGENTS.md that tries to explain every harness becomes the same unreadable manual OpenAI warned about. Keep AGENTS.md as the cross-agent map. Put rich procedures in tool-specific skills, hooks, or docs.
The migration approach
Start with an inventory. List every agent instruction file in the repo:
AGENTS.md
CLAUDE.md
.cursor/rules/*
.github/copilot-instructions.md
.claude/skills/*
Then classify each rule into one of three buckets.
Project rule: applies no matter which agent is working. Move it to AGENTS.md.
Tool rule: only makes sense for one harness. Keep it in the tool file.
Reference material: too long for always-loaded instructions. Move it to docs/ and link to it from AGENTS.md.
The classification step is where most teams discover the mess. A 40-line "Claude rules" section is often 30 lines of project rules, 5 lines of Claude Code mechanics, and 5 lines of stale preferences. Split it. Do not preserve bad structure just because it is already there.
Next, rewrite AGENTS.md as the canonical project map. Keep it short. Include project facts, commands, working rules, architecture boundaries, and references. Do not copy every explanation from the old files.
Then turn tool files into adapters. A thin CLAUDE.md can say:
# CLAUDE.md
AGENTS.md is the canonical project instruction file.
Read it before making changes.
Claude Code-specific behavior:
- Hooks live in .claude/settings.json.
- Workflow-specific procedures live in .claude/skills/.
A .github/copilot-instructions.md can say the same thing in Copilot's preferred shape. Cursor rules can point at AGENTS.md and add Cursor-only globs if needed.
Finally, add a review rule: any change to cross-agent project behavior must update AGENTS.md first. Adapter files only change when tool-specific behavior changes.
When single source of truth does not fit
There are real exceptions.
A regulated team may need separate approved instruction files for separate tools because each tool has different risk controls. In that case, the source of truth may be a policy document or generator, not AGENTS.md.
A monorepo with radically different subprojects may need nested AGENTS.md files. The root file should be the map; local files should narrow rules for apps/web, services/payments, or packages/sdk. That is still single-source thinking at each scope, not one giant root manual.
A team that is mid-migration from Claude Code may keep CLAUDE.md canonical for a while and generate AGENTS.md. That can be reasonable if the migration is explicit and the generated file says "do not edit by hand."
The standard is not purity. The standard is whether a rule has one owner. If nobody can answer "where do I change the test command for all agents?", the system is broken.
The payoff
The payoff is boring in the best way. Fewer contradictory edits. Faster agent onboarding. Less weird behavior across tools. Easier reviews. Shorter instruction files. More rules backed by real enforcement. When an agent does something wrong, you know where to patch the instruction layer.
AGENTS.md as single source of truth is not a magic convention. It is a maintenance strategy for a world where every repo will be touched by more than one agent. AgentLint is useful in that world because it checks the source-of-truth file and its neighboring harness files for drift before the drift becomes behavior.