Skip to content
← Back to all posts One directory. Two agents. Two different rulebooks. ~/ home-directory file workspace/ · git root · 14,864 B engagements/ · 15,855 B project/ · nested .git · 17,770 B ← both agents launched here walks up, no git boundary Claude Code loads 55,986 bytes every parent directory, imports expanded Codex loads 24,150 bytes nested git root down · 32 KiB cap never fired 30,058 bytes unread by Codex 54% of the rulebook · no warning, no error Byte counts measured on one workspace, 2026-09-14. Directory names are generic; the numbers are unmodified.

CLAUDE.md and AGENTS.md: One Rulebook All Three Agents Read

There is one piece of advice about CLAUDE.md and AGENTS.md that every guide gives, and it is good advice: keep one canonical file, and make the others thin shims that import it. Anthropic's own documentation says exactly this — “Claude Code reads CLAUDE.md, not AGENTS.md. If your repository already uses AGENTS.md for other coding agents, create a CLAUDE.md that imports it.” I follow it. My root CLAUDE.md is three lines long and the first one is an import.

It solved the wrong half of the problem. Reconciling the filenames is the easy half, and it is the half everybody writes about. The half nobody writes about is that the three tools do not agree on which directories to collect those files from. Fix the names and you still get two agents, launched in the same folder, holding materially different rulebooks — and the one holding less has no idea.

I only found this because I measured it. Here is what came back.

Quick answer: from a single working directory three levels deep in my workspace, Claude Code loaded 55,986 bytes of instructions and Codex loaded 24,150. The missing 30,058 bytes — 54% of the rulebook — were not trimmed for length and triggered no warning. They sat above a nested repository's own Git root, and Codex starts its search at the Git root. The famous 32 KiB cap had nothing to do with it: the Codex chain finished with 8,618 bytes to spare. Length was never the failure mode. Repository topology was.

The Three Loaders Disagree About Where “The Project” Starts

Every one of these rules is documented, none of them is a secret, and I had read all three before I built the layout that broke. They only become a problem when you put them side by side, which is not something any single vendor's documentation does for you.

ToolReadsWhich directories it collects fromSize behaviour
Claude Code CLAUDE.md, CLAUDE.local.md “your current working directory and every directory above it.” No Git boundary appears in the rule. Subdirectory files load on demand when it reads files there Loads a file up to 4 MiB in full, skips larger. Advises under 200 lines for adherence
Codex AGENTS.override.md, then AGENTS.md, then your configured fallbacks “Starting from the Git root down to your current directory.” A nested .git becomes the ceiling “stops adding files once the combined size reaches the limit defined by project_doc_max_bytes (32 KiB by default)”
Gemini CLI GEMINI.md by default; context.fileName accepts another name or a list, including AGENTS.md Home-directory file, then configured workspace directories, then “that directory and its ancestors up to a trusted root” No published byte cap; concatenates general to specific, deepest last

Read the middle column again. Claude Code walks up and does not stop at a repository edge. Codex walks down from the repository edge and cannot see past it. Those two rules point in opposite directions from the same starting point, and in a flat single-repo project they happen to agree, which is why almost nobody notices. Put one .git inside another and they stop agreeing completely.

The Measurement: 55,986 Against 24,150

My workspace is a root repository with nine sibling repositories inside it, one per area of work, and one of those has a repository of its own nested a level deeper. That structure exists for reasons that have nothing to do with agents — separate histories, separate commit granularity. It is also an ordinary shape. Any monorepo with vendored submodules has it.

I launched from the deepest directory and counted what each tool's documented rule would collect. Directory names are genericised here; byte counts are untouched.

CLAUDE CODE — cwd upward, across git boundaries, imports expanded ~/.claude/CLAUDE.md 7,497 workspace/CLAUDE.md + import 176 + 14,688 workspace/engagements/CLAUDE.md + import 485 + 15,370 workspace/engagements/project/CLAUDE.md 280 + 17,490 ------------------------------------------------- TOTAL 55,986 bytes (743 lines) CODEX — git root downward, no imports ~/.codex/AGENTS.md 6,660 workspace/engagements/project/AGENTS.md 17,490 ------------------------------------------------- TOTAL 24,150 bytes (316 lines) cap 32,768 — headroom remaining: 8,618 UNREAD BY CODEX 30,058 bytes

