AGENTS.md, CLAUDE.md and the rest: what belongs in a memory file
Every harness reads a file before it reads your code. What you put in it decides whether the agent starts each session informed or guessing.
The one file every harness has
Whatever you are driving, it loads a project file before your first message and treats it as standing instruction. The names differ and the loading rules differ in the details, but the job is identical: tell the agent what it cannot work out by reading the code.
That last clause is the whole discipline. Most memory files are bad because they restate what the repo already says.
What does not belong in it
Delete these on sight:
A description of the directory structure. The agent can list files. It does that faster than it reads your description, and your description goes stale the first time someone adds a folder.
The tech stack. It is in the lockfile.
Coding style that a linter enforces. If the linter catches it, the instruction is dead weight in every single session. Move it to the linter and let the hook fail.
Anything aspirational. "We write tests for everything" in a repo at 40% coverage teaches the agent that this file lies, and it will discount the rest of it.
The cost here is not just noise. Everything in this file is in the context window for every turn, forever. A hundred lines of restated repo structure is a hundred lines not available for the problem.
What does belong in it
Facts that are true, non-obvious, and expensive to discover:
Commands that are not guessable. The test command that needs a specific env var. The build that must run from a subdirectory. The one script that looks like it works but is deprecated.
Landmines. "The migrations directory is generated — edit the schema, never the migration." This is the highest-value line in most memory files.
Decisions with a reason. Not "we use X", which is discoverable, but "we use X because Y, so do not replace it with Z" — the thing that stops an agent from helpfully modernising something you chose on purpose.
Where things go. Which layer new code belongs in, when the repo has more than one plausible answer.
A good test: if a competent new hire would ask about it in their first week, it belongs. If they would find it in ten seconds, it does not.
In Claude Code
CLAUDE.md, and it cascades. Files are read from the repo root down to the working directory, plus
a personal one:
~/.claude/CLAUDE.md— yours, applies to every project. Preferences, not project facts.<repo>/CLAUDE.md— the team's, committed.<repo>/<subdir>/CLAUDE.md— loaded when work happens in that subtree. This is the one people forget, and it is the best tool for a monorepo: package-specific rules stay out of everyone else's context.
The split matters. Personal preferences in the committed file will quietly govern your colleagues' sessions; project facts in the personal file will be missing from theirs.
Claude Code is the field's holdout on AGENTS.md. Nearly everything else now reads that file;
Claude Code centres CLAUDE.md and does not pick AGENTS.md up on its own. If your team is mixed,
write AGENTS.md as the source of truth and pull it in with an @AGENTS.md import or a symlink,
rather than maintaining two files that drift.
In Codex CLI
AGENTS.md, which is the closest thing this space has to a standard — several harnesses read it,
which makes it the right choice when your team is not all on the same tool.
It nests the same way: a file deeper in the tree applies to work in that subtree. There is no personal-versus-project split, so anything you want to keep to yourself has to live outside the repo entirely, in your own configuration.
If your team is mixed, write AGENTS.md as the shared source of truth and keep tool-specific files
thin — a few lines that point at it rather than duplicating it.
In GitHub Copilot CLI
AGENTS.md, the same file Codex and most of the field read — which is the practical argument for
writing that one first if your team is mixed.
The thing worth knowing here is organisational rather than technical: in most companies Copilot is
already deployed and already paid for, so AGENTS.md in a repo is the instruction file with the
widest reach by default. If you write only one memory file, this is the one that the most colleagues
will actually be running.
In Cursor
.cursor/rules, and it is the odd one out: rather than one always-loaded file, rules are a set,
and each one can declare when it applies — always, for certain file globs, or only when the agent
decides it is relevant.
That is genuinely more powerful and it is also the main way teams get this wrong. A rule scoped to a glob is invisible until someone touches a matching file, which makes "why did it ignore our convention" hard to debug.
The practical shape: one always-on rule holding the landmines and the non-guessable commands, and glob-scoped rules for anything that only matters in one part of the tree.
In Antigravity CLI
Either GEMINI.md or AGENTS.md — it reads both from your working directory, plus a global
~/.gemini/GEMINI.md on top of that.
That makes it the one harness where the portable file and the vendor-specific file are both
first-class, so write AGENTS.md and you are also covered on Codex, Copilot and Kimi Code. Keeping
both in one repo means both get loaded — two standing instructions competing, not a fallback chain.
The very large context window tempts people into a much longer file, on the theory that it is affordable. It is affordable and it is still a bad idea: a long standing instruction competes for attention with the actual task, and the failure is not truncation but dilution. The limit worth keeping is about attention, not tokens.
In Kimi Code CLI
AGENTS.md, the same file Codex reads — which is the practical argument for writing that one
first. If your memory file is portable, switching harnesses costs you nothing on this axis.
Kimi Code routes between models depending on the work, so keep the file free of anything that assumes a particular model's habits. Instructions of the form "do not over-explain" tend to be tuned to one model and read as noise to another.
Keeping it honest
Memory files rot in a specific way: things get added and nothing ever gets removed, because removing feels risky. Two habits stop that.
Delete on contradiction. The moment you notice the agent following an instruction that is no longer true, remove the line in that session. Not later.
Keep it under a screen. An arbitrary limit, and that is the point — it forces the question "what is the least useful line here" every time you add one. A file nobody prunes is a file that stops being read carefully, by you and by the model.
CLAUDE.md# Project notes
## Commands
- Tests: `just test` (needs DATABASE_URL; `just db` starts one)
- Build: run from `apps/api`, not the repo root
## Landmines
- `db/migrations/` is generated. Edit `db/schema.sql` and regenerate; never hand-edit a migration.
- `internal/legacy/` is frozen. Bugs get fixed there, features do not.
## Decisions
- We hand-roll the query layer instead of using an ORM, because the reporting queries need the
control. Do not replace it with an ORM.
- Errors cross the API boundary as codes, never as messages. Messages are assembled client-side so
they can be translated.
## Where things go
- New endpoints: `apps/api/routes/`, one file per resource.
- Anything shared between api and worker: `packages/core/`. If it imports from `apps/`, it is in
the wrong place.