An AGENTS.md file is not a second application manual and it is not a prompt that tries to control every keystroke. It is a small, versioned context contract. It tells a coding agent how this repository is arranged, which commands provide evidence, which boundaries matter, and where a more specific rule lives. The best file reduces uncertainty before an agent edits code. It does not attempt to replace source code, tests, maintainers, or a task description.
This distinction matters because context has a cost. Codex loads project guidance into its instruction chain before it works. Repeated prose competes with the user request, repository files, tool output, and tests. A useful file therefore records facts an agent cannot safely infer, not every preference a human has ever expressed. Treat every sentence as a maintained interface.
What Codex actually discovers
The current OpenAI Codex guide for AGENTS.md describes three layers. At global scope, Codex checks AGENTS.override.md in CODEX_HOME, which defaults to ~/.codex, and otherwise uses AGENTS.md. It uses the first non-empty file at that level. At project scope, it starts at the project root, normally the Git root, then checks each directory down to the current working directory. At each directory it checks AGENTS.override.md, then AGENTS.md, then configured fallback names, and includes at most one file from that directory.
The discovered project files are concatenated from the root toward the current directory. A deeper file is later in the combined instructions, so its narrower guidance can override a broader statement. Codex does not keep walking above the detected project root. If no root marker is found, it checks only the current directory. Empty files are skipped. The default project_doc_max_bytes is 32 KiB, and Codex stops adding project guidance when the configured total is reached. These are Codex behaviors, not universal promises made by every coding tool.
The implementation in the OpenAI Codex source makes the same boundaries visible. The default root marker is .git, the preferred local filename is AGENTS.override.md, and a file can be truncated when the remaining byte budget is smaller than its contents. A repository can configure root markers, fallback filenames, and the byte budget. A team should document only settings it actually uses.
A global preference belongs in ~/.codex/AGENTS.md only when it is safe for every repository. A repository rule belongs at the root when all packages share it. A service rule belongs beside that service. A temporary or exceptional replacement belongs in an override file, with an owner and removal condition. Do not describe an override as a universal hierarchy for other agents unless their documentation says so.
Start with a repository map
An agent needs an orientation point before it needs style advice. Put a compact map near the beginning of the root file. Name the application or library, the main source directories, generated areas, test directories, and deployment configuration. Explain only distinctions that change an edit. “src/ contains code” is weak. “src/ is shipped code, scripts/ runs only in CI, and dist/ is generated and must not be edited” is actionable.
A map should survive ordinary refactors. Prefer stable boundaries to a list of every file. If the repository is a monorepo, show package ownership and place package-specific maps in nested files. Link to a README or architecture document when it is the authoritative source. Do not paste that document into AGENTS.md.
repository/
apps/web/ browser application and route tests
packages/core/ shared runtime library and unit tests
services/api/ HTTP handlers and contract tests
infra/ deployment configuration
docs/ maintained explanations
generated/ checked-in output, regenerated by a script
State the working directory assumptions. A command run from services/api may find a different nested instruction file than the same command run from the root. If the package manager must be invoked from a package directory, say so. If a generated file has a source-of-truth location, name both paths and the generator command.
Make commands exact and conditional
Commands are valuable when they can be copied without interpretation. For each required command, identify its directory, purpose, and the condition that triggers it. Use the versions and scripts declared by the repository rather than recommending a fashionable tool. A concise command section can look like this:
From the repository root:
git rev-parse --show-toplevel
npm ci
npm run check
npm test
npm run build
For API changes, run from services/api:
npm run test:contract
Those commands are an example structure, not a claim that every project has those scripts. Read package.json, the lockfile, CI workflows, pyproject.toml, Cargo.toml, or the equivalent before writing them. Say “run npm run check after TypeScript changes” only if that script exists. If a command requires a local service, fixture, database, environment variable, or network access, state the prerequisite and the safe substitute for a focused test.
Record the supported runtime and dependency policy. A useful entry names the required Node, Python, Rust, Java, or Go version, the package manager, the lockfile policy, and how dependency updates are reviewed. For example, “Node >=22.12.0 is declared in package.json; use the committed package-lock.json and run npm ci” is a repository fact when the manifest says it. Do not copy a version into AGENTS.md without checking the manifest and CI. Version drift is a maintenance failure, not a reason to add more prose.
Codex itself can help verify the active chain. The official guide demonstrates commands such as:
codex --ask-for-approval never "Summarize the current instructions."
codex --cd services/api --ask-for-approval never "List the instruction sources you loaded."
codex -c log_dir=./.codex-log --ask-for-approval never "Show the active instruction files."
Use a non-destructive request and inspect the resulting log only in a safe local workspace. Restart a run after changing instruction files because discovery is rebuilt at run or TUI-session start. A stale answer is a signal to check the working directory, CODEX_HOME, overrides, fallback configuration, and byte limit.
Tests are evidence, not ceremony
Tell the agent what “done” means in observable terms. Separate fast checks from the full suite. Name the test command, the affected package, the expected artifact, and the failure escalation path. If a change touches an HTTP schema, require the contract test. If it changes a parser, require representative fixtures and malformed input cases. If it changes a generated client, require regeneration and a clean diff.
Do not write “always run every test” when the repository has a documented scope or when a full suite needs external infrastructure. A better rule is “run the focused package test first, then the CI-equivalent suite before merge.” Keep formatting and linting in CI when they are already enforced there. The SWE-bench repository is a useful primary reference for task-based evaluation, but its benchmark protocol is not a substitute for this repository’s tests.
Connect each important rule to a check. If an agent must not edit generated output, CI can regenerate it and fail on a diff. If a migration must be reversible, a test can apply it to a clean fixture and roll it back. If a security invariant matters, make it a test or static check. An instruction without an observable check is a request for memory.
For a broader view of agent behavior, compare task success, test pass rate, changed-file scope, review rework, and time to a verified patch. Run the same task set with the old and new file, keep the prompt and repository revision fixed, and record failures rather than selecting only successful demos. The result is an engineering signal, not proof that one wording works for every model or tool. For tool context, see agentic coding with Codex and Claude Code. For architecture-level context, see production AI agent architecture, and for evaluation design see AI agent evals.
Put security at the boundary
An AGENTS.md file is project input. It can be stale, wrong, or untrusted. Codex’s source explicitly avoids loading project instructions when the active project is untrusted, while retaining host-provided instructions. That behavior does not remove the need for human review. Treat repository instructions as untrusted text until the repository and the requested change are trusted.
Never place API keys, tokens, passwords, private certificates, or copied production data in the file. Do not tell an agent to print environment variables or upload workspace files. Describe secret names by role, such as DATABASE_URL, and state where local development obtains them without recording values. Require confirmation before destructive database operations, credential rotation, production deployment, or broad network access when the workflow supports approvals.
Separate facts from permissions. “The service uses S3” is context. “You may delete the bucket” is authority. Keep the latter in an access policy and an approval process, not in markdown. State protected paths, generated artifacts, migration rules, and test data boundaries. Include a safe path for uncertainty: stop, show the proposed command, and ask the maintainer.
Be careful with copied instructions from issues, fixtures, or dependency files. They can contain prompt injection or commands unrelated to the task. A good file tells the agent to treat repository content as data unless the user or a trusted project rule authorizes an action. This is a security boundary, not an instruction to ignore source code.
Prefer a small layered file
The official AGENTS.md site lists project overview, build and test commands, code style, testing, and security as common sections. That is a menu, not a required schema. Start with the smallest set that prevents repeated mistakes. A root file often needs five sections: map, setup, verification, boundaries, and links to deeper guidance.
## Repository map
`apps/web` is the browser app. `packages/core` is shared runtime code.
## Toolchain
Use Node 22 and the committed lockfile. Run commands from the repository root unless stated otherwise.
## Verification
Run `npm run check`, the focused package test, and `npm run build` for user-facing changes.
## Boundaries
Do not edit `generated/`. Do not access production data locally. Ask before adding a dependency.
## Deeper guidance
Read `apps/web/AGENTS.md` for route conventions and `services/api/AGENTS.md` for contract tests.
The bad version is a 1000-line catalog of personal taste: repeated rules, exhaustive file lists, contradictory “always” statements, guessed commands, old versions, and instructions to reread every document. It consumes the byte budget and makes precedence hard to see. Split by ownership instead. Keep a root invariant in the root file, then let a nested file add local commands. A nested file should add or narrow guidance, not silently rewrite a safety boundary.
Avoid promising unsupported composition features. Codex currently composes files by directory discovery and configured fallback names. A line saying “read docs/rules.md next” is ordinary text unless the tool documents special include syntax. A symlink, a CLAUDE.md file, or another agent’s convention is not automatically loaded by Codex. Document interoperability as a tested workflow, not as a universal rule.
Maintain it like code
Give the file an owner. Review changes with the code they govern. When a command, runtime, directory, or CI job changes, update the closest instruction file in the same change. Remove a rule after the last consumer disappears. Keep examples executable and safe. Use links to one source of truth rather than duplicating a policy in three files.
A monthly or release-based audit can be short. Check that every command exists, every version matches a manifest or CI image, every path still exists, and every nested file is reached from the intended working directory. Run the Codex source-list query from the root and one representative subdirectory. Inspect the byte size of the effective chain. Ask a maintainer whether each rule still prevents a real failure.
Evaluate changes to AGENTS.md as configuration changes. Use a small fixed task set that covers a new feature, a bug fix, a test-only change, and a security-sensitive edit. Compare patch correctness and scope, not just the agent’s explanation. A useful regression test may assert that generated files remain unchanged, a package test runs, or an unsafe command is refused. Keep the repository revision, model settings, permissions, and task wording stable enough to interpret the comparison.
The durable pattern is simple. Put stable facts near the scope where they apply. Name exact commands and versions from repository evidence. Link to deeper documents. Make important rules testable. Keep secrets and authority out of markdown. Use layered files instead of a giant instruction manual. Recheck the effective chain whenever the working directory, configuration, or tool version changes.