There's a question every developer building with agent memory eventually asks, usually around month three, usually at an inconvenient hour:
Where do my memories actually live, and what happens if I need them somewhere else?
It never arrives as a design review. It arrives as an incident. A framework ships a breaking change. Your embedding model gets deprecated. A second agent needs the ninety days of context the first one accumulated. Someone asks for a list of everything the system currently believes about a named user.
You go looking. You find a table of vectors keyed to a model version you already moved off, a JSON dump of raw turns, and extraction rules that lived inside a prompt.
This post is the test I'd run before you get there, and the reasoning behind it.
Table of contents
- The debate is about reading
- Memory is a write problem: five decisions no index makes
- Three tiers of export
- The embedding trap
- The fleet makes it worse
- What OKF gets right
- Where OKF stops
- The round-trip test
- The full checklist
The debate is about reading
Since Google Cloud published the Open Knowledge Format in June, everything has been OKF vs RAG. Curated markdown for authoritative facts, retrieval for the sprawling archive.
There's real work in there. Satvik Singh benchmarked curated docs against a knowledge graph, BM25 retrieval, and plain agentic grep across twelve on-call questions on two production services, and found that question type picked the winner rather than tooling ideology — grep took every code-detail question, curated docs took every architecture question, and every retrieval win was the retriever surfacing chunks of the curated docs.
But every entry in this debate starts from a corpus that already exists and asks how to find the right part of it.
That's a reading problem. Memory is a writing problem that later becomes a reading problem, and nearly all the difficulty is upstream of retrieval.
Memory is a write problem
A document is authored once and read many times. A memory is never authored at all — it accretes sideways, out of interactions that were about something else.
That produces five decisions no index makes for you.
1. Salience. Of 400 turns this week, which mattered? Most implementations answer with a heuristic:
# the shape almost everyone starts with
if turn_count % 10 == 0:
summary = llm.summarize(recent_turns)
store.write(summary)
That heuristic is your quality ceiling. Keep too much and you've rebuilt the transcript with extra steps. Keep too little and the agent is confidently amnesiac about the one thing that mattered.
2. Supersession. In March the user lives in Toronto. In June they mention Berlin. That's not two facts — it's one fact with a history:
# what you usually get
[
{"fact": "user lives in Toronto", "ts": "2026-03-04"},
{"fact": "user lives in Berlin", "ts": "2026-06-19"},
]
# both retrievable, both scored, nothing encoding that one replaced the other
Now do it for a fact asserted by three agents across three sessions, two of which were wrong.
3. Consolidation. "frustrated by the export flow on Tuesday" is an event. "cares about export fidelity" is a memory. The promotion between them is a judgment call, made continuously, on evidence that arrives in pieces.
4. Provenance and time. Who asserted it, when, on what basis, whether it expires. Without those fields you can't reconcile, can't audit, can't honor a deletion request, and can't distinguish staleness from disagreement.
5. Forgetting. Least discussed, most legally consequential. A memory system that can't forget cleanly is a compliance problem wearing a feature's clothes.
Every one is a decision, not a lookup and not a similarity score. That's why memory is an agentic problem rather than a retrieval one — and why the answer keeps looking like infrastructure when it's actually behavior.
Three tiers of export
Ask any memory product for an export and you'll get something. The useful question is which of three things.
| Tier | What you get | What it costs you |
|---|---|---|
| Bytes | Tarball of raw turns, vendor-shaped | Re-run your whole extraction pipeline. That's a rebuild, not a migration. |
| Schema | Structured records with mappable fields | You can write an importer, but you can't recover why a record exists |
| Semantics | Memories as memories: provenance, time bounds, supersession chain | Nothing — this is the tier where "portable" means what it sounds like |
Almost everything on the market ships tier one and markets tier three.
The embedding trap
Worth calling out on its own, because it's subtle and expensive.
If the durable form of your memory is an embedding, your memory is bound to an embedding model.
# this is not a format conversion
$ ./migrate.sh --re-embed --model text-embedding-v3
✓ 148,291 memories re-embedded
✓ 0 errors
Zero errors, and retrieval quality has silently changed. Re-embedding is a lossy re-derivation whose failures are invisible — nothing throws, recall just degrades in ways that show up as vibes three weeks later.
Vectors are a cache. Treating a cache as your system of record is exactly how you end up unable to leave.
The fleet makes it worse
The single-agent version is annoying. The fleet version is the one that costs money.
Real deployments end up with several agents against the same memory estate — one in the IDE, one on support tickets, one doing analysis, one running scheduled work nobody has reviewed in a month. Each learns things, into its own store, in its own shape, under its own rules.
So you get divergence with no reconciliation mechanism, because reconciliation was never a cross-agent operation to begin with. The user corrects the support agent; the coding agent believes the old thing indefinitely.
Singh's framing lands hard here: derived layers are caches without a TTL. His knowledge graph, built five days earlier, scored 0/3 on a two-week-old feature sitting in the working tree it was derived from. The curated docs had zero coverage of the same feature. Neither artifact signals that it's behind.
Multiply that by every agent you run, each derived independently, each lagging on its own schedule.
What OKF gets right
Worth being precise, because the format is less than the hype and considerably more useful than the skepticism.
OKF v0.1 was published by Google Cloud's Data Cloud team on June 12, 2026. A bundle is a directory of markdown files with YAML frontmatter, one concept per file, cross-linked. Exactly one field is required (type). No runtime, no SDK, no registry, no account. It renders on GitHub, ships as a tarball, mounts on any filesystem.
A memory expressed in that shape looks roughly like this — type is the spec requirement, the rest are conventional or extension fields:
---
type: preference
title: "Export fidelity"
description: "User consistently prioritizes lossless export over speed."
timestamp: 2026-07-14T09:22:00Z
tags: [product, ux]
# extension fields carrying the memory semantics
asserted_by: support-agent
evidence: [session:8813#turn42, session:9002#turn17]
supersedes: null
confidence: 0.86
expires: null
---
# Export fidelity
Raised in three separate sessions between May and July. In each case the user
declined a faster path that would have dropped metadata.
## Related
- [Export flow friction](export-flow-friction.md)
- [Account: workspace tier](workspace-tier.md)
For the ownership problem, the properties are exactly right:
- A human can read it at 3am. During an incident that's the difference between checking what the system believes and guessing.
- Git already knows what to do with it. Diffs, blame, PRs, review. Curation becomes a reviewable change rather than an opaque mutation.
- It outlives your stack. No SDK, no version pin, no vendor whose roadmap becomes your roadmap.
- Producer and consumer are decoupled by design. Which is the definition of portable, stated as a spec instead of promised in a docs page.
Where OKF stops
Here's the honest limitation, and skipping it would be dishonest given what the measurements show.
Singh found three confidently wrong facts in the curated docs he benchmarked, each contradicted by code that had been settled for over two years before the docs were written. Not stale — born wrong, in an AI generation pass, into the layer agents are told to trust. Then retrieval amplified one of them: top results repeated the wrong answer 26 times against 2 mentions of the correct one.
A bundle is a snapshot. Memory is a process. Adopt OKF and stop there and you've built a beautifully portable cache with no TTL.
He also names why nobody solves this with discipline: nobody hand-writes and hand-maintains bundles for forty repos. Substitute "forty agents." Manual curation doesn't survive contact with scale — which means curation has to be done by something that doesn't get tired, held to a verification standard, because automated curation's failure mode is precisely the one he measured.
The false dichotomy: it isn't curated knowledge versus active retrieval. Active accumulating memory is how you take in the world — fast, lossy, where new things arrive. Curated committed knowledge is what you've decided is true — slow, durable, auditable. Every functioning system has both.
The real question: what promotes a fact from one to the other, how often, on what evidence — and what demotes it when it stops being true?
That's a job. Formats don't curate. Retrievers don't decide.
The round-trip test
This is the one to run this week. It takes an afternoon and it's the single test that separates a portability claim from a portability guarantee.
# 1. export from your current system
$ your-memory-tool export --out ./snapshot-a
# 2. import into a clean instance — no prior state
$ your-memory-tool init --fresh ./clean
$ your-memory-tool import --in ./snapshot-a --target ./clean
# 3. export again from the clean instance
$ your-memory-tool export --from ./clean --out ./snapshot-b
# 4. diff
$ diff -r ./snapshot-a ./snapshot-b
What you're looking for isn't byte equality — timestamps and ids will move. You're looking for semantic loss:
- Did supersession chains survive, or did the importer flatten them into independent facts?
- Did provenance survive, or is
asserted_bynow null on everything? - Did confidence and expiry survive, or did they get defaulted?
- Did cross-references survive, or are they dangling?
- Count the units. If B has fewer than A, something was dropped silently.
Most systems fail at least three of those. Almost nobody checks until the migration, at which point it's a rewrite with a deadline attached.
The full checklist
- Canonical form a human can read. If answering "what does the system currently believe about X" requires a query and eyeballing cosine scores — no.
- Provenance and time on every unit. Who, when, on what basis, when it expires.
- Supersession recorded, not overwritten. You should see that Toronto was replaced by Berlin, and when.
- Durable form is model-independent. If a new embedding model means a lossy re-derivation, embeddings are your system of record. Fix that first.
- Export round-trips. See above.
- Verification against source. Every curated fact checkable against the thing it describes, on a schedule.
- It can abstain. Fareed Khan's pipeline work makes this point well: when evidence is missing, the correct output isn't a fluent guess. A memory system that can't say "I don't have that" will invent it — and inventions inherit the authority of the curated layer.
- Deletion actually deletes. Including from every derived index, cache, summary, and agent that copied it.
You shouldn't have to choose between memory that's alive and memory that's yours. The accumulating side and the committed side are two tempos of the same process. The thing worth building isn't another place to put memories — it's the thing that decides what moves between them.
Disclosure
This is what I work on, so weight it accordingly.
Memanto is an open-source companion memory agent that helps other agents manage their memories. As of v0.2.8 it ships native Open Knowledge Format integration — memories consolidate into OKF bundles you can read, diff and review in git — and migration from other memory systems built in:
$ pip install memanto
$ memanto migrate --from <source> --out ./memory-bundle
$ memanto export --format okf --out ./okf-bundle
As far as I know it's the only Memory Agent shipping both. MIT licensed, which is the only license under which a claim about portability is worth making.
Recall: 89.8% on LongMemEval, 87.1% on LoCoMo.
Run the round-trip test against it before you believe me. Run it against whatever you're using now either way.
Your agents focus. Memanto remembers.
Top comments (1)
Portability is a great test for agent memory because it exposes what is actually memory versus what is just local habit. If the memory only works inside one tool, one path layout, or one session format, it is closer to cache than durable context.
I would test it by moving the same task across runtimes and asking whether the agent preserves decisions, constraints, and next steps without leaking irrelevant history.