Skip to content

Agent Instructions ​

Every repo carries its standing agent instructions in a single AGENTS.md at the repo root. There is no second file: no CLAUDE.md, no copy, no symlink.

AGENTS.md is the agent-agnostic instructions standard, read natively by Codex CLI, Claude Code, and a growing list of others. It's the home for everything you'd otherwise repeat by hand: linting, PR process, addressing review comments, file-editing discipline, worktree rules.

Delete CLAUDE.md: it suppresses AGENTS.md ​

This is the part that surprises people. A CLAUDE.md in the repo does not supplement AGENTS.md; under Claude Code's default it replaces it.

The default mode is claude-md-or-agents-md: Claude Code looks for a CLAUDE.md-family file, and only if it finds none does it read AGENTS.md. The suppressing set is exactly:

CLAUDE.md   .claude/CLAUDE.md   CLAUDE.local.md

and the search walks every ancestor directory, not just the repo root. So a repo carrying both files gets its AGENTS.md skipped entirely.

This is why the old "one-line CLAUDE.md pointer at AGENTS.md" pattern is now actively worse than nothing. It worked by instructing the model to go read a file, a soft prompt competing with everything else in context, which the model could skim or skip. Deleting CLAUDE.md replaces that with the harness actually loading AGENTS.md itself. Strictly more reliable, and one less file to drift.

Requires Claude Code v2.1.281 or later. Native AGENTS.md support landed in v2.1.277, but until v2.1.281 sessions on Amazon Bedrock, Vertex, or Foundry, and sessions with telemetry disabled, still read CLAUDE.md only. If any of those apply, v2.1.281 is the real floor.

The CLAUDE.local.md trap ​

CLAUDE.local.md is personal and usually gitignored, so it's invisible in the repo, but it counts, and it counts from any ancestor directory. One left over in a parent folder silently disables AGENTS.md loading for you and nobody else, with no error and no warning.

Symptom: your AGENTS.md rules quietly stop applying while working fine for everyone else on the team. When that happens, look for a stray CLAUDE.local.md above your checkout before suspecting anything in the repo.

Confirming AGENTS.md actually loaded ​

Don't infer it from the files on disk. Ask a question that only AGENTS.md can answer, with every file-reading tool disabled so the answer cannot come from a tool call:

sh
env -u CLAUDECODE -u CLAUDE_CODE_CHILD_SESSION -u CLAUDE_CODE_ENTRYPOINT \
    -u CLAUDE_CODE_SESSION_ID \
  claude -p "<question answerable only from AGENTS.md>" \
  --strict-mcp-config \
  --disallowed-tools "Read" "Bash" "Grep" "Glob" "Task" "WebFetch" < /dev/null

Every detail here exists because leaving it out produced a wrong answer:

  • < /dev/null. Without it claude -p blocks on inherited stdin, times out, and answers with no project instructions loaded. You get a confident NONE that looks exactly like a genuine failure to load.
  • Stripping CLAUDE_* variables. A claude launched from inside another Claude Code session inherits them and can answer from the parent session's context instead of the project under test. That is a false positive, which is the more dangerous direction.
  • --strict-mcp-config. --disallowed-tools names built-in tools only. A configured MCP server with a file-reading tool is still available, so the model can read AGENTS.md through it and look like it was loaded. Passing --strict-mcp-config with no --mcp-config loads no MCP servers at all.
  • A probe string unique to AGENTS.md. Grep first. If the phrase also appears in a skill file or README, a correct answer proves nothing.

Run it twice before believing a NONE. The check is not perfectly deterministic: an occasional run returns NONE in a repo where the previous and next runs both answer correctly. A single NONE is a reason to re-run, not a diagnosis.

What a correct answer proves is narrow but sufficient: the content reached the model without a tool call in that session. It does not prove which file on disk supplied it, so keep the probe string unique and the tool surface closed.

User-global ~/.claude/CLAUDE.md is a different file, so keep it ​

~/.claude/CLAUDE.md holds your machine-wide, cross-repo instructions and has no AGENTS.md counterpart. There is no ~/.claude/AGENTS.md and no ~/.agents/AGENTS.md.

It is also not part of the suppression rule: Claude Code only counts project- and local-scope files when deciding whether to skip AGENTS.md. Your user-global CLAUDE.md always loads in addition to a repo's AGENTS.md.

