Skip to content

The evidence chain ​

Most memory systems store what you said. The questions that break them are when it stopped being true and where it came from. Those need a data model, not a bigger vector index.

A retrieved memory is not a floating string ​

It points at the turn that produced it:

evidence_id  = ev_fact:fact_6ada707b…
support      = "Can you recommend a good beach on Oahu that's not too crowded?"
predicate    = user wants a not-too-crowded beach on Oahu
entities     = location=Oahu | occasion=birthday
source       = session_40 / turn_10          ← the exact turn, not "some chat"
date         = 2023-05-25

The chain ​

FactEvent  ──▶  SourceSpan  ──▶  RawTurn
   the fact       the span of      the message
   we derived     text it came     as it was
                  from             actually sent

This is a foreign-key chain, not a similarity score. The difference shows up in two places:

  • When a user asks "why do you think that about me?" there is an answer, and it is the sentence they actually typed.
  • When compliance asks where a stored fact came from, there is a row — not a ranked list of things that were nearby in embedding space.

A key-value memory cannot produce this field no matter how good its retrieval is, because it never recorded the link in the first place.

Where you see it ​

surfacefield
Pythonblock.citations from build_context
HTTPretrieved_evidence[].source_trace_ids
MCPevery read tool returns the evidence ids
published benchmark artifactssodamem_lme_retrieved_context.json — 8,427 rows, 16.9 per question, none empty

Retrieval you can audit ​

Same query, same store, same result, every time. There is no sampling step in the default path, so a retrieval that surprised you can be reproduced exactly instead of argued about.

/v1/events records every add, supersede and delete with its reason, which makes "why did the agent forget X" answerable after the fact rather than a shrug. See HTTP API · events.

Next ​

Apache-2.0 licensed.