Ask an agent what it remembers about your codebase and you are really asking what it remembers about your conversations. Nearly every memory system shipped with a coding agent today is keyed to the chat: what was said, when, in which session. That is a reasonable model for a chat product. It is the wrong model for a codebase.
Code does not care when something was said. It cares where. A constraint on a retry loop belongs to that retry loop, not to the Tuesday afternoon someone happened to explain it. When the knowledge is filed under the conversation, the only way back to it is to have had the conversation, and the next agent, or the next teammate, did not.
What an address buys
Memkith keys every memory to the code it concerns: files, functions, lines. The address is the retrieval path. When an agent is about to touch a file, the question is not "what have we talked about" but "what is known about the thing under edit", and that question has a precise answer.
This sounds like a small indexing decision. It changes three things that matter.
First, relevance stops being a guess. A conversation-keyed store has to infer that a chat from three weeks ago bears on today's diff. An address-keyed store does not infer anything: the memory names the file, the diff touches the file, done.
Second, memory survives the person. The teammate who worked through a workaround leaves the workaround addressed to the function it protects. Anyone who arrives at that function later, human or agent, arrives at the reasoning too.
Third, staleness becomes detectable. When the code a memory points at is deleted or rewritten, the memory has a broken address, and a broken address is a signal you can act on. A stale chat log just sits there, confidently wrong.
The unit is a fact, not a transcript
An address wants a small payload. A transcript is a poor thing to attach to a line of code; what belongs there is the distilled fact. One decision, one constraint, one failed attempt, with enough of the why that a reader does not re-litigate it.
This is the second half of the model. Storage keyed to code, and units shaped like facts. The two reinforce each other: a fact is small enough to be scoped precisely, and a precise scope keeps the fact findable without search gymnastics.
Where the boundary comes from
Once memory has an address, visibility has an obvious rule to follow: the same one the code already has. Locally, Git and branch scope define what is in view. In a team, the repository's own permissions decide who can read what. Memory does not need its own access model; it inherits one that every engineering team has already agreed to.
That inheritance is the part of the design we are least willing to trade away. A memory layer with its own permission system is a second thing to administrate and a second place to make a mistake. A memory layer that follows the code's permissions is invisible in the best sense: the boundary is wherever you already put it.
What this is not
Code-addressed memory is not a documentation generator, and it is not a search index over your repo. Both of those describe the code as it is. Memory holds the part the code cannot say about itself: why it is this way, what was tried and rejected, which constraint is real and which is habit.
It is also not a bigger context window. Stuffing more history into a prompt raises the odds the relevant fact is present somewhere; addressing the fact to the code makes its presence a lookup rather than a lottery.
The test we hold ourselves to is simple to state. An agent opening a file should arrive already knowing what the team knows about that file, and nothing it does not need. Addresses are how both halves of that sentence become possible at once.