The 30,058 bytes are the workspace root rulebook and the tier above the nested repository: the failure-registry triggers, the naming rules, the single-committer Git convention, the instruction never to claim something is done without the artifact that proves it. All of it in force for Claude Code. None of it reaching Codex, from the same folder, on the same machine, in the same minute.

Why the 32 KiB Cap Is the Wrong Thing to Worry About

The cap is real, and it is the single most-cited number in this corner of the internet. OpenAI's documentation states it plainly: Codex “concatenates files from the root down” and “stops adding files once the combined size reaches the limit defined by project_doc_max_bytes (32 KiB by default)”. There is an open issue on the Codex repository reporting that when it fires there is no warning in the terminal UI, no log line and nothing in the editor extension. I checked my own config.toml while writing this: project_doc_max_bytes is unset, so the 32,768-byte default is what I am running.

And it was irrelevant to my failure. The Codex chain came in at 24,150 bytes with a quarter of the budget unspent. Every word I wrote was inside the cap. The cap is a length control, and I did not have a length problem — I had a reachability problem, which is the failure the cap is not designed to catch and the guides do not mention.

The distinction matters because the two have opposite fixes. A length problem is fixed by trimming, and trimming is what every article about these files tells you to do. A reachability problem gets worse when you trim, because you are shortening files the agent was already reading while the ones it cannot see stay exactly as invisible as before. I spent a session trimming before I thought to measure, and it bought me nothing.

The five-second check, before you rewrite anything. If one agent follows a rule and another ignores it, run git rev-parse --show-toplevel from the directory you launch the agent in. If that path is below the file holding the rule, a Git-root-anchored tool was never going to read it, and no amount of rewording will change that.

The Import Trick Covers Two Tools Out of Three

The standard fix — one canonical file, shims that import it — works beautifully where it works. Claude Code's import syntax resolves relative to the importing file and recurses to a maximum depth of four hops. Gemini CLI supports the same idea. Both can be pointed at a single AGENTS.md, and mine are: my CLAUDE.md files in two pillars are eleven bytes each — one import line and a newline, nothing else.

Codex is the one that cannot play. I read its instruction-file documentation end to end looking for an include directive, because I assumed I had missed it. It documents discovery order, precedence, AGENTS.override.md for temporary global overrides, and configurable project_doc_fallback_filenames — and no import or include syntax of any kind. A Codex instruction file has to physically contain its own text.

So a three-tool setup has exactly two honest shapes, and you have to pick one:

ShapeHow it worksWhat it costs
Canonical AGENTS.md
(use this inside a repo)
AGENTS.md holds every shared rule. CLAUDE.md is one import line plus any Claude-only additions. Gemini CLI either imports it or has AGENTS.md added to context.fileName Nothing, inside one repository. Breaks the moment a rule needs to live above a nested Git root
Mirrored portable block
(use this for home-directory files)
The shared rules live between two marker comments and are copied byte-for-byte into each tool's home file. Tool-specific content goes outside the markers It is a copy, so it will drift. Non-negotiable: a scripted diff that fails loudly

The home-directory files are the case where the import genuinely cannot save you, because there is no shared repository to be canonical in. Mine use the mirror, and the drift check is one command:

diff <(sed -n '/PORTABLE-START/,/PORTABLE-END/p' ~/.claude/CLAUDE.md) \ <(sed -n '/PORTABLE-START/,/PORTABLE-END/p' ~/.codex/AGENTS.md)

I ran it against both mirrors while writing this page and both returned clean: a 4,886-byte, 720-word, 60-line block, byte-identical across all three home files. The wrapper files around it differ — 7,497, 6,660 and 6,675 bytes — because each carries the mechanics only its own tool has. That difference is the point. The block that must be identical is identical and is proven identical on demand; the parts that should differ are free to.

