← Work

A memory architecture for a companion that remembers you between conversations

ProjectMemory for an AI companion
RoleSole author, systems design
DatesSeptember 2026
Statusdesign study, not shipped (17-page document, four figures, no code)
Stackdesign work; references Postgres and pgvector, background consolidation jobs, validity windows

An AI companion that talks to someone every day has one job memory has to get right: it must not make the person feel forgotten. I spent a stretch designing the memory system such a product should have. This is a design study, not a shipped system: a 17-page document with four figures and no code. I am putting it here because it shows a part of my range that the agent work does not, which is systems design under real constraints, grounded in both the research literature and the cognitive science.

The point of view

Memory, for a companion, is three promises:

  • You never have to tell me twice.
  • I never tell you twice.
  • I never surprise you with what I bring up.

Almost every failure users report is one of those three broken. The companion asks a question you answered last week. It repeats a story. It brings up something from a closed chapter of your life at the wrong moment. The research backs this up: being forgotten reads as "I don't matter," even when the person knows the cause is just forgetfulness, and users end up doing the repair work themselves.

The problem with how it is usually built

The common design stores facts. Every turn, an extractor pulls facts from what was said, embeds them, and later retrieves the closest ones. It works until a fact stops being true. "I'm dating Theo" and "Theo and I broke up" are both facts, both true when written, and a nearest-neighbor search will happily return the stale one months later. Storing more facts makes this worse, not better. The unit is wrong.

I surveyed six systems that are all wrestling with this: Mem0, OpenAI's background synthesis, Zep, Letta, Tolan, and Honcho. Each solves a piece. Nobody had the whole answer, and the gaps were consistent: staleness of high-relevance facts, change modeled as accumulation rather than evolution, and the read path recomputing expensive context on every single turn.

The idea

Threads, not facts, as the unit of memory. A thread is something in a person's life that is not over yet: a job search, a rough patch with a partner, training for a race. A thread has a state (open, dormant, closed), an expected date, and facts attached to it with validity windows, so a fact can stop being true without being deleted. The prompt is assembled from an identity block plus the handful of open threads, precomputed and cached, so the reply path never recomputes it and a timeout drops only the volatile part.

Closure has an authority order: the user can close a thread, a passed date plus a discussion can close it, and the background process can only ever mark a thread dormant, never closed. That last rule matters, because it keeps a human in authority over what the system decides is finished, which is exactly where an over-eager model does the most damage.

Why I trust the shape

I did not want this to be a clever data model that happens to feel right. Two lines of cognitive science say the shape is not arbitrary. Event segmentation theory says the brain holds a model of what is happening now and organizes memory around event boundaries, which is what open and closed threads are. Complementary learning systems and the consolidation-during-sleep literature say the brain fast-learns episodes and then slowly, offline, transforms them into gist, which is exactly the split between the live write path and the background synthesis job. The design borrows the architecture the brain already uses.

The discipline that made it a design and not a wish

The document separates physics from choices. Physics are the non-negotiable constraints: it runs over SMS, there is a hard reply-latency budget, memory degrades but is never erased, sensitive tiers never leak into the always-on profile, and a human authorizes every memory change. Choices are everything replaceable: Postgres and pgvector, the token budget, the retrieval formula. Naming which is which is what lets someone else build it without relitigating the parts that are fixed.

I costed it. Reply-path cost, batch cost, token budget, and what breaks at ten times the scale. And it ends on known unknowns, stated plainly: attach precision is unmeasured, the cap on open threads is itself a new cliff, and the auto-merge threshold goes further than a dry-run-only system would.

Why it is here

Every other project on this site is an agent that takes actions. This one is the layer underneath: what the agent is allowed to remember, and how it decides what is still true. It is the same instinct, applied to state instead of action. Boring, durable primitives, a human in authority over the irreversible decisions, and the honest gaps written down before anyone has to find them.