Skip to content

Shared agent rules — one core, tested adapters

Shared agent rules are one versioned instruction core (a root AGENTS.md), the thinnest per-tool adapter that makes Claude Code, Codex and Cursor load it, and a test proving each tool did. Rules steer the model; anything that must never happen belongs in permissions, sandboxes, CI and branch protection.

Your repository has a 400-line CLAUDE.md written in March, an AGENTS.md that the Codex users added in July, and a Cursor rule that still says npm test after the move to pnpm. Three agents read three versions of the truth, and nobody can say which one a given session loaded. This page is for the tech lead who owns the shared harness and the CTO answering question 5 of the CTO Scorecard.

What a tested shared-rules setup gives you

Section titled “What a tested shared-rules setup gives you”
  • A file layout and an AGENTS.md core template you can commit today.
  • The adapter each tool needs, based on how it discovers instruction files (checked 2026-09-26 against Claude Code 2.1.283 and Codex 0.157.1).
  • A written precedence table that settles conflicts by rule, not by load order.
  • A deterministic CI check and a fresh-session probe that prove each agent loaded the rules, so nobody has to read transcripts.
  • The failure modes that make an agent silently ignore the rules, and how to recover from each.

How does the CTO Scorecard grade shared rules?

Section titled “How does the CTO Scorecard grade shared rules?”

Question 5 asks: “Does the team share agent rules (CLAUDE.md / AGENTS.md / managed policy)?” Use the table to place the team honestly, then close the gap to the next row.

PointsAnswerEvidence a reviewer asks for
0Everyone authors their own, no sharingnone
1A “recommended” CLAUDE.md in the READMEa copy-paste snippet, no enforcement
2Per-repo CLAUDE.md/AGENTS.md committed to mainthe file exists; nobody knows whether every tool loads it
3Versioned shared core plus tested tool adapters, owners, precedence, change review and external enforcement for hard requirementsCODEOWNERS entry, the CI check below, probe results per tool, a list mapping each hard rule to its control

The jump from 2 to 3 is almost entirely verification. The file is the easy part.

Each layer has one job. When a sentence could live in two layers, it belongs in the lower one.

LayerHoldsLives in
Shared corerepository map, commands, definition of done, protected paths, human gates, ownersroot AGENTS.md
Directory scoperules for one package, service, language or risk areaservices/billing/AGENTS.md and similar
Tool adapterdiscovery glue and genuinely tool-specific behaviour, nothing elseCLAUDE.md, a Cursor project rule
External enforcementwhat must hold even when the model ignores every file abovesandbox, permission rules, CI, branch protection, deploy approval

The core goes in AGENTS.md because it is the format the tools converge on: an open format stewarded by the Agentic AI Foundation under the Linux Foundation, which its site describes as “used by over 60k open-source projects” (agents.md, September 2026). How to write the content itself (what to include, and what to leave out) is covered in AGENTS.md and CLAUDE.md: concise repository context.

A layout that works for a monorepo:

AGENTS.md # shared core, target under 200 lines
CLAUDE.md # adapter: "@AGENTS.md" + Claude-only lines
services/billing/AGENTS.md # directory scope
services/billing/CLAUDE.md # adapter: "@AGENTS.md"
.claude/rules/ # optional Claude path-scoped rules (paths: frontmatter)
.github/CODEOWNERS # rule files owned by the harness owner
scripts/check-agent-rules.sh # deterministic CI check (below)
tests/agent-rules/probe.sh # fresh-session probe (below)

The shared core template, ready to adapt:

AGENTS.md
Rules version: 2026-09-26.1
## Commands
- Install: `pnpm install --frozen-lockfile`
- Unit tests: `pnpm test`
- Types and lint: `pnpm typecheck && pnpm lint`
## Definition of done
- Tests, types and lint pass locally before you open a pull request.
- New behaviour has a test that fails without the change.
## Protected paths (ask a human first)
- `services/billing/migrations/`
- `infra/` and anything that changes production access
## Human gates
- Merging to `main` and deploying are human decisions. Never push to `main`.
## Precedence
- A directory `AGENTS.md` may add constraints. It may not relax a rule in this file.
- If two rules conflict, stop and ask; do not pick one.
## Owners
- This file: @acme/agent-platform. Change it through a pull request.

The Rules version: line is a canary: every test on this page checks that an agent can quote it.

How each agent discovers instruction files

Section titled “How each agent discovers instruction files”

Discovery is where shared rules fail, and it differs per tool, so the adapters differ too.