A symlink is the third option and Anthropic documents it, with the caveat that it needs Administrator privileges or Developer Mode on Windows and that the import is the better choice there. It also leaves you nowhere to put tool-specific content, which is usually why the shim exists.

The Layout That Survives All Three

Four rules. The first is the one I did not have, and it is the only one that addresses the failure above.

1. Every nested repository opens its instruction file with an inheritance block. A tool that starts at the Git root cannot walk up to the parent rulebook, but it can be told to open it. Name the parent files by relative path, in the first section, before anything else. Tools that already walked up lose nothing; tools that start at the Git root gain the thing they were structurally missing. This converts a silent omission into one explicit instruction, and it is the cheapest fix in this entire article.

## Governance inheritance — read first This folder is its own git repo. Some agents load parent folders automatically; others start at the nearest git root and will not. Open these yourself before reading on: 1. `../AGENTS.md` — the shared rulebook 2. `../PITFALLS.md` — the failure registry

2. Budget the chain, not the file. The 32 KiB cap applies to root-to-working-directory concatenation, so the number to watch is the sum along the deepest path, not the size of any one file. Keep each chain under roughly 24 KB and the strictest tool never gets to decide what you meant. This is also where Claude Code's under-200-lines advice belongs — as a target for adherence, well below anyone's hard limit.

3. A pointer file holds no rules. If CLAUDE.md is a shim, it must be a shim: an import and, at most, a sentence saying where the rules actually are. The moment a real rule gets added to the pointer “just this once,” you have two sources of truth and one of them is invisible to two thirds of your tools. Mine says so in its own text, which is a note to the next person as much as to the agent.

4. Conditional content leaves the always-loaded file. Everything above is about reach — making sure the right files are seen. The separate question is what belongs in them at all, and the answer is: only what is true for every task. Anything that applies under a stated condition should sit in its own file behind a trigger, which costs a line of budget instead of a section. Claude Code now has a first-class mechanism for this in path-scoped rules under .claude/rules/, which load only when it touches matching files. For the portable version — and for the specific case of corrections you have had to give an agent twice — I wrote that up separately in Your AGENTS.md Gets Worse Every Time You Fix It, which is the companion to this page: that one is about what goes in the file, this one is about which files get read.

Running more than one agent in the same repo?

I run a free community for people building real data and AI pipelines — warehouse modeling, analytics, and AI-augmented workflows. No course, no paywall, just practitioners shipping.

Join the free AI community →

Frequently Asked Questions

