0%

0000000

0x00

AGENTS.md vs CLAUDE.md: Read by Five Tools, Enforced by None

One rulebook. Every AI coding tool. AGENTS.md on red, green and blue frames, fanning out to Claude Code, Cursor, Cline, Gemini CLI, Copilot and Codex.

A shared AGENTS.md file gets five AI coding tools reading the same rules. It does not make them follow the rules: that still needs review guidelines and a CI gate that actually checks.

TL;DR: In one of my own repositories, AGENTS.md is 678 bytes of boilerplate that next dev writes back into it on every run, and none of the project's rules. Those survive only because CLAUDE.md is a symlink to a different file, so any tool that reads AGENTS.md alone gets the boilerplate. That is the risk whenever AI coding tools such as Claude Code, Cursor, Cline, Gemini CLI and GitHub Copilot each default to reading a different rules file: the rules exist, they just aren't where every tool looks. I set engineering standards for a cross-functional team of 20 across five concurrent products with an AGENTS.md rulebook, AI coding tool configs (Claude Code, Cursor, Cline, Gemini CLI), code review guidelines and CI quality gates. Here is what belongs in the shared file, what stays in each tool's own config, and what no rules file will ever enforce on its own.

Why Do Claude Code and Cursor Need One Shared AGENTS.md Rules File?