So when clearing CLAUDE.md out of a repo, sort every hit into one of two groups before changing anything.

Delete these. Every suppressing file inside the repo, not just the one at the root:

CLAUDE.md   .claude/CLAUDE.md   CLAUDE.local.md

Keep these. Anything under ~/.claude/, which is the user-global file described above.

Then check above the repo too. Because the search walks ancestors, a CLAUDE.md or CLAUDE.local.md in a parent directory suppresses AGENTS.md just as effectively as one in the repo, and a clean repo will still fail to load. Those live outside version control, so no repo-level cleanup can reach them:

sh
d=$PWD
while [ "$d" != "/" ]; do
  for f in CLAUDE.md .claude/CLAUDE.md CLAUDE.local.md; do
    [ -e "$d/$f" ] && echo "suppressing: $d/$f"
  done
  d=$(dirname "$d")
done

A container-style checkout makes this easy to hit: one stray CLAUDE.local.md in the directory holding all your worktrees silently disables AGENTS.md in every one of them.

Now that AGENTS.md is read natively there's no reason to want this, but the hazard is worth recording because it also applies to any other symlinked instructions file.

Symlinks are not reliably resolved in GitHub Actions. When a workflow checks out the repo, the link can be read as its literal contents (a relative path string) instead of the target file. That throws an error and halts the entire run. A single real AGENTS.md works everywhere: locally, in CI, and across every agent.

Organizing AGENTS.md ​

Structure the instructions as a sequential workflow: the order an agent works through any task. A reader skimming top to bottom encounters rules in the order they need them.

A natural sequence:

  1. Understanding the repo. The facts to know, read, and check before starting: what the project is, where things live, how it builds and deploys.
  2. Working with GitHub issues. Find, read, and understand the issue that defines the task. This precedes implementation work. See the github skill.
  3. Setting up the environment. Before any code changes, get the workspace right: worktrees, branches, dependency installs.
  4. Edits and coding standards. File-editing discipline, code style, and comment conventions.
  5. PR and review workflow. GitHub Markdown, opening the PR, and addressing review comments. Fix all true-positive code style violations before opening the PR for review, then again after every change during the review process.
  6. Verification and cleanup. Verify the merge succeeded and that downstream processes like GitHub Pages ran successfully. Then tear down the worktree and branch.

Sourcing the content ​

Don't write AGENTS.md from imagination. A rule that was actually needed is worth encoding; a rule imagined as a might-need is noise. Source rules from real friction in the repo's history:

  1. Chat session history. The most direct signal: the times the human corrected you and said "no, do it this way." Past session transcripts are the richest single source of real corrections.
  2. Issues. Especially ones whose titles describe a convention or a class of mistake (formatting, broken links, CI, PR process).
  3. PR review comments. (Most important source.) A comment left on a PR is a correction that will recur. Recurring review nits are prime AGENTS.md material.
  4. CI config. What the pipeline already enforces (or fails to enforce) tells you which rules are load-bearing and where the manual-verification gaps are.

Rank by recurrence: a rule corrected five times belongs at the top. The highest-confidence signal is double-corroboration: a rule that appears in both session history and the issue/PR record. That is exactly how this repo's AGENTS.md content was assembled.

Prose rules vs enforceable checks ​

Sort every candidate by whether it can be automated:

  • Scriptable as a hard rule (broken links, backticks, line length, build is green): the real home is a CI check or lint script. AGENTS.md should point at the check, not just assert the rule. A check that runs beats a paragraph you skim.
  • Requires interpretation and judgment (comments say why not what, don't escalate destructive operations, reply to every reviewer): AGENTS.md prose, because you can't lint intent.

Anything computable as a hard rule should be scripted. Checks that require interpretation and judgment require an agent.

When a prose rule keeps getting violated, the fix is to make it runnable: either as an automated script or as an unavoidable agent check. Prose alone is weak enforcement: in this repo, "no broken links" lived in writing guidance for a long time and the site still broke repeatedly, because nothing ran the check.

Setup in a new repo ​

  1. Create AGENTS.md at the repo root. Structure it as the sequential workflow described above, with rules sourced from real friction in the repo's history.
  2. Do not create a CLAUDE.md. If one already exists, delete it: while it is present, AGENTS.md is never read.
  3. Commit AGENTS.md.