persistent agent memory codebase

Agent Memory That Outlives the Session: A Practical Look at Persistent Codebase Context

A coding agent that resets every session re-explains the same decision, re-finds the same gotcha file, and re-breaks the same convention. Here is what persistence changes.

A coding agent starting a new session is, structurally, a new hire. Not a new hire on day one of a job search, still learning the industry in general. A new hire on day one at your company specifically, who has read a great deal about software and nothing at all about yours. It does not know the checkout flow caps payment-capture retries at two attempts before routing the order to manual review, because the team learned the hard way what happens past that. It does not know which file everyone quietly avoids touching. It does not know the team spent forty minutes last month arguing through a design and landed somewhere specific. None of that is in the model's weights, and none of it survived the boundary between that session and this one.

Agent memory as a general idea has been covered here already: the working, episodic, semantic, and procedural memory an agent needs, and the extract-store-retrieve loop that gives it any memory at all beyond the context window. This post is narrower and more specific. It is about one expensive instance of that general problem: a coding agent working against a real codebase, and what actually breaks, in concrete terms, when nothing about that codebase carries over from one session to the next. Not what memory is in the abstract. What its absence costs a team by Thursday.

Origin: what a fresh session actually throws away

Every agent, coding or otherwise, starts from the same structural fact: the model is stateless, and the context window is a buffer, not a store. Close the session, and whatever was not written down somewhere durable is gone. For a general-purpose assistant, that mostly costs a repeated preference: reminding it you prefer bullet points, or that you go by a nickname instead of your full name. For a coding agent, the same reset costs something with far more surface area, because a codebase is not a preference. It is thousands of files, a dependency graph between them, a history of decisions about why the graph looks the way it does, and conventions the team agreed on and never wrote down in one place. All of that has to either live in the model's weights (it does not; no model was trained on your private reasoning for why you chose a queue over direct calls), get re-explained every session, or be captured somewhere that survives the reset.

The tool vendors clearly know this is the gap, because they have spent the last two years building around it. Cursor's documentation is upfront that a model retains nothing from one completion to the next, and that its fix is rules: files re-injected at the start of every session so the model gets the same standing instructions each time. Claude Code does the same job with CLAUDE.md, pitched in its own docs as where a developer records what would otherwise have to be repeated to the model every session, plus a newer auto-memory layer where the agent saves its own notes between sessions. GitHub Copilot has repository custom instructions. Windsurf's Cascade auto-generates memories mid-conversation. Devin has a Knowledge feature that recalls tips and conventions across sessions. Five different products converging on some version of the same patch, inside about two years, is itself evidence of how real the underlying gap is.

The academic side saw the shape of this before the product teams shipped fixes for it. A 2024 survey out of Renmin University and Huawei's Noah's Ark Lab, cataloguing the memory mechanisms proposed for LLM-based agents up to that point, already needed a formal taxonomy to organize the number of competing designs: what to store, how to structure it, when to retrieve it, and how to keep it from going stale. None of that literature is specific to coding agents, or even to agents that write software at all. It describes the general shape of a problem this post is about one particular, expensive instance of.

Look closely at what each of those shipped tools actually stores, though, and a pattern shows up. Most of it is instructions a developer wrote by hand: rules, conventions, "always do X." That is genuinely useful, and it is genuinely not the same thing as memory of the codebase. A rule that says tests live next to the code they test is a standing instruction. It does not tell the agent that the billing module calls the ledger module which calls notifications, that the last change to ledger broke notifications in a way nobody thought to write a rule about, or which file will quietly corrupt data if changed without reading the whole thing first. That kind of fact is not a preference to state once. It is a property of the code, usually discovered the hard way, and most of these systems have no durable place to put it beyond a chat transcript or a local, best-effort note.

Present: three scenes every team running a coding agent knows

Take the architecture decision. Three weeks ago, an engineer spent forty minutes with the agent working through why the order pipeline uses an event queue instead of direct service calls: direct calls were fine at ten orders a minute and fell over at peak load, and the queue fixed it without a rewrite of checkout. The agent reasoned through the tradeoff well and the two of them landed on a design together. This week, someone asks it to add a new order type, and it proposes wiring the new type directly into checkout with a synchronous call, the exact pattern the queue exists to avoid. It is not being careless. It never carried forward a version of itself that remembers the conversation. The session that reasoned through the tradeoff and the session doing this week's work are, to the model, unrelated events.

