releasescoremem3 min read

CoreMem 0.14.0 — versioned memory, built on the validation era

Every default your memory system ships is a bet. We spent a release cycle measuring ours — then added tamper-evident governance on top of what survived.

Agents rewrite memory through LLMs, and vendors call that a feature. The problem with LLM-rewritten memory is you can never answer the most important question about it: what actually happened? CoreMem’s answer was always deterministic retrieval — and 0.14.0 extends determinism all the way to the history itself: versioned memory with a tamper-evident chain, opt-in, built on the HybridDB versioned tables that shipped days earlier.

But before we could add governance, we had to be sure the pipeline underneath was worth governing. That’s the untold half of this release.

The validation era (0.13.x)

Over three releases in August, everything that would become the default behavior was measured first — 500-question LongMemEval-S runs with a resumable harness, and honest verdicts:

  • 0.13.0 folded in the two improvements that survived scale: temporal query decomposition (+0.037 session recall on the 133 temporal questions) and preference union routing (+0.033 on preference questions). The default context bundles became 4k evidence-first — 0.678 answer accuracy versus 0.608 at 16k, with ~60% less context. And ingest_many got 4.3× faster, because a memory layer you can’t fill quickly is one you won’t fill.
  • 0.13.1 gave agents the hygiene API they were missing: list_sessions(), delete_messages(), stats(), close() — and the MCP server grew to 8 tools, because the fastest integration is the one already in your agent runtime.
  • 0.13.2 was the bug hunt release: filters now honored by every strategy (preference queries, session_cap, fusion no longer leak other sessions’ messages), ingest() returns the turn_id it actually stored, use-after-close raises instead of corrupting silently. Twelve regression tests, suite at 175 passing.
  • 0.13.4 swapped the default embedder to bge-small (+0.010 message recall on full S). Small numbers, measured, shipped.

The composition lesson hung over all of it: individually-positive improvements don’t always sum — the L-12 reranker we’d validated on one subset cancelled the temporal win on another. The default ships only the combination that survived the full 500/500 test.

Then: versioned memory

With a pipeline we trusted, 0.14.0 made memory provable:

  • MemoryCore(path, versioned=True, author=...) — new stores only. Messages and journal records join a SHA256(prev_hash | op | pk | row_json) chain. (No in-place migration in v1 — versioning is a create-time commitment, and we’d rather say that plainly than pretend legacy stores can be retrofitted safely.)
  • The governance API: checkpoint_memory(label), rollback_memory(...) — which records the rewind as new versions instead of erasing it; memory_history(id) as a provenance timeline; memory_diff, as_of_memory, verify_memory_chain().
  • MCP tools for the operators: memory_history, memory_rollback (refuses without confirm=true), memory_verify — because an audit trail nobody can query might as well not exist.
  • The perf gate, measured the same way everything else was: +8.2% ingest overhead (budget ≤15%), recall latency unchanged, storage 1.13×.

That gate is the punchline: versioned memory passed the same kind of measurement that rejected our favorite reranker. The release that flips it to default was already greenlit that day.

More on the methodology: half our experiments failed — and why that’s the feature.