What a root AGENTS file tells Codex on the first run
Codex begins every session with almost no memory of your project. It sees files as they are handed to it, not the intentions behind them, and a first run on an unfamiliar repository usually starts with exploratory questions that eat into the task itself. The AGENTS file at the repository root is the onboarding document that removes that exploration: one markdown file, read before the model touches anything else, that explains where things live and how the project is meant to be worked on.
Treat it as a map rather than a manifesto. The useful version answers five questions in order, and it answers them with paths and commands instead of adjectives.
- What this repository is and which parts matter to most tasks.
- Where the entry points live, such as the app bootstrap, the server start file, or the CLI runner.
- Which directories hold source, tests, fixtures, generated code, and vendored dependencies.
- The commands to run for building, testing, and linting, written exactly as you type them.
- The rules that are easy to break, such as generated files that must not be edited by hand or shared modules that need a review pass.
Keep each line short and concrete. If Codex reads that src/generated is produced by a code generator, it will not try to refactor it. If it reads that tests mirror the source tree under tests/, it places a new test in the right directory without asking. The map pays for itself on the very first task.
Nested AGENTS files that live next to the code
A single root file works until the repository outgrows it. When one file has to describe a services directory, a mobile client, a shared SDK, and three tooling packages, the instructions start contradicting each other, and Codex has to guess which rule wins. The alternative is to split instructions by scope: a root file for global conventions and nested AGENTS files inside each subsystem for local detail.
Nested files shine in workspaces where each area has its own build tool, its own test runner, and its own conventions. A service directory can carry its own file that names the database migration folder and the exact test command for that service, while the root file keeps the shared rules about commit hygiene and generated code. Codex reads the file closest to the task and falls back to the root for the rest.
- Root file: project purpose, shared commands, global do-not-touch rules.
- Subsystem file: local entry points, local test commands, local naming habits.
- Module file: the one or two warnings that only matter inside that module.
The trade-off is maintenance. Every nested file is a second place where instructions can drift out of date, so keep them short and only add one where the root file is genuinely too coarse.
Side-by-side: first-run behaviour of each layout
Here is how the two approaches behave on a typical first task in an unfamiliar repository.
- Discovery: the single root file puts every answer in one place, so Codex finds it immediately; nested files need the model to open a directory before the local rules appear.
- Precision: nested files describe one subsystem without contradiction; a root file blurs together rules from areas that never meet.
- Drift: one file is easy to review in every pull request; several files quietly age apart unless you check them together.
- Onboarding humans: a single map is readable by a new engineer in one sitting; a set of local notes rewards people who already know where they are.
- Task routing: nested files give Codex the right command for the right package; a root file often lists three test commands and hopes the model picks one.
- Cost of change: editing one file is trivial; changing a convention across many nested files needs a sweep and a grep for leftovers.
Neither layout is wasted effort. The difference is where you want your accuracy: a single well-kept map beats a scattered one, and a small set of local notes beats a root file that has grown into a novel.
A checklist before the green light
Before you hand a task to Codex, run this pass over the instructions it will read.
- Every directory mentioned in the file still exists, and no retired path is left behind.
- Every command is copy-pasteable and runs from the repository root without extra setup.
- Generated and vendored paths are named explicitly so they stay out of edits.
- Test placement is stated as a rule, not as an example.
- Conflicting rules are resolved, with one instruction winning and the other deleted.
- Local files are shorter than the root file and add only local detail.
- The file names the tools that actually run in your workflows, so the instructions match reality.
This checklist is cheap, and it catches the failure mode that wastes the most effort: instructions that were true three months ago and now describe a layout that no longer exists.
The recommendation: single page first, split when the map breaks
Start with one root AGENTS file and keep it under a page. Write the directory map, the real commands, and the do-not-touch rules, and stop there. Split into nested files only when you can name a specific failure: a root file that contradicts itself across subsystems, or a task where Codex picks the wrong test runner because three runners are listed side by side. At that point, move the local detail down and leave the root file as the shared spine.
Once the layout is settled, the next variable is which model reads it. SwiftRelay is a pay-as-you-go relay for Claude, GPT, Gemini, DeepSeek, Kimi, GLM, Qwen, Grok and other models, and it works with Claude Code, Codex, Gemini CLI and any OpenAI-compatible SDK. Point Claude Code and Gemini CLI at the bare host https://api.fastapirelay.com, and add /v1 for OpenAI SDKs. Billing is per token, so a lighter model such as Claude Haiku 4.5 or DeepSeek V4 Flash is a good fit for map-checking passes while heavier work goes to a larger model. New accounts get a small gift credit, and inviting friends earns 14% of their top-ups.
Sign up for SwiftRelay and run your first AGENTS-file walkthrough today. Then treat the file like any other piece of code: review it in pull requests, delete lines that stopped being true, and let the map grow only where the repository actually grew.