Agent memory. What it remembers, what it should.
Fresh session, same agent: it re-reads the project, re-derives the conventions you explained last Tuesday, and re-makes the mistake you already corrected once. Not because it cannot remember — because nothing told it to write things down.
Memory for coding agents has settled into a small set of mechanisms, close enough across Claude Code, Codex and friends to describe once:
- Project files it always reads.
CLAUDE.mdorAGENTS.mdat the repo root, committed, team-shared. If a new teammate would need to know it, it goes here. - A personal memory directory the agent writes itself. Notes with an index file loaded each session — feedback you gave it, environment quirks it discovered. If only you would need to know it, this layer.
- User-level preferences that follow you across projects — the small stuff, like “no emojis in code”.
- The instruction in the moment. “Remember that deploys go through staging first.” The correction you make twice out loud is the one that should be a memory.
What belongs in memory
- Feedback with its why. “We do not push to main — release branches only, because the release train cuts on Thursdays.” The why is what lets the agent generalize the rule to a case you did not predict.
- Environment quirks not in the repo. The staging port, the VPN dependency, which box runs the database this month.
- Decisions that outlive a session. “We chose queue B over A because of the delivery semantics” — so the agent does not relitigate it every session.
What does not
- Anything derivable from the repo in a minute. Project structure, exports, function names. Memory for that is a cache nobody invalidates.
- Secrets. The contents of
.envare not a memory. A pointer to where secrets live is a memory. - One-off task state. “Currently refactoring auth” is stale in a week and actively misleading in three. The git history already tracks what is happening.
The rot problem
Memory is configuration now, and it deserves the treatment config gets:
- Version-control what you can. A memory directory you cannot diff is a memory directory you cannot trust.
- Review it on the same cadence as dependencies. Agents happily append; the same convention recorded three slightly different ways is how contradictions are born.
- Expired facts are worse than no facts. A decommissioned server’s name in memory sends the agent confidently poking a box that no longer exists — with full conviction and zero doubt, which is the failure mode unique to memory.
The honest trade-offs
- Memory eats the context window. An unbounded notes file is a tax on every session; keep the index tight and the entries short.
- Wrong memory beats no memory for damage, every time, because it arrives pre-believed.
- Isolation is per-checkout: one worktree per branch (as per the post from a few weeks back) means the parallel agents do not share what they learn. Mostly a feature. Sometimes you want the lesson propagated, and today that is still a copy-paste job.
- Team versus personal is a real boundary. The committed file teaches your colleagues’ agents too; your vim-binding preferences belong in the untracked layer.
Where I landed
The two-line test settled it: if a new teammate would need to know it, the committed file; if only I would, the personal layer; if nobody needs it in a month, nowhere. Memory went from “the agent keeps forgetting” to “the notes need occasional weeding” — which is the same transition every knowledge system here has made before it started working.