Each tool defaults to reading a different filename: CLAUDE.md for Claude Code, .cursor/rules/*.mdc for Cursor, .clinerules/ for Cline, GEMINI.md for Gemini CLI, .github/copilot-instructions.md for GitHub Copilot. A rule written for one tool is invisible to the next tool added to the team, unless someone keeps the files in sync by hand, or the project adopts one of them as the shared source.

AGENTS.md exists to solve exactly this. The spec describes it as "a README for agents": a dedicated, predictable place for agent-specific instructions, plain Markdown with no required schema, stewarded by the Agentic AI Foundation rather than any one vendor. OpenAI Codex uses it as its native format. Cursor, Cline and GitHub Copilot all read it natively today, alongside their own formats. Claude Code added support for it too, falling back to it only when no CLAUDE.md exists on the path. Gemini CLI reads it if you tell it to, through a settings key rather than out of the box.

That difference in defaults is where drift starts. Two of my own repositories show it happening in two different ways.

Why Does a Rules File Drift When Every Tool Keeps Its Own Copy?

It drifts because nothing checks that two files stay identical, and because a file every tool can write to is a file any tool can overwrite. Both failures show up in my own repositories, not as theory.

In one project, a CMS build, AGENTS.md and CLAUDE.md are byte-for-byte identical, confirmed with diff. Both are plain files, not a symlink. The shared content is an index pointing to rules.md, conventions.md and security.md, and nothing in the repository enforces that an edit to one copy also lands in the other. git log dates the last edit to AGENTS.md at 2026-09-26, and no hook or check ties it to CLAUDE.md. A future edit to one with no matching edit to the other diverges silently, with nothing to catch it.

A second project shows a worse version of the same problem. CLAUDE.md there is a symlink to a real index file elsewhere in the repo, and it carries the project's actual rules. But AGENTS.md in the same repository is a real file, not a symlink, and it holds none of that. It holds a boilerplate block that next dev writes into it automatically; the block's own text says it "is written and re-added by next dev." That block gets re-added the moment it's removed, so the diff never stays clean. Any tool that reads only AGENTS.md, which by default includes Cursor and Claude Code when no CLAUDE.md exists, would see the injected boilerplate instead of the project's real standards. The rules survive in that repository only because CLAUDE.md happens to point somewhere else. Nothing forces a re-check after a tool overwrites the shared file.

What Goes in the Shared AGENTS.md File, and What Stays in a Tool's Own Config?

The shared file carries project facts, the stack, hard rules and the working agreement: anything every tool needs regardless of which one a given session is running. Tool-specific mechanisms, like Claude Code's subagent routing or Cursor's glob-scoped frontmatter, stay in that tool's own config, because no other tool can act on them anyway.

This site's own repository is the cleanest example I have of that split, and it currently sits on the wrong side of the recommendation I'm about to give: it has a CLAUDE.md but no AGENTS.md at all, so Cursor, Cline and Gemini CLI, on their documented defaults, see none of its rules. The CLAUDE.md it does have pairs prose rules with their enforcement directly, the way a shared file should: rule 9, "NEVER use an em dash (U+2014) anywhere," is stated once and enforced by a grep command run at every checkpoint (more on that below). Tool-specific routing lives separately, in .claude/agents/ (the setup behind this site's own build): six subagent definitions, each with its own frontmatter (name, tools, model) and a scoped brief, a mechanism Cursor's .mdc frontmatter and Cline's rules panel have no equivalent for.

A shared file that stays an index, not a copy of everything, holds up better across a team of tools with different context limits. Sample skeleton, redacted of anything project-specific:

## AGENTS.md (sample, redacted)

## Project
- Stack: <framework>, <CMS or database>, <hosting>
- Working agreement: plan against `docs/` before writing code; PR-sized changes only

## Hard rules
1. No `any` in TypeScript. No secrets committed. No invented numbers in shipped content.
2. Every change passes the checklist in `docs/definition-of-done.md` before merge.

## Where the rest lives
- `docs/architecture.md`, `docs/conventions.md`, `docs/security.md`

Getting every tool to read that one file takes either a symlink or a documented setting, not a copy-paste:

## Claude Code: read AGENTS.md as CLAUDE.md
ln -s AGENTS.md CLAUDE.md

## Or keep CLAUDE.md and import AGENTS.md as its first line
echo '@AGENTS.md' > CLAUDE.md

## Gemini CLI: point context.fileName at AGENTS.md, in .gemini/settings.json
{"context": {"fileName": ["AGENTS.md", "GEMINI.md"]}}

Cursor, Cline and GitHub Copilot need none of that; they read AGENTS.md on their own once it exists at the project root.

How Do Written Rules Turn Into Enforced Rules?

Written rules turn into enforced rules only when each one is paired with a check outside the file: a review guideline for what a human has to judge, and a CI-style gate for what a script can verify on every change. The file alone cannot do it. Claude Code's own docs say CLAUDE.md content is delivered as a user message after the system prompt, "not as part of the system prompt itself," so there is "no guarantee of strict compliance, especially for vague or conflicting instructions." I treat the other tools the same way until their docs say otherwise.

This repository's own hard rule against em dashes is the clearest first-party example I have of pairing the two: the rule is one sentence in CLAUDE.md, and its enforcement is a grep run at each draft check:

grep -cP '\x{2014}' "$F"     # must be 0, the no-em-dash rule
grep -nE '^# ' "$F"          # must be empty, no H1 typed into the body
python3 - "$F" <<'EOF'       # length checks on title/metaTitle/metaDescription/excerpt
...
EOF

The prose rule and its enforcement live in two different places on purpose, and only the second one is unbypassable. A different one of my repositories, a local SEO audit tool, shows the same pattern for structural invariants instead of style: its own AGENTS.md states "a failed or skipped check never zeroes a score" and "there are no anon RLS policies on audit tables," then names the exact files, types.ts and scoring.ts, that hold those contracts. A rule like that cannot live in prose alone. It needs a type check, a linter or a migration behind it, and the file points at where that check belongs.

How Do You Know the Rules Are Actually Being Followed?

Not by trusting the document. The way I know is a gate that blocks publishing until specific checks have run and passed, and reports rather than silently skips a check that couldn't run at all. This site's own publishing workflow states the model plainly: "an article is not pushed... until every item below has been run and passes. A check that cannot run... blocks the step and is reported; it is never skipped silently and never reported as passed."

That discipline, a check that works because something runs it, not because a document says so, is the same one that caught a green deploy that still shipped a stale page on this site: the build, migration and health check all passed, and the site served old content anyway, because nothing checked what the page actually said. A rules file has the identical failure mode. It can state a rule perfectly and still not catch the session where a tool ignored it, unless something downstream checks the output.

Knowing which tool reads which file in the first place is the other half of verifying this. Based only on each tool's own documentation:

  • Claude Code reads AGENTS.md only if no CLAUDE.md exists on the path; it prefers CLAUDE.md.
  • Cursor reads AGENTS.md at the root or in subdirectories; it also applies .cursor/rules/*.mdc, scoped by frontmatter.
  • Cline auto-detects AGENTS.md; workspace .clinerules/ override on conflict.
  • Gemini CLI reads it only if context.fileName includes it; otherwise it reads GEMINI.md.
  • GitHub Copilot reads the nearest AGENTS.md in the tree; its own .github/copilot-instructions.md combines with path-specific .instructions.md files.

What Can't an AGENTS.md File Enforce?

A rules file cannot stop a tool from writing plausible, rule-following, wrong code. A line like "handle errors explicitly" is still met, to the letter, by a try/catch that logs and swallows the error. The file cannot tell the difference. A reviewer or a test can.

It also cannot make five different tools apply the same written rule with the same judgment. A vague instruction like "keep functions small" gets interpreted differently by whichever model is reading it that session, and the file has no way to arbitrate between them. Only a linter with an actual threshold, or a reviewer with actual taste, resolves that.

And it cannot protect itself from being overwritten. The pattern in the second repository above, a framework tool silently re-writing AGENTS.md on every dev-server start, is proof that a file sitting in a repository is a file any process with write access can touch. Nothing about the AGENTS.md format changes that. Only a check that reads the file after every run would notice.

What this article does not claim: precedence rules for these tools are current as of 29 September 2026, when I fetched each tool's docs, not permanent, and every one of them can and will change defaults. Treat the list above as a snapshot, not a spec.

References

AGENTS.md decides what a tool reads. Only a gate decides what ships. If your team runs more than one of these tools, which rule did you move out of the rules file and into CI first?