Nested AGENTS.md for Monorepo: How E Dey Work
One 600-line root AGENTS.md fit stale and waste context. See how nested files share common rules while each service gets only its own commands and conventions.
Wetin nested AGENTS.md mean for monorepo
Nested AGENTS.md for monorepo mean say one small file dey repository root, plus another file inside each service directory. Root file dey contain the few rules wey apply everywhere, together with map of where the other files dey. Each service file dey contain the commands and conventions wey apply only to that directory. Agent wey dey edit services/worker/queue.py go read root file and worker file, and e no go use any context on front end wey e no go touch.
No installation dey needed. AGENTS.md na convention, and upstream project talk am clearly:
AGENTS.md na standard Markdown. You fit use any headings wey you like; agent simply parse the text wey you provide.
Na why e make sense to learn this technique well. The format no go change without warning. Na placement and maintenance dey cause problems, and na your responsibility to handle both.
Why one big root AGENTS.md no dey work?
One 600-line AGENTS.md for the root of repository wey contain web app, background worker, and Terraform directory dey fail for four different ways.
E dey become outdated, because nobody own am. The engineer wey rename test script for apps/web dey edit files under apps/web. Root AGENTS.md no dey inside that diff, so no reviewer go see the mismatch. Six weeks later, the file still dey describe build step wey no longer exist, and the person wey cause the problem don forget the change.
E dey use context for every task. These files dey load when session start, before agent know wetin you wan ask. Claude Code documentation give one number: "target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence." Codex stop merging instruction files once their combined size reach 32 KiB, the default project_doc_max_bytes. Root file wey document four services dey spend that budget on three of dem for every task.
Instructions start to contradict each other. The web directory need pnpm test. The worker need pytest -q. Once dem write everything for one file, each rule correct only some of the time, so agent must guess which one apply. Claude Code docs describe the result: "if two rules contradict each other, Claude may pick one arbitrarily." File for each directory remove the guess, because only one of the two rules dey inside context at any time.
E dey fill with facts wey agent fit read from the code. Directory tree, dependency list, and summary of wetin each package dey do. Claude Code's /doctor check dey there to remove exactly this kind content. E "cuts content Claude can derive from the codebase, such as directory layouts, dependency lists, and architecture overviews" and keeps "pitfalls, rationale, and conventions that differ from tool defaults." That sentence na the best test I know to decide whether one line suppose dey inside the file at all.
Agent dey read root file, or na only the nearest one?
Na here plenty people dey understand the model wrongly, so e better make we quote the upstream convention instead of paraphrase am:
Put another AGENTS.md inside each package. Agents go automatically read the nearest file for the directory tree, so the closest one get precedence and every subproject fit ship instructions wey match am.
And for conflicts:
The AGENTS.md wey dey closest to the edited file go win; explicit user chat prompts override everything.
“Takes precedence” dey make many people think say “root file dey ignored”. E no be so. For tools wey implement this convention, dem dey read every file for the path from repository root down to the working directory, then join everything together. The nearest file go win only when two files talk different things about the same subject.
Codex explain the mechanism clearly: “Codex concatenates files from the root down, joining them with blank lines. Files closer to your current directory override earlier guidance.” Claude Code dey walk the same path for its own file name. Files for directory hierarchy above the working directory “are loaded in full at launch”, and “All discovered files are concatenated into context rather than overriding each other.” Directories below the working directory dey behave differently: Claude Code loads those files when e need dem, “when Claude reads files in those directories.”
Two practical results dey follow. The root file na prefix for every session inside the repository, so treat every line there like line wey you go pay for one hundred times every week. A per-directory file no cost anything when agent dey work for another place, so detail cheap there and na there e suppose dey.
We check this behaviour against Codex and Claude Code documentation for August 2026. Tools dey implement the convention small-small differently, and dem dey change too, so confirm the loading rules for the agent wey your team dey run.
A layout wey work for repository with three services
repo/
AGENTS.md rules true everywhere, plus the map
apps/web/AGENTS.md TypeScript client, Vite, Vitest
services/worker/AGENTS.md Python queue consumer, pytest
infra/AGENTS.md Terraform and the deploy scriptsThe root file dey short on purpose. E tell you where to look, and e carry only the rules wey apply for every directory.
# AGENTS.md
This is a monorepo. Each top-level directory ships its own AGENTS.md.
Read this file and the AGENTS.md nearest the code you are editing
before you change anything.
- `apps/web` browser client
- `services/worker` queue consumer
- `infra` Terraform and deploy scripts
## Rules for the whole repository
- The package manager is `pnpm`. `npm install` writes a second lockfile
that CI ignores, so the install you tested is not the install that ships.
- Any `generated/` directory is build output. Edit the schema in
`schemas/` and run `pnpm codegen` instead.
- `.env.local` holds real credentials. Do not read it and do not print it.
- If you change code in a directory, update that directory's AGENTS.md
in the same commit.The per-directory file na where the details dey, and e fit long as the directory need am.
# apps/web
Browser client. Vite and React, TypeScript with `strict` on.
## Commands
- `pnpm dev` serves on port 5173.
- `pnpm test` runs Vitest once and exits.
- `pnpm typecheck` runs `tsc --noEmit`.
## Conventions
- One component per file under `src/components/`.
- All HTTP goes through `src/api/client.ts`. Do not call `fetch` directly,
because the client attaches the auth header and retries on 429.
## Traps
- `pnpm build` does not type check. Vite strips the types instead of
checking them, so a broken type still produces a green build.
Run `pnpm typecheck` as a separate step.The worker file get the same shape but different content: the install command, pytest -q, why the consumer must stay idempotent, and the migration wey must run before the tests pass. The infra file na where you write the rules wey stop an agent from causing damage. Never run terraform apply. Run terraform plan and stop there, then name the state backend wey don already configure so the agent no try initialise another one.
Notice wetin no dey inside any of these files: explanation of wetin each service dey do. Na the humans suppose get that one. Upstream draw the same boundary, e say "README.md files dey for humans: quick starts, project descriptions, and contribution guidelines", while AGENTS.md carry "the extra, sometimes detailed context coding agents need: build steps, tests, and conventions." The difference between AGENTS.md and README for humans explain that boundary sentence by sentence, and a DESIGN.md wey record why dem shape the code that way cover the third file, the one wey explain decisions instead of commands.
Who dey update the file when code change?
Put one rule for the root file: anybody wey change code for one directory must update that directory AGENTS.md for the same commit.
This one work because of how the files dey relate, not because of team culture. The file for each directory dey inside the same diff with the code, so the person wey review the pull request go see both together. Root file belong to everybody, and because of that e belong to nobody. E no dey inside the diff wey anybody already dey read.
Support the rule with check for the pull request. The check go find the nearest AGENTS.md above each changed file, then report when dem no touch that file.
#!/usr/bin/env bash
# Warn when code changed but the nearest AGENTS.md above it did not.
changed=$(git diff --name-only origin/main...HEAD)
nearest_doc() {
d=$(dirname "$1")
while [ "$d" != "." ]; do
if [ -f "$d/AGENTS.md" ]; then echo "$d/AGENTS.md"; return; fi
d=$(dirname "$d")
done
echo "AGENTS.md"
}
printf '%s\n' "$changed" | while read -r f; do
[ -n "$f" ] || continue
case "$f" in AGENTS.md|*/AGENTS.md) continue ;; esac
doc=$(nearest_doc "$f")
printf '%s\n' "$changed" | grep -Fqx "$doc" && continue
echo "note: $f changed but $doc was not updated"
doneFor branch wey change the API client but no touch the docs, the output go look like this:
note: apps/web/src/api/client.ts changed but apps/web/AGENTS.md was not updatedMake am warning, no make am failure. Hard gate go teach people to add empty line to the file just to make CI green. File wey person edit only to satisfy robot get less value than no file at all. The warning give reviewer one question to ask, and na that part actually dey work.
AGENTS.md wey don stale, how I fit notice am?
Checks two dey wey you fit run today, plus one symptom wey you go see inside session.
Compare the age of each file with the age of the code wey e dey describe. %cs dey print the commit date as YYYY-MM-DD.
for f in $(git ls-files '*AGENTS.md'); do
d=$(dirname "$f")
printf '%s doc:%s code:%s\n' "$f" \
"$(git log -1 --format=%cs -- "$f")" \
"$(git log -1 --format=%cs -- "$d")"
doneapps/web/AGENTS.md doc:2026-02-11 code:2026-08-07
services/worker/AGENTS.md doc:2026-07-29 code:2026-08-09
infra/AGENTS.md doc:2026-08-01 code:2026-08-01If doc date dey six months behind code date, e no prove say the file wrong. E just tell you which file to read first. Na all you need from check wey dey take one second.
Look for paths wey no dey exist again. Documentation dey rot for one clear way: e continue to describe code wey dem don delete. Dem write every path for these files inside backticks, so e easy to pull dem out and test dem.
grep -o '`[^`]*`' apps/web/AGENTS.md | tr -d '`' | grep '/' | while read -r p; do
[ -e "$p" ] || [ -e "apps/web/$p" ] || echo "missing: $p"
doneRead the output instead of connecting this one to CI. E also flag globs like src/**/*.ts and any URL wey you quote, because both get slash and neither one be file for disk.
The symptom inside session. The agent reads the file, tries to open src/api/client.ts because na wetin the file tell am, and the tool returns:
No such file or directorySo e do the reasonable thing and write im own fetch wrapper. Na this be the real cost of stale file. The agent no ignore your documentation. E follow the documentation, reach path wey dem delete three months ago, then rebuild code wey you already get. Skill like Ponytail, wey dey hold agent to the smallest change wey go work, fit make this rebuilding instinct happen less often, but e no fit find helper wey your file point to wrong place.
Claude Code dey read AGENTS.md files?
No. E good make we talk am clearly because the nested layout depend on this. As of August 2026, the documentation talk say: "Claude Code dey read CLAUDE.md, no be AGENTS.md." The pattern still dey work, but you need one CLAUDE.md beside each AGENTS.md.
The import form correct when you want tool-specific lines join the shared ones. Put this inside services/worker/CLAUDE.md:
@AGENTS.md
## Claude Code
Use plan mode for changes under `services/worker/migrations/`.The symlink form correct when you no get any tool-specific thing to add.
git ls-files '*AGENTS.md' | while read -r f; do
ln -s AGENTS.md "$(dirname "$f")/CLAUDE.md"
done
ls -l apps/web/CLAUDE.mdln no dey print anything when e succeed, so check the listing: apps/web/CLAUDE.md -> AGENTS.md. Then start one session and run /context, where the loaded files go show under Memory files. For Windows, symlink need Administrator rights or Developer Mode, so use the @AGENTS.md import there instead.
One trap dey here. After /compact, the root file dey read again from disk, but nested files for subdirectories no dey inject again. Dem go return the next time the agent read one file for that directory. If per-directory rule seem stop applying halfway through one long session, na usually this cause am, and touching any file for the directory go bring am back.
Settings wey point other agents to AGENTS.md
Codex dey read AGENTS.md natively. For each level, e first check AGENTS.override.md, so one directory fit get local override without editing the shared file. E stop merging when the combined size reach 32 KiB, wey be the default project_doc_max_bytes, and this na another reason to keep the root file small.
Aider dey take am through .aider.conf.yml with the line read: AGENTS.md.
Gemini CLI dey take am through .gemini/settings.json with { "context": { "fileName": "AGENTS.md" } }.
Upstream documents one backward-compatible rename for repositories wey still dey use the older singular name: mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.
For one very large monorepo, Claude Code's claudeMdExcludes setting fit skip ancestor files by path or glob. This useful when another team's directory dey above your own.
Dis na so e different from agent memory, or from a skill?
These mechanisms dey look alike, but dem dey fail for completely different ways. So e good make you clear about which one you wan use.
You write AGENTS.md, commit am to git, review am for pull request, and everybody wey clone the repository go get the same copy. Agent memory na agent dey write am, e dey stored outside the repository, and na one machine get am. Claude Code documentation draw the same line: CLAUDE.md hold "Instructions and rules" wey you write, auto memory hold "Learnings and patterns" wey Claude write, and memory directory no dey shared across machines. The test simple. If fact must dey true for colleague wey just clone repository, e no fit dey memory. How agent memory persists between sessions cover that side of the matter.
A skill na the third thing. AGENTS.md na context wey loads for every session; a skill na procedure wey loads when you need am. Claude Code docs give one useful rule: "If an entry is a multi-step procedure or only matters for one part of the codebase, move it to a skill or a path-scoped rule instead." The second part of that sentence na exactly wetin nested AGENTS.md dey solve. The first part na wetin agent skills dey for, and when you need the same procedure for more than one repository, share the skill across repos instead of pasting the same paragraphs inside ten different AGENTS.md files.
Upstream note say "at time of writing the main OpenAI repo has 88 AGENTS.md files". That number na the complete argument. Big repository no need bigger file. E need more small files, with each one dey beside the code wey e describe, and whoever last change that code dey own am.
FAQ
Nested AGENTS.md root file replace e, or e dey add to am?
E dey add to am. Upstream talk say "the closest one takes precedence", and this dey describe wetin happen when conflict dey, no be which files go load. Codex "concatenates files from the root down, joining them with blank lines", while Claude Code dey concatenate every file wey e find as e dey move up from the working directory, instead of overriding dem. The nearest file only win when two files give different instructions about the same subject. Write shared rules once for the root, and no repeat dem for every directory.
How big root AGENTS.md suppose be?
Make e small enough say you no go mind make dem paste am on top of every request wey you make for that repository, because na so e dey happen. Claude Code documentation suggest say make each file under 200 lines, and e warn say longer files "reduce adherence". Codex dey stop merging instruction files when the combined size reach 32 KiB by default. If your root file dey document four services, most of am na dead weight for any one task. Move the details go per-directory files, and leave map behind.
How I fit stop these files from becoming stale?
Put one rule for the root file: anybody wey change code for a directory must update that directory's AGENTS.md for the same commit. Putting the file near the code na wetin make the rule stick, because the change go land for the same pull request diff wey human dey already read. Add CI warning wey maps each changed path to the nearest AGENTS.md above am, and from time to time compare git log -1 --format=%cs for each file with the same command wey you run for the directory wey e document.
Claude Code dey read AGENTS.md files?
No. As of August 2026, the documentation state say "Claude Code reads CLAUDE.md, not AGENTS.md." Create a CLAUDE.md for the same directory with @AGENTS.md for the first line. This go load the shared file and allow you add Claude-specific instructions underneath. A symlink created with ln -s AGENTS.md CLAUDE.md go work when you no get anything extra to add, but for Windows e need Administrator rights or Developer Mode. Run /context for a session and confirm say the file dey show under Memory files.
Where I suppose put rule wey only matter sometimes?
No put am for AGENTS.md. That file dey load for every session, so every line inside am dey compete for attention with the request wey you actually type. Procedure wey get several steps and you only need sometimes belong for a skill, wey loads on demand. Rule wey apply to one directory belong for that directory's AGENTS.md. Fact wey agent fit read directly from the code, like directory tree or dependency list, belong for neither of dem.