Checked against the memory documentation and Claude Code 2.1.283 on 2026-09-26.

  • Launch: Claude Code loads CLAUDE.md, .claude/CLAUDE.md and CLAUDE.local.md from the working directory and every directory above it. Files in subdirectories load when Claude reads files there. Everything is concatenated, root first; nothing overrides anything.
  • AGENTS.md: read directly from v2.1.277 (v2.1.281 on Bedrock, Google Cloud, Foundry, gateways and telemetry-off sessions), and by default only when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working directory or above. On 2026-09-26 that is the latest channel only; the stable channel is 2.1.274 and reads CLAUDE.md files only.
  • Also read, by Claude Code only: .claude/AGENTS.md in the working directory and above. Codex ignores it, so it is another way for the two tools to diverge; the CI check below fails on it.
  • Not read: AGENTS.override.md, AGENTS.local.md, and anything under .agents/.
  • Adapter: a CLAUDE.md next to each AGENTS.md whose first line is @AGENTS.md. The import works on every version and channel, and a version that also reads AGENTS.md directly never loads it twice.
  • Alternative: in /config, set Project instructions to claude-md-and-agents-md to read CLAUDE.md and AGENTS.md together, deduplicated. It is honoured only in user or managed settings, never in project settings. It also lets a CLAUDE.local.md coexist with AGENTS.md; under the default, a CLAUDE.local.md counts as a CLAUDE.md and suppresses AGENTS.md. Keep the import adapter anyway, because it works on every channel.
@AGENTS.md
## Claude Code only
- Use plan mode for changes under `services/billing/`.
  • Check: run /context and confirm the files appear under Memory files; /memory opens the loaded CLAUDE.md files for editing.

Neither Claude Code nor Codex resolves conflicts for you. Both concatenate files, and Anthropic’s memory page warns that if two rules contradict each other, “Claude may pick one arbitrarily”. So precedence is a rule you write, review and test, not a load order you hope for.

SituationWhat winsHow it is enforced
Directory file contradicts the rootthe stricter rule; a directory may add constraints, never relax themstated in the core; conflict audit in review
AGENTS.override.md existsCodex reads it instead of that directory’s AGENTS.md; Claude Code ignores itnever committed; the CI check fails on it
Personal preferencesCLAUDE.local.md or user-level files, gitignoreda personal file cannot weaken a hard rule, because hard rules are not in files
Organisation-wide rulesmanaged instructions deployed by IT, such as Claude Code’s managed CLAUDE.md, which loads before project filesmanaged policy across every agent
A rule and a control disagreethe control; fix the rule’s wordingthe map from each hard rule to its control, reviewed quarterly

Roll out shared rules without a big-bang rewrite

Section titled “Roll out shared rules without a big-bang rewrite”
  1. Inventory every source. List each AGENTS.md, CLAUDE.md, .claude/rules/ file, Cursor rule and personal default in use, with its scope and owner. The first prompt below does the reading; on the Claude side, /doctor prompt-audit (v2.1.283, latest channel) also flags contradicting CLAUDE.md and AGENTS.md files.
  2. Choose the canonical core. Move durable rules into the root AGENTS.md, keep it under 200 lines (the size Anthropic’s memory page recommends per file), and link to architecture docs instead of pasting them. Use the ablation protocol to decide what earns a line.
  3. Replace copies with adapters. Each CLAUDE.md becomes @AGENTS.md plus Claude-only lines. Delete the duplicated text in the same pull request, so there is never a period with two live copies.
  4. Map hard rules to controls. For every “never” in the core, name the control that enforces it: a permission rule, a sandbox mode, a CI job, branch protection. A rule with no control is advice, and the core should say so.
  5. Add the CI check and the probe. Both are below. The CI check runs on every pull request; the probe runs on rule changes and after tool upgrades.
  6. Assign ownership. Put the rule files under a CODEOWNERS entry, and require every rule change to cite what prompted it: an incident, a review comment, an onboarding failure.

Prove every agent loaded the rules without reading transcripts

Section titled “Prove every agent loaded the rules without reading transcripts”

Verification has two layers. The deterministic layer checks files and needs no model. The probe layer asks each agent what it loaded and compares the answer with the canary.

Layer 1: a CI check on every pull request. It fails when an adapter is missing, when a Codex-only override or a Claude-only .claude/AGENTS.md is committed, or when a directory’s chain exceeds Codex’s default budget. Tested with bash on 2026-09-26.

