Accountable agent memory. The layered memory and hybrid retrieval agents expect, plus the three things no other memory system ships: every memory carries its provenance, every recall reproduces its ranking, and every stale memory flags its own drift.
Install today (PyPI release imminent):
pip install git+https://github.com/HarperZ9/mneme.gitZero runtime dependencies · fully local · deterministic · MIT.
Agent memory systems store facts and hand them back. None of them can answer two questions a serious deployment must ask:
- Why did you recall this memory? Their ranking is a black box.
- Is this memory still true to its source? They keep a fact after its source changed and you find out when the agent acts on stale information.
mneme answers both, because every operation emits a re-checkable receipt.
L0 turn raw dialogue -> stored verbatim
L1 atom atomic user facts -> extracted, each bound to its turn
L2 scenario scene blocks of related atoms
L3 persona the user profile -> synthesized, citing its atoms
Retrieval is hybrid: BM25 (pure Python, always on) fused with an optional embedding channel by Reciprocal Rank Fusion: the same keyword / semantic / hybrid surface the leaders offer, with no required embedding API.
A recall you can re-derive. Every recall returns a receipt with the ranked
hits, their BM25 and vector scores, and the exact fusion rule. And verify_recall
ships the check: it re-runs the scorer over the same rows and confirms the ranking,
so a fabricated or tampered recall is caught even if its definition hash still
matches, and a store that changed no longer reproduces. The recall is auditable by a
function you can put in CI, not a claim you take on faith.
from mneme import recall, verify_recall
r = recall("deploy steps", rows, strategy="hybrid", embedder=embed)
assert verify_recall(r, rows, embedder=embed) # re-derived from the store, not trustedmneme remember alice session.json
mneme recall "where does the user live" --json
# -> {"schema":"mneme.recall/1","hits":[{"memory_id":"…","bm25":2.14,"fused":…}],
# "recheck":"mneme recall --query Q --state DB (re-run the scorer, reproduce the ranking)"}A memory that flags its own staleness. drift re-derives every memory's
grounding against the current store: MATCH (source present and unchanged),
DRIFT (a source changed under the memory), UNVERIFIABLE (a source is gone).
mneme drift # -> {"overall":"DRIFT","drifted":["…"], …} exit 1 on driftProvenance on every memory. Every atom names the turn it came from, the extractor, the criterion, and a content hash. The persona is not free text: it cites its atoms, so it is drift-checkable too.
from mneme import AgentMemory
mem = AgentMemory("mem.db") # or ":memory:"
mem.remember("alice", [{"role": "user", "text": "I live in Denver and love dark roast."}])
receipt = mem.recall("coffee preference") # RecallReceipt, re-derivable
print(mem.drift()["overall"]) # MATCH until a source changesAn embedder (AgentMemory(..., embedder=fn)) turns on the vector channel; an
LLM Extractor plugs in for richer atoms. Neither is required: the
deterministic floor works with no model and no API.
Point mneme at an accountable intake tool (gather, the sibling flagship) and the provenance chains end to end, something no single-purpose memory library can do:
web url --(gather sha256)--> mneme turn --> mneme atom --> recall
mneme ingest research items.json # gather-shaped {id,text,source,ref,method,sha256}
mneme recall "where is the user based"
mneme chain <memory_id> # -> the web url + content hash it came fromAn agent that remembers what it researched, and can prove a recalled memory
traces to the exact bytes fetched from the exact source (re-fetch the ref, re-hash, confirm it equals the origin sha256). Any intake tool that emits that
shape composes; mneme never imports gather.
And the loop closes at the other end. mneme to-crucible emits a schema-v2
crucible export: each memory is a claim
paired with Mneme's source-bound drift measurement. Crucible independently
recomputes and seals MATCH, DRIFT, or UNVERIFIABLE from that measurement.
Each exported measurement now carries a declarative mneme.recheck/1
descriptor. After Crucible writes an assessment-bound replay template, Mneme
can re-read the supplied state and fill its replay pack without importing
Crucible or embedding a database path or executable command in the descriptor:
crucible recheck REGISTRY --template replay-template.json
mneme --state mneme.db replay-crucible replay-template.json --out replay-pack.json
crucible recheck REGISTRY --pack replay-pack.json --jsonThe replay command fails closed when the assessment triple, claim binding,
descriptor, original measurement contract, or target memory grounding differs.
Ordinary source drift remains a replay result (1.0); a missing source remains
unverifiable (null). Crucible still does not independently re-read Mneme's
source—the source recheck is Mneme-owned and Crucible verifies that the replayed
measurement exactly reproduces its sealed contract.
The command consumes crucible.replay-template/1, opens the supplied SQLite
state read-only, verifies and preserves the compact descriptor-only
crucible.replay-set/1 binding, and emits crucible.replay-pack/1. The binding
records descriptor and skipped-row counts without disclosing descriptorless
assessment rows. Historical schema-less templates remain compatible only when
they have no replay binding and their complete measurement seal reproduces;
bound templates require the canonical schema. Read-only schema compatibility is
checked without migration, and a completed, synced pack is published atomically
without overwriting an existing path. Malformed provenance is rejected before
descriptor or pack creation; replay never rewrites the evidence database.
gather (intake) --> mneme (drift + replay) --> crucible (sealed recomputation)
The export keeps measurement and assessment separate without claiming independent source certification.
Every memory system lets you delete a fact. mneme is the only one where the
deletion is auditable: forget and update leave a hash-chained tombstone,
what was forgotten, its hash, and why, so you cannot quietly forget that you
forgot something (required for GDPR-style "right to be forgotten" you can prove).
mneme forget <memory_id> --reason "user requested deletion"
mneme audit # -> {"entries":1,"chain_intact":true,"log":[{"op":"forget", …}]}update edits a memory's text while keeping its provenance and recording the
before/after hash. Tamper a tombstone and the chain breaks.
mneme mcp # JSON-RPC 2.0 over stdio; MNEME_STATE points at the DBTools: mneme.remember, mneme.recall, mneme.drift, mneme.provenance. A
recall through MCP returns the same re-derivable receipt, so the agent (or its
operator) can see and re-check why a memory was surfaced; the accountability
travels with the tool result.
The category is sold on one number: "N% fewer tokens." Everyone publishes the reduction; nobody proves the answer survived it. mneme measures both.
mneme bench
# token_reduction: 76.6% (full history 125 tok -> avg recalled 29 tok)
# answer_recall: 100% (5 probes, every needed fact survived the reduction)A reduction is only reported alongside its answer recall, so a number that
looks great by forgetting the answer is disqualified, not a win. The receipt
carries the per-probe detail and the exact token estimator, so a third party
re-runs the measurement over the same conversation and reproduces the number,
a benchmark you can escrow, not a marketing figure. Point it at your own
conversation with --turns convo.json --probes probes.json.
mneme scenarios alice # cluster the session's atoms into scene blocksAtoms sharing a theme cluster deterministically into L2 scenarios; each scenario
cites its atoms, so it is drift-checkable too (a scenario whose atom is gone is
UNVERIFIABLE, never silently kept).
- Zero runtime dependencies (stdlib
sqlite3).pytestis the only dev dep. - Deterministic. No wall clock or randomness enters a stored hash or a ranking; the same turns rebuild the same memory, byte for byte.
- Tests are the contract. Every behavior above ships with a falsifier.
MIT.
This tool is one lane of a family that holds a single belief steady across every surface: knowledge open to anyone who can attain the means; acceptance decided by external checks, never reputation; every result re-runnable; honest nulls first-class; ownership earned by comprehension; learning woven into the work. The full text lives in CREDO.md. The long form of this belief: The Unbundling.
Zentropy Labs · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at Project Telos.
