Memoosea dual-path memory system for proactive agents

Source on GitHub

Evidence & history

Finding a fact once is the easy half. The hard part is keeping a body of facts trustworthy for months, which is what these four mechanisms are for.

Memoose is built for long-lived project work, so the questions it has to answer are not needle lookups. They are: a fact changed, does recall return the current one? Two sources disagree, does the system say so? Why do we believe this? We solved this before, what did we learn? Each has a mechanism, and each mechanism is checked by a benchmark that needs no model.

Facts carry their evidence

Every relation can point at where it came from. The evidence field on a relation takes a file range like repo://src/auth.py#L40-L82, a URL, an issue id, or user said 2026-09-06, and the extraction skill requires one wherever the source supports it. valid_from and valid_to record when a fact became and stopped being true, when the source says.

The point is re-verification rather than trust: a later run can follow the pointer and check whether the claim still holds, instead of believing a sentence it has no way to audit. OpenWiki's grounded claims follow the same discipline.

Nothing true is deleted

When a fact changes, the old one is superseded, not removed. It leaves default recall, so the agent sees the current answer; it stays in the store, so history stays queryable.

For relations declared functional, meaning they hold a single current value per subject like owned_by or deployed_in, this happens on its own: assert a new value and declare_functional_relations makes the old one supersede automatically. Everywhere else, supersede(old, new, reason) records it explicitly, with the reason attached.

recall("who owns billing")                            # the current owner
recall("who owns billing", include_superseded=true)   # and who used to

forget exists, but it is for mistakes and for things that were never true. Anything that was true once should be superseded instead.

Disagreement is surfaced for a model to judge

Memoose never decides what conflicts. The store has no judgment and does not pretend to, but it does refuse to hide the problem. A remember that lands next to a fact it may contradict comes back with a hotspot warning; contradiction_candidates returns the facts around an entity grouped by subject, flagging where one subject holds several values for one relation; and recall marks facts contested so the agent reading them knows two sources disagree.

The judgment is the memoose-upkeep skill's job, and it comes down to one distinction: if the newer fact simply replaced the older one in time, supersede it; if both are asserted and cannot both be true, mark_contradiction records the disagreement with a reason and a confidence, and the contradicts edge stays visible.

An append-only provenance ledger

history is the audit trail: every create, merge, assert, supersede and forget, with its actor and its time. It is append-only, so it answers “when did we start believing this, and who told us?” even for facts that have since been replaced.

history(entity="billing-service")   # everything that ever happened to this entity
history(relation_id="rel_...")      # the life of one fact

This is also the honest answer to automatic capture: facts get written that nobody explicitly asked for, and history is how you find out what was written, by which actor, and when.

Lessons: we solved this before

A session's turns and typed context sections are distilled into lessons: one to three sentences that stand alone without the session, each with its own evidence and linked to the entities it applies to. They come back through recall in session mode, and through the standing context a session start puts in front of the agent, so the thing you learned last month arrives before you re-learn it.

How these are checked

Each of those four mechanisms is asserted on directly by the test suite, which runs with uv run pytest on every commit: it checks what the tools actually return rather than asking a model to grade prose.

What does not exist is a published benchmark that asks these questions of a memory system at all. Designing one other systems can run is on the roadmap; scoring ourselves on an eval of our own making would prove nothing, so we publish no number for it.

What we measured

LoCoMo is the standard benchmark for conversational memory: a model answers from whatever the memory system retrieves, and a second model grades the answer. Memoose scores 90.4 (95% CI 88.8–91.8) at 4,699 mean prompt tokens across all 1,540 questions, run under mem0’s protocol with their answerer and judge prompts verbatim.

By category: single-hop 93.5, temporal 89.7, multi-hop 88.7, open-domain 70.8. Open-domain is the weak one, where the gold answer is a name or a place living in a single turn that never reaches the retrieved context. The answerer and judge are both Claude Haiku 4.5, smaller than the models other published scores use, and swapping the answerer moves a score more than swapping the memory system does: read it as what Memoose does on a small model.

Two findings from those runs cut against us and are published anyway: the knowledge graph does not beat plain chunk retrieval there (paired McNemar p = 1.00) at 77% more tokens, and raising the retrieval budget does not lift the score. LoCoMo asks needle questions over conversations that fit in a context window, so chunk retrieval finds the needles and the answering model does the joining. It never asks whether a changed fact is still current, which is what this page is about.