Take the gotcha file. Every codebase past a certain age has one: a file nobody wants to touch, because it looks like ordinary code and is not. Maybe it has a side effect nobody documented, maybe it swallows an exception that matters, maybe it quietly backs a cron job nobody remembers configuring. A capable agent reading it carefully can work this out, the same way a capable engineer can, but working it out costs real analysis: tracing callers, checking what else touches the same table, reading the whole file instead of skimming it. An agent that does this on a Tuesday, again two weeks later when an unrelated task happens to touch the same corner of the code, and a third time the following month, is not getting more careful with practice. It is repeating the same investigation from nothing every time, because none of the three sessions has any access to what the other two already found.

Take the convention. Say the team agreed, out loud, in a session with the agent, that test files live beside the code they test rather than in a parallel tests tree, specifically because the old layout let coverage drift unnoticed. The agent agreed and followed it, for that session. Two weeks later, a different session, same repository, and the agent scaffolds a new feature with a separate tests directory, because that is the more common pattern in what it was trained on and nothing in this session told it otherwise. The agent is not inconsistent by temperament. A decision that lives only in a conversation is not a decision that lives in the project, and without a durable place to put "we decided X, and here is why," every new session is a fresh roll against the model's prior training, which knows nothing about last Tuesday's meeting.

None of this is rare or exaggerated for effect. One developer put it plainly after months of exactly this pattern: opening a project he had worked on for months and asking the agent something reasonable about how two services connect, only to have it guess, ask for the file to be pasted back in, or say outright that it had no access to the codebase at all. Multiply any one of these three scenes by every week a team keeps working this way, and the annoyance turns into a line item.

The three costs that compound, session after session

None of these three scenes involves the model hallucinating. It is reasoning correctly from an incomplete, and repeatedly reset, starting point, and that has a price with at least three distinct line items.

The first is repeated onboarding, paid every session. Someone has to re-explain the architecture, or the agent has to re-derive it by reading files cold, before either of them can get to the actual task. Claude Code's own documentation is explicit that the point of a project memory file is to hold the facts a developer would otherwise retype, itself a tacit admission of how much re-explaining was happening before that feature existed. There is a rough, non-literal human analogy worth naming: Gloria Mark's research at UC Irvine found that people took roughly 23 minutes on average to fully return to a task after an interruption. A model does not get frustrated the way a person does, but the shape of the cost is the same: work resumed from a cold start takes measurably longer than work resumed from a warm one, and every session boundary is a cold start unless something bridged it.

The second cost is quieter and more corrosive: inconsistent output across sessions, which is a different complaint from an agent simply being wrong. It is an agent being right in one session and different, not necessarily worse, in the next, about the same underlying question. Stack Overflow's 2025 developer survey found the single most common frustration with AI coding tools, named by 66 percent of respondents, was output that is almost right but not quite, with time spent debugging that output close behind. A meaningful share of almost right is not a reasoning failure inside one response. It is a consistency failure across responses: the agent that used the event-queue pattern correctly last week and reaches for a synchronous call this week has not gotten worse at reasoning. It lost the thread that made last week's answer the right one.

The third cost is the easiest to put a number on and the one teams notice last: tokens spent re-deriving what was already worked out. Reading five files to reconstruct a call graph is not free. It is prompt tokens for the file contents, completion tokens for the summary the agent builds of what it just read, and wall-clock time before the actual task starts. Aider's answer to a version of this problem, inside a single session, is a repository map built by parsing the codebase with tree-sitter and ranking files by relevance within a fixed token budget, precisely because handing a model the whole repository on every request is not viable even once, let alone every session. That engineering effort is itself a tacit price tag: teams already spend real design work avoiding re-derivation inside one conversation. On a codebase of any real size, re-establishing that context cold can run to tens of thousands of tokens before the agent has produced a single line of the work it was actually asked to do, and at current API pricing that is a real, recurring bill for remembering rather than for building. Paying the same cost again at the start of every new session is the context engineering problem stretched across time instead of across one long conversation, and it compounds in a way a single session's token budget never has to reckon with.

A chat transcript is not memory of a codebase

The obvious fix, and the one most tools reach for first, is to keep the conversation: save the transcript, summarize it, or embed it into a vector store and retrieve the relevant slice next time. This is the same extract-store-retrieve loop covered in the general case, and for an assistant remembering your preferences, it works well enough. For a coding agent it solves less than it looks like it solves, because a chat transcript is memory of the conversation, not memory of the codebase.

