Skip to content

Nowhere to Put the Disagreement: What a Memory Response Cannot Say

TL;DR

  • A memory API returns items with scores. It cannot express relations: superseded by, retracted, no longer governing.
  • So a store that knows about a conflict still flattens it, and similarity silently performs conflict resolution.
  • The word "update" hides three different operations: supersession, correction, invalidation. A typical store has one verb for all three, or none. Mnemoverse has none.
  • Fixing this is not a new column. It changes the response type, and it moves the hard question from ranking to budget allocation.

Ask a memory system which database production uses, and it can return two records that flatly contradict each other, each carrying a confident similarity score, and nothing else. Ken Alger opened his piece on this with exactly that shape: PostgreSQL at 0.94, MongoDB at 0.91, and a migration four months ago that neither number knows anything about.

He wrote it from the interface side. This is the same problem from the store side, and the uncomfortable part is that a store can hold everything it needs to see the conflict — both records, both timestamps — and still return it flattened.

Why does a memory store return a contradiction without saying so?

Because the response has nowhere to put it.

A memory API returns a list of items with scores. That shape can express "here are five things, sorted by how well they match". It cannot express "these two are in conflict", "this one was superseded by that one", or "this is still true but no longer governs". Those are relations between records, and a flat list has no field for a relation.

So even a store that tracked the conflict will flatten it on the way out. The agent sees two ordinary hits, takes the top one, and 0.94 beating 0.91 quietly becomes conflict resolution, performed by a number that was never asked to adjudicate anything.

This is not a defect in anyone's ranker. It is a type problem, and the fix is not a new field on an item. It is a response that carries edges as well as items.

What are the three operations hiding inside "update"?

This decomposition belongs to Ken Alger, from the exchange that produced both articles:

  • Supersession: this was true, and now this other thing is. The world changed.
  • Correction: this was never true. The record was wrong, and it was load-bearing for whatever happened while it was believed.
  • Invalidation: this is accepted as true and no longer governs. Not a claim about the world at all.

At the storage layer all three look identical, because all three end up writing a value. They diverge the moment anyone audits. Supersession keeps the past explicable. Correction says the past was built on something false, which is a different and more expensive fact. Invalidation is not a truth claim: a record can be accurate and still stop being the thing that decides.

A typical store has one verb for all three, or none. Ours has none, and our own changelog says so: there is no update verb, so a correction that is admitted at all lands as a second record beside its target. Two entries, two timestamps, and no relation between them. The store cannot distinguish "never true" from "no longer true" — the columns that could hold that difference landed in August 2026, dark by design, and no code path reads or writes them yet.

Why can't you just add relationships to the response?

Because of a bootstrapping problem underneath the interface question.

To know whether a supersession edge is worth carrying, you have to already be holding the record it supersedes. So hydrating relations cannot be a filter applied after the top-k cut. It has to influence which candidates are considered in the first place, which means relations must be visible before ranking rather than after it.

That turns a ranking problem into an allocation problem. Once a response can carry facts, relations, authority, and prior decisions, something has to decide what gets dropped when they do not all fit in the context budget. Ken Alger's two examples from that exchange are exactly the shape of it: a lower-scoring authority edge can matter more than the next highly relevant fact, and dropping a supersession relation changes the meaning of the records that survive it. Top-k knows none of this, because top-k knows one number.

Ranked lists are impoverished. They are also cheap, and whatever replaces them inherits a harder question than the one it solved.

What identity does a disagreement need?

If a decision made today is to be findable when the same disagreement returns, the disagreement needs a durable identity of its own.

The obvious move is to key it on the pair: A conflicts with B. That breaks. As soon as a third record arrives, A-conflicts-with-B is no longer the same object, and yesterday's decision points at a conflict that no longer exists in that shape. Key it on the subject the records argue about, and the identity survives however many records accumulate under it. The participants change. The disputed thing does not.

Stores key on the atom. We have not yet found one that keys on the question the atoms are arguing about.

Who is allowed to promote a memory, and who can revoke it?

A response honest about conflict needs a write path that knows who decided what. The shape below came out of a public thread, and the pieces belong to the people who named them there:

  • A promotion boundary on the way in (Max Quimby), so an episode cannot graduate into policy silently. Policy is expensive to change by design and should be expensive to create.
  • A named revoker on the way out (Reid Marlow), so stale policy cannot survive on sounding official.
  • An acceptance step between them (joinwell52), with scope and supersession kept as separate fields rather than folded together.
  • Trust provenance in the promotion rule (Suny Choudhary), because ten consistent episodes from untrusted documents should not outweigh one reviewed decision. Without it, memory poisoning becomes a promotion attack rather than a retrieval one.
  • No self-promotion (anassBld): two corroborating tool outputs are not authority, and an agent promoting its own episodes is how a hallucination hardens into a permanent truth.

None of that is better ranking. It is governance on the write path and honesty on the read path about which record governs and on whose authority.

Notice what the list is not: it does not rank sources. Every piece of it is authority made explicit and reviewable — a named rule, a named revoker, a visible acceptance — instead of authority hidden inside a scoring function. That is a smaller thing to defend, and a much easier thing to audit.

One thing worth stating plainly for anyone building it: authority is not a score. Collapsing trust, recency, validity, and usefulness into a single number produces a system nobody can explain, because once they are one number you cannot ask which of them decided.

What happens to a decision that is never recorded?

