Skip to content
Back to all field notes knowledge · 9 min

Product memory: what your team forgets and your system shouldn't

Teams don't forget the code. They forget the decisions, the reasons, and the dead ends. When nothing remembers those, you keep re-litigating settled questions and agents keep re-walking paths you already abandoned.

field note 9 min

Six months in, a team has a specific kind of amnesia. The code is all there, readable, running. What is gone is everything around it. Why did we split the service? Why is this field nullable when it obviously shouldn’t be? Didn’t we already try caching here and rip it out? Nobody remembers, or three people remember differently, and the person who actually decided left in the spring.

Teams don’t forget the code. The code is the one thing that survives, because it is the artifact everyone is forced to keep. What evaporates is the layer above it: the decisions, the reasons behind them, and the dead ends. That layer is product memory, and almost nothing in a normal setup is responsible for holding it.

The three things that get forgotten

The decisions. Not the outcome, which is visible in the code, but the fact that a choice was made at all. Someone decided to use this queue instead of that one, to make this endpoint synchronous, to cap retries at three. In the code it just looks like how things are. The decision, the moment where it could have gone another way, leaves no trace unless someone records it.

The reasons. This is the expensive one. The why is never visible in the code, because code is the result of a reason, not the reason itself. You can read that retries are capped at three. You cannot read that they are capped at three because the downstream provider throttled you at four and paged someone at 3am. Lose the reason and the decision looks arbitrary, which means the next person, or the next agent, will “fix” it and rediscover the 3am page.

The dead ends. The paths you tried and abandoned. The caching layer you built and removed because it caused stale reads. The library you evaluated and rejected. These are the most completely forgotten of all, because there is no code left to even hint they happened. The work was done, the lesson was learned, and then the evidence was deleted along with the branch. So the knowledge that “we already tried this and here’s why it failed” exists nowhere, and the team is doomed to try it again.

What it costs when nothing remembers

With a human team, forgotten memory shows up as re-litigation. The same debate about the same architecture, every few months, with no one able to point to why it was settled last time. Decisions get quietly reversed by people who never knew they were decisions. The product-brain rots and you feel it as a vague sense that the team keeps having the same conversations.

With agents, the cost is sharper and faster, because an agent has no memory at all beyond what you hand it. An agent does not know you already tried the caching approach and abandoned it. So when the task looks like it calls for caching, it builds the caching, confidently, walking straight back down the dead end you spent two weeks escaping. It reverses a decision because it never knew a decision was made. It “cleans up” the weird nullable field because nothing told it the field is weird on purpose. Every gap in product memory becomes a place where the agent does damage while behaving reasonably, because reasonable-given-no-memory is exactly the failure.

And this compounds with parallel agents. Each one starts fresh, so each one is equally capable of re-walking the same dead end, and they can do it simultaneously, in different parts of the codebase, all afternoon.

Memory has to attach to the thing it explains

The instinct is to write it down somewhere. A decisions doc, a wiki page, a channel where choices get announced. This is better than nothing and it degrades the same way every folder of notes degrades: it drifts from the code, nobody links it to anything, and six months later the decision record and the code it supposedly explains have no connection you can follow.

Product memory is only useful when it is attached to the thing it explains. A decision floating in a doc is trivia. The same decision linked to the exact code it governs, and to the code that got removed when a dead end was abandoned, is memory you can actually use. Now when an agent, or a person, looks at the retry logic, the reason it is capped at three is right there, attached to the retry logic, not buried in a doc from last year that nobody will find. When an agent considers building a cache, the record of the last cache and why it was removed is reachable from the place the cache would go.

That is the difference between an archive and a memory. An archive is where information goes to be forgotten in an organized way. A memory is knowledge attached to the context where it will actually be needed, which for a codebase means attached to the code, in a structure both people and agents can walk. It is the same reason a product knowledge graph links artifacts to code rather than storing them beside it, and the reason context for coding agents is about structure over prose: memory that isn’t attached to where it’s needed is memory that won’t be found in time.

The dead end is the most valuable memory and the one nothing keeps

Of the three, the dead end deserves special attention, because it is simultaneously the most useful memory and the one your tools are structurally designed to erase. When you abandon an approach, the normal thing is to delete the branch, revert the commits, close the PR. You clean up. And cleaning up is exactly the act of destroying the only record that the attempt happened. The code that would have hinted “someone went this way and turned back” is precisely the code you remove.

So the failure mode is guaranteed. There is no artifact left saying “we tried event sourcing here and abandoned it because the replay cost was untenable at our volume.” Six months later someone proposes event sourcing, fresh and enthusiastic, and there is nothing in the codebase to contradict them, because the evidence was tidied away. The team pays the two weeks again to relearn what it already knew.

For an agent this is worse, because the agent is the most enthusiastic re-proposer on the team. It has no scar tissue. It reads the current state, sees a problem that event sourcing would elegantly solve, and builds it, with no awareness that this exact idea was tried and failed for a concrete reason that still applies. The only thing that stops the loop is a memory of the dead end that outlives the deleted branch: a record, attached to the part of the system it concerns, saying this was tried, this is why it was dropped, and this is the constraint that made it fail. That is a thing you have to keep on purpose, because every default in your workflow is trying to throw it away.

Where PaellaDoc fits

This is a layer PaellaDoc holds on your machine. Decisions are recorded when they are made, with their reasons, and linked into the graph next to the code they govern. Abandoned approaches are captured as what they are, tried and rejected and why, so the dead end is remembered even after the branch is gone. When an agent works, that memory is reachable from the code it is about, so the agent stops reversing settled decisions and re-walking paths the team already escaped. The code was never the thing you forgot. This is the part your system should hold, so your team stops paying to relearn it.

What decision has your team re-litigated the most times, and where is the reason it was settled actually written down? Tell me on the forum.

↓ Download PaellaDoc · macOS

Frequently asked questions

What is product memory?

The layer above the code that a team forgets: the decisions that were made, the reasons behind them, and the dead ends you tried and abandoned. The code survives because everyone’s forced to keep it. That layer doesn’t, unless something is responsible for holding it, and in most setups nothing is.

Why does my team keep re-litigating the same decisions?

Because the reason a question was settled lives in someone’s head, and that person left in the spring or remembers it differently now. Without a record linked to the code it governs, a decision leaves no trace, so it looks arbitrary and gets quietly reversed by people who never knew it was a decision.

Why do coding agents rebuild approaches we already threw away?

Because an agent has no memory beyond what you hand it, and the deleted branch that proved the approach fails is exactly what your workflow tidied away. It sees a problem the abandoned approach would elegantly solve and builds it, confidently walking back down the dead end, because reasonable-given-no-memory is the failure.

Where should product memory live?

Attached to the thing it explains, not floating in a doc. A decision linked to the exact code it governs is memory you can use; the same decision in a wiki is trivia nobody finds. When the reason for a retry cap sits on the retry logic, a person or an agent reading that code sees it in time.