What is the difference between CLAUDE.md and AGENTS.md?
Same idea, different filenames, different readers. AGENTS.md is the vendor-neutral format, and its spec lists roughly twenty-five tools that read it — Codex, Cursor, Aider, Devin, Copilot, VS Code and others. CLAUDE.md is what Claude Code reads; GEMINI.md is Gemini CLI's default. Claude Code's docs are explicit that it reads CLAUDE.md and not AGENTS.md, and the AGENTS.md spec never mentions CLAUDE.md. The difference that actually bites is not the name: each tool applies a different rule for which directories it collects files from, so two agents in the same folder can hold different rulebooks even after you reconcile the filenames.
Can I use one file for all three agents instead of three?
Partly. Claude Code and Gemini CLI both support an import directive, so a one-line CLAUDE.md delegates to a single canonical file. Codex has no equivalent — its documentation covers discovery, precedence, override files and fallback filenames, and documents no import syntax at all, so a Codex file must physically contain its text. That leaves two shapes: make AGENTS.md canonical and have the other two import it, or mirror a portable block byte-for-byte into each tool's home file. One of the three ends up a copy either way, and a copy without an automated diff will drift.
Why does Codex ignore rules that Claude Code follows?
Usually because the rule lives above the nearest Git root. Codex collects from the Git root down to your working directory; Claude Code walks from the working directory up through every parent, with no Git boundary in the documented rule. In nested repositories those select different files. Measured here from one directory: Claude Code 55,986 bytes, Codex 24,150 — a 30,058-byte difference that was never trimmed and produced no warning, because it sat above a nested repository's Git root. Check repository boundaries before you rewrite the rule.
How big can an AGENTS.md file be?
Each tool answers differently. Codex stops adding files once the combined chain hits project_doc_max_bytes, 32 KiB by default and raisable in config.toml — note that the cap is on the combined chain, not one file, and an open issue reports it fires with no warning anywhere. Claude Code loads a CLAUDE.md up to 4 MiB in full, skips larger, and advises under 200 lines for adherence rather than capacity. Practically: size for the advice, not the cap, and keep any single root-to-working-directory chain well under 32 KiB.
Where should AGENTS.md live in a monorepo or nested repositories?
One at each level where the rules genuinely differ — the spec's guidance is to put another AGENTS.md inside each package. The trap is that nested repositories are not nested folders: a subdirectory containing its own .git becomes a Git root, and for any tool that starts its search there, everything above stops being visible. Open each nested repository's file with a short block naming the parent files by path and telling the agent to open them directly. It costs one section and converts a silent omission into an explicit instruction.
Is a symlink better than an import for keeping the files in sync?
Cleaner where it works, and it does not work everywhere. Anthropic documents a symlink from CLAUDE.md to AGENTS.md as an alternative, with the caveat that Windows needs Administrator privileges or Developer Mode and that the import is the better choice there. A symlink also leaves nowhere to put tool-specific content, which is usually why the shim exists. Symlink when the file is genuinely identical for every tool and you are not on Windows; import when it is not.

Related reading: Your AGENTS.md Gets Worse Every Time You Fix It — the companion to this page: what belongs inside the file, once you know which files get read. I Ran Claude Code and Codex Head-to-Head — the two tools above, working the same spec in the same repo, blind-judged. Multi-Model Verification — the same don't-trust-one-pass discipline applied to output instead of instructions. AI as an Operations Layer — where these agents actually run. For the hardware they run on, see Blendlogic Tech.

What would make this wrong

  • The byte counts are what the documented rules select, not a packet capture. I counted the files each tool's published discovery rule would collect from that directory and summed them. I did not instrument the agents and read back what actually entered the context window. If a loader deviates from its own documentation — skips a file, deduplicates, applies an exclusion I did not account for — my totals are off. The 30,058-byte gap follows from two documented rules pointing in opposite directions, which I am confident about; the precise figure assumes both implementations match their docs.
  • n=1, and it is my own layout. One workspace, ten repositories, designed by the person now writing about how it failed. The nested-repository shape is common enough that I think the finding generalises, but I have not reproduced it on anyone else's tree, and a flat single-repo project will never see it at all.
  • Claude Code's rule is a documented absence, not a documented presence. Its docs say “your current working directory and every directory above it” and simply never mention Git boundaries. I am reading silence as “no boundary,” which matches the behaviour I see, but a stated rule would be better evidence than an unstated one.
  • This is a moving target, and the docs moved while I wrote. Two of the three documentation URLs I fetched had been redirected to new homes since I last read them. Every quote here was pulled on 2026-09-14; the project_doc_max_bytes default, the import depth and the fallback mechanism are all implementation details that can change in a point release, and the Codex truncation issue is open rather than resolved.
  • My own chain is four times past the advice I am repeating. Claude Code recommends under 200 lines per file; the chain it loads for me is 743 lines across seven files. The reach problem and the length problem are genuinely separate, which is this article's argument — but having fixed the first, I still have the second, and I would rather print that than imply the layout is finished.
  • Harness features may absorb all of this. Path-scoped rules already do a better job than a hand-built trigger for the conditional-content case. If discovery converges — every tool reading a shared filename with a shared traversal rule — the inheritance block becomes a workaround for a gap that closed. The durable part is the four-rule layout; the part most likely to be obsoleted is the mirroring.