Handing the contradiction back to the agent only closes the gap if the choice the agent then makes is recorded too. Mike Czerwinski put it best in the thread: otherwise "silent resolution just relocates from the store to the inference step, same bug at a different address, and now it's harder to find because the store looks honest."

This is not hypothetical. Tae Kim, working on trade data, described the same company resolving to different nodes depending on whether the question was asked before or after an acquisition. Time ranges on the relations helped, and both versions started reaching the reasoning layer. What stayed broken was that the agent's choice between them vanished without a trace. They began writing those choices back as events, and the reason was not architectural taste: a client asked about a strange output and there was nothing to point at.

There is a caution about where that record lives, and the same thread supplied the evidence for it. Giulio D'Erme counted his own corpus after reading an earlier article in this series: zero of 152 memos and zero of 59 documents carried a validity window or a supersession edge. His engine could read those fields. Nothing was writing them.

A schema nobody writes to is shelfware, and a decision log that sits beside memory, outside the retrieval path, ends up the same way: readable, unread, technically shipped. If the next agent cannot retrieve the earlier decision at the moment the same conflict returns, what you have built is an audit artifact, not memory.

What would a response that carries disagreement look like?

Not a list. Closer to this shape, where the conflict is an addressable object and the records hang off it:

json
{
  "subject": "production-database",
  "conflict": {
    "id": "cf_7fa2",
    "status": "unresolved_by_store",
    "records": [
      {"id": "m_101", "content": "Production uses PostgreSQL.",
       "valid_from": "2025-11-02", "valid_to": "2026-04-18",
       "status": "superseded_by:m_244", "source": "adr-014"},
      {"id": "m_244", "content": "Production uses MongoDB.",
       "valid_from": "2026-04-18", "valid_to": null,
       "status": "active", "source": "adr-031", "accepted_by": "platform-team"}
    ]
  },
  "prior_decisions": [
    {"conflict": "cf_7fa2", "chose": "m_244",
     "authority": "adr-031", "at": "2026-05-06"}
  ]
}

Three things are true of that shape and false of a ranked list. The conflict has an identity, so a decision can reference it. The relation between the records is carried rather than implied by order. And the reason one record governs is a field rather than a side effect of a score.

We do not ship that. In a personal domain, what we ship today decides admission with a novelty check against the nearest existing memory — we even named it an importance gate, and the name has outlived the accuracy. It measures neither trust nor importance, and it has a failure mode documented in our own changelog: a correction is phrased almost exactly like the thing it corrects, so it scores as a near duplicate, so it is the input most likely to be rejected. The stale record then survives as the only one on that subject and looks more authoritative than it did before anyone tried to fix it.

Three checks are worth running against any memory system, including this one. Store a fact, contradict it, and list everything the system holds on that subject. Submit a correction phrased like the original and see whether it survives the write path. Then ask what the response can express beyond a score.

Common questions

Why does a memory API return contradictory results without flagging them?

Because the response type has no field for a relation. A memory API returns a list of items with scores, which can express "here are five things, sorted by match quality" but cannot express "these two are in conflict" or "this one was superseded by that one". Even a store that tracked the conflict flattens it on the way out, and the higher similarity score silently performs the conflict resolution.

What is the difference between supersession, correction, and invalidation?

Supersession means this was true and now something else is: the world changed. Correction means this was never true: the record was wrong while it was still being used to make decisions. Invalidation means this is accepted as true and no longer governs, which is not a claim about the world at all. At the storage layer all three look like writing a value. They differ the moment anyone audits.

Can you add relationships to a retrieval response after ranking?

Not reliably. To know whether a supersession edge matters, you have to already hold the record it supersedes, so relations have to influence which candidates are considered rather than filter what survived the top-k cut. That turns a ranking problem into a budget allocation problem, because facts, relations, authority, and prior decisions compete for the same context window.

How should a stored conflict be identified?

By the subject the records disagree about, not by the pair of records. A pair is unstable: when a third record arrives, the A-conflicts-with-B object is no longer the same thing, and any earlier decision now points at a conflict that does not exist in that shape. Keying on the disputed subject keeps prior decisions addressable as records accumulate.

Why is authority not just another score?

Because collapsing trust, recency, validity, and usefulness into one number makes the system unexplainable. Once they are a single score you cannot ask which of them decided. A record can be true and still not be the one that governs, and that distinction disappears the moment it is expressed as a rank.

Sources

  • Alger, K. (2026). Your Memory API Is Lying to Your Agent. The same problem from the interface side, and the source of the supersession, correction, and invalidation split used above. dev.to/kenwalger
  • Discussion under Agent Memory: Everything It Remembers Has the Same Authority, and That Is the Bug, 2026-08-19 to 2026-08-21. The write-path shape above belongs to the engineers credited inline: Max Quimby (promotion boundary), Reid Marlow (named revoker), joinwell52 (acceptance step), Suny Choudhary (trust provenance), anassBld (no self-promotion), Mike Czerwinski and Tae Kim (the resolution log and the trade-data account), Giulio D'Erme (the 152/59 corpus count).
  • Mnemoverse changelog, 0.8.1 (2026-08-09): no update verb, and the write-path novelty gate rejecting corrections as near duplicates. CHANGELOG.md

— Edward Izgorodin · Last updated 2026-08-22

— Mnemoverse is a persistent-memory API for AI agents. Free key: console.mnemoverse.com · Docs: Getting Started