Your coding agent does not remember your codebase; it re-perceives it every session, greps and reads its way back to a mental model, then throws that model away. That re-perception is a line item, and the fix is not a bigger context window.


TL;DR

  • A coding agent starts most sessions with a fresh context window. It rebuilds its understanding of your repo from primitives (read, grep, glob) every time, and loses most of that understanding at session end or at compaction.
  • What persists across sessions is instructions (CLAUDE.md, rules) and, in Claude Code, some agent-written notes. What does not persist is the hard-won synthesis: why the code is shaped this way, what was tried and rejected, which files matter for which task.
  • The re-perception has a price. A representative 50-turn agentic session runs about 1 million input tokens, roughly 25:1 input to output, with input around 85% of the bill.
  • The two obvious fixes both fail on the merits. A bigger window costs more and answers worse (context rot, lost-in-the-middle). Embedding the repo returns what looks similar, not what is correct, and flattens the exact structure of code.
  • What is missing is a durable, structured model of the codebase-as-world: short facts, long-form notes, typed properties, and graph relations on the same entity, governed, and retrieved under a token budget.

Give a coding agent a bug report and watch what it does first. It greps for a function name. It reads three or four files. It globs the test directory, opens the module it thinks is responsible, traces an import, forms a hypothesis, and fixes the bug. Good. Tomorrow you hand it a task in the same corner of the same repo, and it does the entire thing again from zero: the same greps, the same reads, the same slow reconstruction of a model it already built yesterday and the day before.

We call this memory, but it is not memory. A coding agent does not remember your codebase; it re-perceives it every session, rebuilding hard-won synthesis at cost and destroying it again at compaction. The agent is not consulting knowledge. It is re-deriving knowledge, on the clock, every time.

What actually persists, and what gets rebuilt

Start with the mechanics, because the marketing word "memory" hides them. Each Claude Code session begins with a fresh context window. Two disk-backed mechanisms carry anything across sessions, and both are re-loaded at launch. CLAUDE.md files are loaded in full at the start of every session, walked up the directory tree and concatenated. Auto memory (a MEMORY.md the agent writes for itself) loads only its first 200 lines, or 25KB, whichever comes first; topic files load on demand and stay machine-local, not shared across machines or teammates.

Notice what both of those actually hold. CLAUDE.md holds instructions: conventions, commands, do-nots. The docs are candid that it is context, not enforcement, with no guarantee of strict compliance, and that adherence degrades once a file runs long. Auto memory holds the agent's self-notes. Neither one holds the thing that was expensive to produce: the agent's working model of the code itself. The file contents and structure it discovered last session are not persisted. Only whatever it chose to jot down is.

Within a session there is a second eraser: compaction. When input tokens cross a threshold (150,000 by default), older turns are summarized and the pre-compaction content is dropped from subsequent requests. Files re-read from disk survive, because they can be re-read. What does not survive is anything that existed only in the conversation: a decision, its rationale, a gotcha the agent discovered the hard way. If an instruction vanishes after compaction, it was either given only in chat or lives in a nested file that has not reloaded yet.

Cursor takes a different route to the same gap. It maintains a codebase index (a Merkle tree of file hashes plus embeddings in a remote vector store, re-synced as files change) and a Rules system for durable instructions. It briefly shipped a per-project Memories feature and later folded it back toward its Rules and automation model. So Cursor's durable code knowledge is fundamentally similarity retrieval over an index plus human-written rules. It does not maintain a synthesized, structured record of decisions and rationale that survives across sessions.

The pattern generalizes. Persistence today is (a) human-written instruction files plus (b) a similarity index over source. What is not persisted anywhere native is the agent's own synthesis.

| Layer | Persists across sessions? | What it holds | |---|---|---| | CLAUDE.md / rules / .cursorrules | Yes (disk, re-loaded at launch) | Human-written instructions, conventions | | Auto memory (MEMORY.md) | Partly (first 200 lines / 25KB at load; rest on demand; machine-local) | Agent's self-notes | | Codebase embedding index | Yes (vector store) | Similarity lookup over chunks, not synthesis | | In-session mental model (files read, greps, decisions, rationale) | No | Rebuilt from scratch each session; compacted or dropped within a session |

The three bills you pay for amnesia

Amnesia is not a UX quirk. It shows up on the invoice in three ways.

The first is re-perception. Every API turn re-sends the full context as input: the system prompt, every file read, every edit, the whole running conversation. A representative 50-turn session lands around 1 million input tokens against 40,000 output, roughly 25:1, with input about 85% of the cost, on the order of $6 per session on an Opus-class model. At a 25-engineer team running about a thousand sessions a month, that is near $72,000 a year on that model, and the same figure recurs because nothing durable was written between sessions. The dominant cost is not the model generating code. It is the agent re-reading and re-carrying context it already understood once.