#!/usr/bin/env bash
# scripts/check-agent-rules.sh: deterministic, no model calls. Run from the repository root.
set -euo pipefail
fail=0
files=$(find . -name 'AGENTS*.md' -not -path './node_modules/*' -not -path './.git/*')
for f in $files; do
d=$(dirname "$f")
case "$f" in
*/AGENTS.override.md) echo "$f: Codex-only override is committed"; fail=1; continue ;;
*/.claude/AGENTS.md) echo "$f: read by Claude Code only; merge it into AGENTS.md"; fail=1; continue ;;
*/AGENTS.md) ;;
*) continue ;;
esac
# Claude Code adapter: a CLAUDE.md next to every AGENTS.md whose first line imports it
if [ "$(head -n 1 "$d/CLAUDE.md" 2>/dev/null)" != "@AGENTS.md" ]; then
echo "$d: needs a CLAUDE.md whose first line is @AGENTS.md"; fail=1
fi
# Codex budget: every AGENTS.md from the root down to this directory
total=0; p="$d"
while :; do
[ -f "$p/AGENTS.md" ] && total=$(( total + $(wc -c < "$p/AGENTS.md") ))
[ "$p" = "." ] && break
p=$(dirname "$p")
done
if [ "$total" -gt 32768 ]; then
echo "$d: AGENTS.md chain is $total bytes, over Codex's 32 KiB default"; fail=1
fi
done
exit "$fail"

Layer 2: a fresh-session probe per tool. Run it when a rule file changes and after every tool upgrade. The canary grep is the pass/fail signal; the other three answers are for the owner to skim.

#!/usr/bin/env bash
# tests/agent-rules/probe.sh: run from the repository root on a trusted checkout
set -euo pipefail
CANARY=$(grep -m1 '^Rules version:' AGENTS.md)
PROBE=$(cat tests/agent-rules/probe-prompt.txt) # the probe prompt above
codex debug prompt-input "noop" | grep -qF "$CANARY" || { echo "Codex: core not in prompt"; exit 1; }
claude -p "$PROBE" --permission-mode plan > claude.out
codex exec --sandbox read-only --ephemeral -o codex.out "$PROBE"
for out in claude.out codex.out; do
grep -qF "$CANARY" "$out" || { echo "$out: canary missing"; exit 1; }
done

Cursor has no line in the script because its CLI was not verifiable on 2026-09-26; paste the same probe into a new Agent chat and record the result in the pull request.

Sign-off. The harness owner in CODEOWNERS approves every rule change. The pull request carries the CI check result, the probe output per tool, and the incident or review comment that motivated the change. A reviewer checks those artefacts, not the full diff of every transcript. Report the same three items when you answer question 5.

Claude Code ignores AGENTS.md. Symptom: the probe returns no canary in Claude Code while Codex passes. Cause: someone has a CLAUDE.md or CLAUDE.local.md in the working directory or above, is on the stable channel (2.1.274 on 2026-09-26), or, in some cases, is in the first session after upgrading from 2.1.276 or earlier. Recovery: add the @AGENTS.md adapter; it works in all three cases.

Codex drops the package rules. Symptom: a rule from services/billing/AGENTS.md is followed when Codex starts in services/billing/ and ignored when it starts at the root. Cause: Codex builds its startup chain only from the root down to the working directory. Recovery: move rules that every session needs into the root core, and tell engineers to start Codex in the package they are changing.

Codex truncates the chain. Symptom: the canary is present but a directory rule is missing from codex debug prompt-input. Cause: the chain passed 32 KiB and Codex truncated it, logging only a warning. Recovery: cut the core, starting with anything the ablation protocol cannot justify. Raise project_doc_max_bytes only after the cut, and only with a written reason.

Codex and Claude Code disagree on one directory. Symptom: behaviour differs by tool in one directory only. Cause: an AGENTS.override.md that Codex reads and Claude Code ignores. Recovery: delete it, move the content into AGENTS.md, and keep the CI check that fails on it.

Codex loads no project rules at all. Symptom: an empty instructions block in codex debug prompt-input on one machine. Cause: that project is marked untrusted there, because someone declined the trust prompt or ~/.codex/config.toml sets trust_level = "untrusted" for it; since 0.150.0 an untrusted project does not supply project-level AGENTS.md. Recovery: set the project to trusted on that machine, and keep the canary check in the onboarding fixture.

The core loads twice. Symptom: context grows and the fresh-session probe (or asking the session to quote its instructions) shows the core twice: once from the SessionStart hook output and once from the loaded file. Cause: a SessionStart hook that prints AGENTS.md still runs after Claude Code learned to read the file. Recovery: remove the hook; the @AGENTS.md import never duplicates.

A rule is treated as a security control. Symptom: an agent reads .env although the core says “never read .env”. Cause: instructions steer the model; they do not bind it. Recovery: enforce with permission rules or a sandbox, reviewed as code in shared hooks governance, and keep the sentence in the core only as an explanation of the control.

Policy by duplication creeps back. Symptom: the inventory prompt finds the same rule in three files. Cause: a migration command or a well-meaning engineer copied text instead of importing it. Both Claude Code and Codex offer /import for another tool’s configuration; run it once during migration, then run the inventory prompt and delete the copies.

Before this page: make the codebase agent-ready and read how teams share context and rules. After it, package procedures that do not belong in always-loaded rules as skills, and move hard requirements into reviewed controls.

Edit page

Last updated: