Codex · Series · Part 2 of 8
AGENTS.md: the project memory that Codex reads every time
In Part 1 we installed Codex and had a first session. Now the important question: what happens tomorrow? Open a new session and Codex has no idea what the project is, how you build it, or the three things you corrected yesterday. This part explains why that happens and how a plain text file solves it.
- A model has no memory between conversations. Everything it “knows” must be in the text it is given.
AGENTS.mdis a markdown file that Codex reads before it does any work.- It can live in your Codex home folder (personal,
~/.codex), the project root (shared), or sub-folders (specific). Files closer to your working folder win. - An
AGENTS.override.mdfile takes priority overAGENTS.mdin the same folder. /initdrafts one for you. Codex reads a limited amount: 32 KiB by default.- Good files are short, specific and checkable. Bad ones are long, vague or out of date.
Contents of Part 2
- Why Codex forgets
- What AGENTS.md is
- All the ways Codex “remembers”
- Where the file can live, and how Codex finds it
- Creating one with /init
- What to put in it
- A complete example
- Nested files and overrides
- Growing up: rules, skills and linked notes
- Keeping it up to date
- What it cannot do
- Links and official docs
1. Why Codex forgets
If you read my earlier post on how AI chat works, this will sound familiar. A language model does not store your conversation. Every time you send a message, the app packs the conversation so far into one block of text, called the context, and hands it to the model. The model can only look at a fixed amount of text at once, the context window.
When you close the session, that block is gone. A new session starts with an empty window. The model is the same, but it is meeting you for the first time.
2. What AGENTS.md is
It is exactly what the name says: a file called AGENTS.md, written in markdown (the same simple format as a README). Per the official docs, “Codex reads AGENTS.md files before doing any work.” By layering global guidance with project-specific overrides, every task starts with the same expectations, no matter which repository you open. The text becomes standing instructions for the session.
Imagine a contractor with perfect skills but no memory, who forgets everything overnight. You would not re-brief them every morning. You would leave a note on the monitor: “Build with this command. Tests live here. We use tabs, not spaces. Never edit the generated folder.” AGENTS.md is that note, and Codex reads it first every day.
It is different from your README.md. A README is written for humans who might contribute. An AGENTS.md is written for the coding assistant, and contains the things you would otherwise keep repeating in chat. The name is not unique to Codex: the official docs point to the AGENTS.md website for more information about the format.
3. All the ways Codex “remembers”
Before going further, one important fact: the model does not remember anything on its own. It is the same on day 10 as on day 1, and it forgets when a session ends. Everything that looks like memory is Codex putting saved text back into the context window, or saved settings changing how it behaves. The documentation describes these mechanisms:
| Kind of memory | How it works | Lasts how long |
|---|---|---|
| The conversation (chat) | Everything said so far is re-sent with each message (the context window). /compact replaces earlier turns with a summary to free space, and Codex also compacts chats automatically. | One chat. A new chat starts with an empty window. |
| Saved chats | /resume (inside Codex) or codex resume (from the terminal) reloads a saved chat. The docs also describe /fork and codex fork to branch a chat. | Brings the old transcript back, which fills the window again. |
| AGENTS.md files | Read automatically before Codex does any work. Global, repository and nested folders are layered together. | Permanent: they are files on disk. |
| Memories | A feature that turns useful context from eligible earlier chats into local memory files under ~/.codex/memories/. Off by default. Control per chat with /memories. | Until you delete them. Still saved text read back in, not the model learning. |
| Skills | A folder with a SKILL.md file: a reusable workflow. Codex sees the name and description first and loads the full instructions when the task matches or you invoke it. | Permanent while the folder exists. |
| Rules | .rules files that control which commands Codex can run outside the sandbox. Marked experimental in the docs. | Permanent. Enforced by Codex, not just guidance. |
| Config | ~/.codex/config.toml holds saved behaviour such as settings and feature flags (for example project_doc_max_bytes). | Permanent. |
| Custom prompts | Markdown files in ~/.codex/prompts/ that you run as slash commands. Deprecated: the docs say to use skills instead. | Permanent, but local to your machine and not shared through the repository. |
The Memories feature in more detail
Memories let Codex carry useful context from earlier work into future work. The official page is clear about their place: keep required team guidance in AGENTS.md or checked-in documentation, and treat memories as a helpful recall layer, not as the only source for rules that must always apply.
- Off by default. In the ChatGPT desktop app, open Settings > Personalization and turn on Enable Codex memories. For a config-based setup, add this to
config.toml:
[features]
memories = true- It works in the background. After you enable it, Codex can turn useful context from eligible earlier chats into local memory files. It skips active or short-lived sessions and redacts secrets from generated memory fields. A chat must be idle for a while first, so memories may not appear right when a chat ends.
- It is stored locally. The main files live under
~/.codex/memories/(or underCODEX_HOMEif you set it). The docs call them generated state: inspect them when troubleshooting, but do not rely on hand-editing them as your main control. - You control it per chat. Type
/memoriesto choose whether the current chat can use existing memories and whether it can contribute to future ones. That choice does not change your global settings. - You can reset it. In the desktop app, Delete Codex memories clears the memory store of the selected machine.
- Settings exist for finer control, such as
memories.generate_memoriesandmemories.use_memoriesin the config reference. - Do not store secrets in memories. Codex redacts secrets, but the docs still say to review the memory files before sharing your Codex home folder.
Details: Memories in the official docs.
What happens if you say “remember this”?
By itself, nothing is guaranteed. Saying it does not change the model. Whether anything survives depends on whether Codex actually writes a file:
- It edits a file (you see a diff for
AGENTS.md). That text is read next session. - It only replies “Okay, I'll remember” and no file changes. Nothing is saved from that sentence alone, and a fresh session will not know.
- Memories may pick something up later, but only if the feature is on, and it decides what is worth keeping.
To check, look for the file edit in the session or run git diff. Part 3 shows a better way, an explicit handoff note.
4. Where the file can live, and how Codex finds it
You can have several, and Codex combines them. Each location has a different audience:
| Location | Who it is for | Typical content |
|---|---|---|
~/.codex/AGENTS.md | You, in every project | Personal working agreements: “prefer pnpm”, “ask before adding production dependencies”. |
~/.codex/AGENTS.override.md | You, as a temporary global override | Replaces the global file without deleting it. Remove it to restore the base file. |
AGENTS.md at the project root (typically the Git root) | Everyone on the project (you can commit it to git) | Build and test commands, layout, conventions. |
AGENTS.md or AGENTS.override.md in a sub-folder | Work inside that folder | Rules for one service or module, such as services/payments/. |
The “Codex home folder” defaults to ~/.codex. If you set the CODEX_HOME environment variable, Codex uses that folder instead.
How Codex builds the instruction chain
According to the official docs, Codex builds its instruction chain when it starts (once per run; in the terminal interface that usually means once per launched session). The order is:
- Global scope. In your Codex home folder, Codex reads
AGENTS.override.mdif it exists. Otherwise it readsAGENTS.md. It uses only the first non-empty file at this level. - Project scope. Starting at the project root (typically the Git root), Codex walks down to your current working folder. If it cannot find a project root, it only checks the current folder. In each folder along the path it checks for
AGENTS.override.md, thenAGENTS.md, then any fallback names you configured. It includes at most one file per folder. - Merge order. Codex joins the files from the root down, separated by blank lines. Files closer to your current folder override earlier guidance because they appear later in the combined prompt.
A good split is: personal taste in the global file, how this project works at the root, and how this one area works in a nested file.
Size limit and fallback names
- Size limit. Codex skips empty files and stops adding files once the combined size reaches
project_doc_max_bytes, which is 32 KiB by default. If you hit the cap, raise the limit or split instructions across nested folders. - Fallback names. If your repository already uses another file name, list it in
project_doc_fallback_filenames. Names not on the list are ignored.
project_doc_fallback_filenames = ["TEAM_GUIDE.md", ".agents.md"]
project_doc_max_bytes = 65536With that config, Codex checks each folder in this order: AGENTS.override.md, AGENTS.md, TEAM_GUIDE.md, .agents.md. Restart Codex after changing the config.
Checking what Codex loaded
The docs suggest asking Codex itself. Start it with approvals off for a read-only question, from the folder you want to test:
codex --ask-for-approval never "Summarize the current instructions."
# test a nested folder without cd-ing into it
codex --cd services/payments --ask-for-approval never "List the instruction sources you loaded."Expected, per the docs: Codex reports the global file first, the repository root file second, and the nested file last. If instructions look stale, restart Codex in the target folder. It rebuilds the chain every run, so there is no cache to clear. If nothing loads, check that you are in the repository you expect (codex status shows the workspace root), that the file is not empty, and that no AGENTS.override.md higher up is hiding the normal file.
5. Creating one with /init
You do not have to start from a blank page. Run /init in the folder where you want Codex to look for persistent instructions. The docs describe it as the command that generates an AGENTS.md scaffold for the current folder.
> /init
● Looking at your project…
● Created AGENTS.md
A starter scaffold for this folder.
Review it, then edit it to match how you build and test.
The docs call it “a great starting point,” but say you should edit the result to match how your team actually builds, tests, reviews and ships code. It cannot know your unwritten rules or what has gone wrong before, so that part is yours to add. The scaffold is something you can refine and commit for future sessions.
You can also create the global file by hand:
mkdir -p ~/.codex
# ~/.codex/AGENTS.md
## Working agreements
- Always run `npm test` after modifying JavaScript files.
- Prefer `pnpm` when installing dependencies.
- Ask for confirmation before adding new production dependencies.6. What to put in it
The official best-practices page says a good AGENTS.md covers: repo layout and important directories, how to run the project, build, test and lint commands, engineering conventions and PR expectations, constraints and do-not rules, and what done means and how to verify work. My test for every line is simple: would Codex get this wrong, or waste time finding it, without being told? If not, leave it out.
Specific beats vague. Compare these two lines:
| Vague | Specific |
|---|---|
| Format code properly. | Run ./gradlew ktlintFormat before committing. |
| Keep tests passing. | Run ./gradlew testDebugUnitTest; all tests must pass before you say a task is done. |
| Follow our architecture. | UI calls a ViewModel, the ViewModel calls a Repository. Never touch the database from a screen. |
The docs add: “Keep it practical. A short, accurate AGENTS.md is more useful than a long file full of vague rules. Start with the basics, then add new rules only after you notice repeated mistakes.”
7. A complete example
Here is a realistic root file for the Android chat app from my earlier post. It is deliberately short. The commands are the ones a normal Gradle Android project uses; replace them with yours.
# Private AI Chat (Android)
Kotlin + Jetpack Compose app that chats with an on-device model
(llama.cpp) or an online model, with fallback between them.
## Commands
- Build debug: ./gradlew assembleDebug
- Unit tests: ./gradlew testDebugUnitTest
- Lint/format: ./gradlew ktlintFormat
- Release bundle: ./gradlew :app:bundleRelease
## Structure
- app/ui/ Compose screens (no business logic)
- app/chat/ ViewModels, builds the prompt
- app/engine/ LlmEngine interface + local / online / rules impls
- app/data/ Room database (chats, memories, settings)
- native/ llama.cpp + JNI bridge (C++)
## Conventions
- Screens never call an engine directly: go through the ViewModel.
- Every engine returns Flow<String> of text pieces.
- All native calls run on the single dedicated native thread.
- Use https only for online models; never log prompts or API keys.
## Do not
- Do not edit anything under app/build/ or generated/.
- Do not add a production dependency without asking first.
## Gotchas
- The native build must target plain armv8-a, or older phones crash (SIGILL).
- Test release builds on a real device: R8 can strip JNI classes.
## Definition of done
- Unit tests pass and ktlint is clean.
- New user-visible strings are in strings.xml.It is about thirty-five lines. It answers the questions Codex would otherwise spend time on: how to build, where things live, what not to touch, and the two traps that already cost me a day each.
For a JavaScript or Node project the shape is the same. Only the commands change, for example npm run lint, npm test and “document public utilities in docs/ when you change behavior”.
8. Nested files and overrides
As a project grows, one team needs different rules from the rest. Put a file in that team's folder. The docs use a payments service as the example:
# services/payments/AGENTS.override.md
## Payments service rules
- Use `make test-payments` instead of `npm test`.
- Never rotate API keys without notifying the security channel.Start Codex from that folder and it reads the global file, then the root file, then this one last. Because later text wins, the payments rule about tests beats the general one. A few details worth remembering:
- An
AGENTS.override.mdin a folder is checked beforeAGENTS.mdin that folder, and only one of the two is used per folder. - “Codex stops searching once it reaches your current directory”, so place overrides as close to specialised work as possible.
- A stray override higher in the tree is the usual reason wrong guidance appears. Rename or remove it to fall back to the regular file.
- If you use Codex code review on GitHub, the docs say to add a
## Code Review Rulessection to theAGENTS.mdclosest to the code it governs. Keep those rules concise, and leave formatting and lint checks to CI.
9. Growing up: rules, skills and linked notes
One AGENTS.md is enough for a small project. As a project grows, a single file turns into a long list that fills the 32 KiB budget and is hard to maintain. The docs suggest two moves: split instructions across nested folders (section 8), and keep the main file concise while referencing task-specific markdown files for things like planning, code review or architecture. Beyond that, Codex has separate places for other kinds of knowledge:
The pieces, one by one
| Piece | What it is | Loaded | Guaranteed? |
|---|---|---|---|
AGENTS.md | Core notes: commands, structure, key conventions. | When the session starts, up to the size limit | No, it is guidance |
Nested AGENTS.override.md / AGENTS.md | Rules for one area of the project. | Along the path from the project root to your working folder | No, it is guidance |
SKILL.md in a skill folder | A reusable workflow for one job. It must include name and description. | Only the name and description are listed up front; the full text loads when the task matches or you invoke it with /skills or $ | No, Codex decides when to use it (unless you call it) |
.rules files | Which command prefixes may run outside the sandbox: allow, prompt or forbidden. Experimental. | Scanned at startup from the rules/ folder of each active config layer | Yes, Codex applies them |
config.toml | Saved settings: behaviour, feature flags, instruction-loading options. | At startup | Yes, enforced by the tool |
The most useful distinction is the last column. AGENTS.md and skills ask Codex to behave a certain way. Rules and configuration make it happen. If Codex must never run a command, do not rely on a sentence in AGENTS.md. Use a rule.
Skills: a recipe that loads on demand
A skill packages a procedure you would otherwise paste into chat again and again, such as “how we write release notes”. Codex starts with each skill's name and description (the docs call this progressive disclosure), then loads the full instructions when it decides to use that skill. That is the token saving: long how-to text costs nothing on unrelated tasks. Codex reads repository skills from .agents/skills (it scans every folder from your working folder up to the repository root), and your personal skills from $HOME/.agents/skills.
---
name: create-release-notes
description: Write release notes from merged changes. Use when asked to
prepare or draft release notes for a version.
---
1. List merged pull requests since the last tag.
2. Group them: Features, Fixes, Internal.
3. Write one plain-language line per change; no ticket numbers.You can mention a skill in a prompt with $ or pick it with /skills. To draft one, the docs say to invoke $skill-creator. Skills are covered properly in Part 6.
Rules: enforced command policy
Rules are a different thing from instructions. They control which commands Codex can run outside the sandbox. A rules file lives under a rules/ folder next to an active config layer, for example ~/.codex/rules/default.rules. Here is the docs' example, which asks for approval before gh pr view runs:
prefix_rule(
pattern = ["gh", "pr", "view"],
decision = "prompt",
justification = "Viewing PRs is allowed with approval",
match = ["gh pr view 7888"],
not_match = ["gh pr --repo openai/codex view 7888"],
)If more than one rule matches, the most restrictive decision wins (forbidden beats prompt, which beats allow). Restart Codex after adding a rule, and use codex execpolicy check to test one. Project-local rules under .codex/rules/ load only when that project layer is trusted. The docs mark rules as experimental and subject to change, so check the Rules page before relying on the syntax. The approval and sandbox ideas behind this are in Part 1.
Custom prompts: deprecated
You may find older guides that tell you to put reusable prompts in ~/.codex/prompts/ and run them as /prompts:name. The docs now mark custom prompts as deprecated and point to skills instead, because prompts need explicit invocation, live only on your machine, and are not shared through the repository.
What goes in git, and what does not
- Commit: the project
AGENTS.mdand nested files, and repository skills. The whole team gets the same assistant. - Keep personal: your global
~/.codex/AGENTS.md, yourconfig.toml, and generated memory files. Those belong to you. - Never store keys, tokens or customer data in any of these files, committed or not.
- Review changes to these files in pull requests like code, because a bad instruction affects every future session.
Start small. Begin with one AGENTS.md. Add a nested file only when one area really differs, and add a skill when you paste the same instructions a third time.
10. Keeping it up to date
Three easy ways to change the file:
- Tell Codex in plain words: “Add to AGENTS.md that we always run ktlint before commits.” It will edit the file for you, and you review the diff.
- Edit it like any other file in your editor and review the change in a pull request.
- Run a retrospective. The docs suggest: when Codex makes the same mistake twice, ask it for a retrospective and update
AGENTS.md, so the guidance stays based on real friction.
> The debug build needs JAVA_HOME set to JDK 17.
Add that to AGENTS.md.
● Edited AGENTS.md
+ - Needs JDK 17: set JAVA_HOME before running Gradle.
● Added under ## Commands.
Make this a habit: if you correct Codex twice, put the correction in the file. Equally, when a line stops being true, delete it. A wrong note is worse than none, because Codex will follow it with confidence. After a change, start a new session (or restart Codex) and ask it to summarise the current instructions, as in section 4, to confirm the new text is picked up.
11. What it cannot do
- It is guidance, not enforcement. Codex usually follows it, but nothing guarantees it. For commands that must never run without approval, use rules and the approval and sandbox settings from Part 1.
- It has a size limit. By default Codex stops adding files at 32 KiB combined, so a bloated file can be cut off. It also sits in the context window, using room that could hold your code or conversation.
- It is not learning. Codex does not get smarter from your usage. The model is fixed, and a new session on day 10 starts as blank as on day 1. Only what is written down carries over, so the file is your memory, not Codex's.
- It is not secret. It is plain text, and a project file is usually committed to git. Never put credentials in it.
- It is read when a session starts. Edits made mid-session are not guaranteed to be in the window until the next run, so restart after big changes.
- It can go stale. Nobody updates what nobody owns. Treat it as code: review it, and prune it.
That size point, the cost of space, is where Part 3 begins: how to make the file earn its tokens, and how it helps when you join a new project or start a new feature.
| Term | In plain words |
|---|---|
| Context window | The fixed amount of text the model can read at once. |
| AGENTS.md | A markdown file Codex reads before it does any work. |
| AGENTS.override.md | A file checked before AGENTS.md in the same folder; it takes priority there. |
| CODEX_HOME | The Codex home folder. Defaults to ~/.codex. |
| /init | Command that generates an AGENTS.md scaffold. |
| /memories | Command that controls whether a chat uses or creates memories. |
| project_doc_max_bytes | Config setting for the size limit on instruction files. 32 KiB by default. |
| Skill | A reusable recipe whose full text loads only when the task matches. |
| Rule | A .rules entry that decides whether a command may run outside the sandbox. |
| Standing instruction | A rule present at the start of every session. |
12. Links and official docs
Codex changes quickly. This series was checked against the official documentation on 18 October 2026; always confirm details on the official pages.
- Custom instructions with AGENTS.md: discovery order, overrides, fallback names and size limit.
- Memories: the local memory feature,
/memoriesand its settings. - Skills:
SKILL.mdand how skills load. - Rules:
.rulesfiles andprefix_rule. - Advanced configuration: project instructions discovery and config locations.
- Slash commands in the CLI:
/init,/memories,/resume,/compact. - Best practices: what a good AGENTS.md covers.
- agents.md: the format's own website.
These pages move and grow as Codex changes. If a name or option here does not match your version, the docs are right and this post is out of date.