The second bill is lost decisions. Compaction and session boundaries destroy precisely the highest-value, lowest-volume information: why a choice was made. A file comes back from disk on demand. A decision made in chat ("we don't use that library because of this failure mode") does not, unless a human remembered to promote it into an instruction file.

The third bill is repeated mistakes. The agent re-introduces a bug it already fixed, re-violates a convention, re-litigates a settled design choice, because the record of "we tried that and it failed" lived in a conversation that no longer exists. It makes the same mistake in session five that it made in session one.

Why the two obvious fixes fail

The reflex is to reach for more context. It backfires on both axes. On quality: every frontier model tested degrades as input grows, even on simple retrieval, and larger windows (256K, 1M, 2M) do not fix it; this is the "context rot" result, with some models falling from around 95% accuracy to roughly 60% past a threshold. Layer on lost-in-the-middle, where models attend well to the start and end of a long context and poorly to the middle, with reported accuracy drops north of 30%. On cost: re-sending everything every turn is the quadratic-ish curve that produced the numbers above. A bigger window is a bigger bill and a worse answer.

The second reflex is to embed the whole repo and retrieve by similarity. This is better than nothing and still the wrong primitive for code. Similarity retrieval finds what looks related, not what is correct. Ask about idempotency keys and get generic retry advice. Chunking fragments continuity, so isolated chunks lack the context to judge their own relevance; that is the exact problem Anthropic's contextual retrieval work exists to patch, and even there the wins come from adding context and reranking on top of raw embeddings, not from embeddings alone. Code has exact structure (imports, ownership, invariants, which decision governs which file) that a vector space flattens into vibes. Similarity is a recall tool. It is not a correctness tool, and it is not a structure tool.

What a real memory layer has to do

Here is the reframe. Stop trying to make the agent hold the codebase in its head each session. Give it a persistent, governed model of the codebase-as-world that it writes to and reads from under a token budget. Not a bigger window: a smaller, better-chosen, durable representation.

Concretely, that model composes four kinds of memory on the same codebase entity.

Short facts. Single self-contained statements: auth lives in src/modules/auth, we pin Node 20, the test database needs a local Redis. Cheap to carry, instant to retrieve.

Long-form notes. The agent's own synthesis: an architecture overview, why a module is shaped the way it is, the write-up of a debugging session. This is the compaction that survives. In an experiment I ran on our own production codebase, about 1.5 million tokens of source distilled into a curated set of long-form module notes totaling roughly 27,000 tokens, about 1.7% of the original, and agents navigating by those notes matched raw file search on most real engineering queries at a fraction of the tokens. Applied to code, this is the direct antidote to re-reading: read once, synthesize, then consult the synthesis.

Typed, structured properties. The fields you can filter, count, and govern: a module's owner, its criticality, a deploy gate, a test command. This is the part free text cannot do and every downstream system needs.

Graph relations. The links: which module imports which, which decision governs which file, which PR touched which subsystem, where a bug recurred. Isolated facts become a world the agent can traverse. This is the codebase's real structure, the part embeddings erase.

The emerging tools each cover a fragment. Native instruction files are durable but human-authored and instruction-only. Claude Code's auto memory is the closest native analog to long-form notes, but it is machine-local, capped at load, and self-notes only. Graph memory systems bring relations and temporality. OS-style approaches let the agent edit its own in-context blocks. Hybrid stores compose vector, graph, and key-value. And there is early research aimed squarely at coding agents that pairs an event log of prior work with a judgment layer separating strategies that worked from ones that failed. None of them yet compose all four kinds, on the same codebase entity, governed, team-shared, and retrieved under budget. That is the opening.

The last requirement is the one people skip: it has to run under a budget, not a bucket. Write synthesis at ingest time, retrieve the few right signals at query time, keep the working set small and correct, and let the agent pull the original back only when it must. Memory that only grows is not memory; it is a slower context window that goes stale. Which is why it also has to be governed: typed, inspectable, with conflict detection and a sense of time, so the model can retire a fact that stopped being true instead of confidently repeating it.

The same lens, pointed at the case you feel daily

I have argued this shape before for the enterprise and the CRM: model the world as entities, relations, and constraints so a machine can act on it well, and treat memory as a model of a thing rather than a pile of stored text. A codebase is just another world to model. Its entities are modules, initiatives, decisions, incidents, releases. Its relations are imports and ownership and provenance. Its constraints are the invariants a team agreed to and keeps forgetting to write down.

And here the identity underneath shows through. A model of a codebase is a model of the decisions a team has made, which is to say a model of the people who made them. Memory, here as everywhere, is a polite word for a model of something.

The takeaway is narrow and, I think, correct. Coding-agent amnesia is not solved by a larger context window (that costs more and answers worse) and not by a better embedding index (that finds what looks right, not what is right). It is solved by a persistent, governed model of the codebase the agent writes to and retrieves from under a budget. The durable synthesis is the missing layer. Everything the agent re-derives at 8 a.m. tomorrow, it already knew at 6 p.m. today. The job is to keep it.