The difference is not pedantic. A transcript, even a well-summarized one, records what was said about the code at a point in time: this is why we chose the queue, this file is dangerous, we agreed tests live next to source. Say it enough times in enough sessions and a similarity search over old transcripts will eventually surface something relevant, probabilistically, if the new question happens to be phrased close enough to the old one. But that is retrieval over prose, and prose drifts under summarization and was never guaranteed to be complete to begin with. Windsurf's Cascade memories, for instance, are generated automatically during a conversation, and the product's own documentation is upfront that they are stored locally per workspace and do not sync across machines or teammates: useful for the one developer on the one laptop that generated them, invisible to everyone and everything else. Cursor's rules are the developer-authored counterpart, durable and shareable, but static: they hold what the team decided to write down, not what the agent discovered by reading the code itself.

What none of these quite holds is a structural fact about the codebase, independent of any conversation: that the ledger module is called by billing and by reporting, that changing its return type breaks two specific callers and none of the fourteen other files that merely import it, that this dependency graph is what it is regardless of which chat last mentioned it. That kind of fact does not live in prose, and does not need retrieval by similarity to find, because it is not a memory of something someone said. It is closer to a parsed property of the code itself, the same distinction this site has drawn between a knowledge graph an LLM extracts from documents and a graph built by parsing a structured artifact like source code: the parsed version is deterministic in a way summarized prose is not. Parse the same files twice and the graph comes out the same. Summarize the same conversation twice and it can drift a little each time. A genuinely persistent agent memory, for a codebase specifically, looks a lot more like the first kind of structure than the second.

Future and impact: what changes when the graph persists

None of this means chat memory is a bad idea, or that CLAUDE.md files, rules, and knowledge bases were the wrong thing to build. They are a real improvement over nothing, and five separate products converging on some version of the same patch inside about two years says the industry already agrees a plain reset every session is broken. What most of them are, though, is developer-authored instruction plus a local, best-effort notebook. The less commonly shipped piece is a memory of the codebase itself: a structural representation, built by parsing rather than by summarizing conversation, that persists independent of which developer asked what in which session, and ideally independent of which machine they happened to be sitting at when they asked it. It also has to stay current as the code changes, rather than fossilizing the codebase as it looked on the day someone first ran a scan, and it has to be something an agent can query directly rather than something a developer has to remember to paste back in.

This is the shape of the gap Spiderbrain, built by Perform Digital, is aimed at. It parses a codebase locally into what it calls a brain: a deterministic, source-free context graph of the project, rather than a log of what got said about it. The same codebase produces the same brain every time, a property backed by roughly 350 automated checks run on every release, and only a source-free map of that parsed structure, never the code itself, goes to Spiderbrain's EU-based servers for scoring. The part that matters here is persistence: the brain carries over across sessions, and on the cloud-hosted Pro and Cortex tiers, across machines and devices too, so a new session, even one started on a different laptop, does not begin from the blank page this piece has been describing. It speaks MCP and connects to Claude Code, Cursor, and several other MCP clients, giving an agent something to reason over beyond a transcript of what it was told last time: the deterministic graph that holds it.

None of this requires believing any single tool is the last word on the problem. What it requires is noticing the pattern in the three scenes this piece opened with. An agent that re-argues a settled decision, re-discovers a known hazard, and re-breaks an agreed convention is not a worse model than the one that got each of those right the first time. It is the same model, minus everything the team already knew. Session-scoped chat memory narrows that gap a little. A structural memory of the codebase, kept separate from any one conversation and available to the next one by default, closes more of it. The real measure of whether an agent is getting better at your codebase, session over session, is not whether it sounds more confident. It is whether the fourth session already knows what the first three found out.

Council summary

This post narrows the general case of agent memory, covered separately in agent memory explained, to one expensive instance of it: a coding agent whose session resets discard everything it previously learned about a specific codebase. It grounds the claim in how current tools actually behave: Claude Code's CLAUDE.md and auto memory, Cursor's rules, Windsurf's locally-scoped Cascade memories, GitHub Copilot's repository instructions, and Devin's Knowledge feature, and shows that most of what they persist is developer-authored instruction or a local, best-effort note rather than structural memory of the code itself. Three concrete scenes carry the argument: an agent re-litigating a settled architecture decision, re-discovering the same dangerous file, and re-breaking an agreed convention, each tied to a specific, named cost: repeated onboarding, inconsistent output, and tokens spent re-deriving known facts. The load-bearing distinction is chat transcript versus structural graph, probabilistic recall of a conversation versus a deterministic parse of the code, and the claims made about Spiderbrain are scoped narrowly to that one property, persistence across sessions and machines, rather than a general claim of superiority over any named tool.

Comments

Leave a comment

Your email won't be published. Comments are reviewed before they appear.
★ Read next