klar labs Products Open Source Writing Products Open Source Writing Writing · July 4, 2026 · 7 min read

From store to brain

A memory library that only writes and reads is missing the interesting half. What building the other half — consolidation, forgetting, salience, self-correcting recall, and metacognition — taught us, with no language model in the loop.

AIMemorySystemsEngineering

Mnemos started as an evidence layer: typed claims, each linked back to the source event that produced it, with contradictions surfaced instead of silently overwritten. That part is useful on its own. But the longer we ran it, the more it looked like a store — something you write to and read from — and less like a memory, which is something that also changes on its own between the writes and the reads.

A brain does not just record and recall. While you sleep it consolidates the day into gist, forgets what did not matter, and quietly strengthens what did. At encoding it tags some things as important and lets others fade. At retrieval it notices when it comes up short and looks again. And it flags, loudly, when new evidence contradicts something you were sure of. We spent a stretch building those processes into Mnemos. Here is what we learned — including the parts we got wrong first.

A store holds. A memory works. A store holds. A memory works. The same write and read — the difference is everything in between. STORE write bytes on disk read MEMORY write encode · consolidate · forget · retrieve · reflect continuous background processes — deterministic, no LLM read what it recalls tomorrow depends on the work it did overnight

A store keeps bytes between a write and a read. A memory runs continuous processes in between — so what it recalls tomorrow depends on the work it did overnight.

A store is not a memory system

The most useful realisation came early and was slightly humbling: most of the organs of a memory system were already in the codebase, just never wired to run on their own. Trust scoring with half-life decay was there, but only computed at query time. A consolidation routine existed, but as a manual command. A bias-detection pass existed, but ran on demand. Temporal pattern detection was computed and then never read.

The lever, over and over, was not "build a new capability" — it was "take the capability you have and make it a process." Schedule the consolidation. Read the temporal signals into the recall path. Turn the one-shot bias check into a standing alert. If you are building a memory system, audit what you already compute and throw away before you add anything new.

Forgetting is reduced retrievability, not deletion

Forgetting sounds destructive, so it is worth being precise. In Mnemos a forgotten claim is invalidated, not erased: we close its valid-time. Recall stops surfacing it, but the claim and its full history stay in the store — a point-in-time query still shows what was once believed. Forgetting is a drop in retrievability, not a delete. Human-promoted knowledge is never forgotten at all.

This is also where we shipped a bug and learned something. Our first forget implementation marked claims deprecated by status. It looked right and did nothing — the forgotten claims kept showing up in recall. The reason: recall filters by valid-time, not by status. Deprecating a claim changed a field nothing downstream read. Closing its validity was what actually removed it from results.

Before you build forgetting, know exactly what your retrieval path filters on. Ours filtered on valid-time; we spent an afternoon changing a field that recall never looked at.

The bi-temporal model — separate axes for when a fact was true and when it was recorded — is what makes forgetting safe rather than lossy. You can prune aggressively because nothing is gone; it is only no longer current.

Trust and importance are different axes

We nearly conflated two things that need to stay separate. Trust answers "is this still true?" and it decays — an unverified claim gets less trustworthy as its evidence ages. Salience answers "does this matter enough to keep, even if I rarely recall it?" and it does not decay. A Sev-1 post-mortem is important the day it is written and important a year later, regardless of how fresh the evidence is.

If forgetting keys only on decayed trust, you forget the consequential-but-old — exactly the memories you most want to keep. So salience is a separate, write-time score, computed from signals already on the claim: confidence, how much independent evidence corroborates it, its kind (a decision or a verified test result outweighs a passing remark), source authority. The consolidation pass protects anything sufficiently salient from being forgotten, and prunes only the mundane tail. It is the rule-based analog of the poignancy score other systems ask a language model for — and it costs nothing to compute.

Trust decays, salience does not Trust decays. Salience does not. Two different axes — and why forgetting has to consult both. trust — decays as the evidence ages salience — never decays age of the claim → score forget floor Below the floor, an ordinary claim is dropped — but a salient one is kept, however old.

Trust decays with the age of the evidence; salience does not. Forgetting looks at both — so an old, unverified aside is pruned while an old, consequential decision is kept.

For hybrid search, fuse ranks, not scores

Embedding similarity has a systematic blind spot: exact tokens. A commit SHA, a service name, an error code, a flag — cosine blurs these, because they carry little semantic weight. So a query for a specific identifier can miss the one event that contains it, even with a perfectly good embedder.

The fix is hybrid retrieval — run a sparse full-text leg alongside the dense vector leg — but the interesting part is the fusion. The two legs produce incomparable scores: cosine distance and a full-text rank are on different scales, and normalising them is guesswork. Reciprocal Rank Fusion sidesteps this entirely by consuming only ranks.

score(result) = Σ  1 / (k + rank_in_leg)      # k ≈ 60, summed over the legs it appears in
Reciprocal Rank Fusion: no score calibration, only ranks.

No calibration, no tuning, and a result that ranks well in both legs naturally beats one that tops a single leg. It is a two-line idea that removed a whole category of "how do we weight these" bikeshedding.

Self-correction has to be bounded and non-regressive

When a recall comes back weak — no claims, or low aggregate confidence — the obvious move is to look again: widen the search, relax a filter. But "look again" is how you build an unbounded loop that blows a latency budget, and how you accidentally return a worse answer than the one you had.

Two constraints kept it honest. First, bounded: exactly one corrective pass, ever — structurally, not by a timeout. One retry respects a tool-call budget without any deadline plumbing. Second, non-regressive: the corrective answer only replaces the first one if it is strictly better (more claims, or higher confidence), and it never trades a real answer for an empty one. A self-correcting step that can make things worse is a liability; make it provably unable to.

And relax the right filters. We widen the corpus and drop the soft trust floor, but we never touch the semantic filters — scope, visibility, point-in-time. Loosening those would return results the caller explicitly excluded, which is not recovering recall, it is answering a different question.

Metacognition: surface the contradictions that matter

Contradiction detection is table stakes; the metacognitive move is knowing which contradictions deserve a human. When new evidence contradicts a claim nobody vetted, that is ordinary churn. When it contradicts an established belief — one a human promoted, or one that earned high trust — that is the event worth attention: either a settled belief is now wrong, or the new claim is suspect. Mnemos surfaces exactly those, most-established-first.

Resolving one taught us the valid-time-versus-status lesson a second time. Retiring a claim means transitioning it to superseded — but that sets a lifecycle field, and our alert query filtered on valid-time, so resolving a conflict left the alert standing. The fix was to make the alert query also treat a superseded side as resolved. Same shape of bug as forgetting: a write that changes a field the read never consults does nothing you can see. It is worth writing down which field each query keys on, and checking every mutation against it.

The constraint that shaped all of it: no model in the loop

Every one of these runs with no language model. Salience is a weighting rule, not an LLM importance rating. Consolidation is embedding similarity plus deterministic merges. Contradiction detection is rule-based across polarity, numeric, entity, and temporal axes. That was a deliberate constraint, and it did more to shape the design than any feature decision.

Determinism means the memory layer is self-hostable, reproducible, and free to run — no per-operation billing on your own recall, no data leaving your infrastructure, no third service to be down at 3 a.m. It also forces a certain honesty: you cannot hand-wave that the model will figure out what is important. You have to say, in code, what important means. Writing those rules down turned out to be clarifying rather than limiting.

We leaned on neuroscience for the shape of it — complementary learning systems for the hippocampus-to-neocortex consolidation, synaptic renormalisation for the pruning of weak traces, salience gating for write-time importance, the hypercorrection effect for the intuition that high-confidence errors correct hardest — and cross-checked each against how leading agent-memory systems approach the same problems. But the implementations are boring on purpose: SQL, rank fusion, a scheduled job. A brain worth of behaviour does not require a brain worth of magic.

Mnemos is open source

MIT-licensed, a single Go binary, and it runs entirely on your infrastructure. The cognitive layer described here — consolidation, forgetting, salience, hybrid and corrective retrieval, hypercorrection — is all in the box.

View Mnemos on GitHub
← All writing