Memory that commits: how Memoir remembers a fact
Most agent memory is an opaque pile of embeddings. Memoir takes the opposite bet: classify a fact into a human-readable semantic path, then commit it like git — so memory is structured, attributable, and reviewable.
Most agent "memory" is an opaque pile of embeddings. You can't see what it learned, why, or when. Ask where a belief came from and the honest answer is "vector #4823, similarity 0.81." Memoir takes the opposite bet: make every memory a named thing with a history.
Memoir doesn't dump text into a vector blob. It classifies a fact into a human-readable semantic path and commits it like git — so memory is structured, attributable, and reviewable.
Let's follow one sentence all the way through. A user tells their assistant: "I prefer dark mode in every app." Here is what happens to it.
The call
The agent passes plain text. It does not say where the fact belongs — Memoir decides. Through the MCP server the call and its result are tiny:
// the agent calls:
memoir_remember({ content: "I prefer dark mode in every app" })
// memoir returns:
{ "success": true, "key": "preferences.ui.theme",
"confidence": 0.97, "commit": "a1b2c3d" }
That key — preferences.ui.theme — is the whole trick. It
is a human-readable address, not a vector id. The same write path
runs in the Claude Code, Hermes, and OpenClaw plugins; the MCP server
is just the example we'll use here.
Step 1 — the secret guard
Memory is versioned plaintext. A store you can
log and blame is the last place you want an
API key. So before anything else, Memoir refuses obvious credentials —
tokens, passwords, PEM keys, card-like digit runs. "Remember my
password is hunter2" → refused, nothing stored.
Step 2 — classification into the taxonomy
This is the heart of the write path. Memoir has a fixed
taxonomy: roughly 200 paths, exactly three levels —
category.subcategory.type. An LLM classifier reads the
fact and picks the single best leaf. "I prefer dark
mode in every app" lands on preferences.ui.theme.
preferences.ui.theme, not
an opaque vector id.
Two nuances worth stating, because they're easy to assume wrong:
- Verbatim. Memoir stores the fact as given, classified to one path. It does not rephrase or split it — that's a separate feature (auto-capture).
- The LLM is optional. Pass an explicit
pathand classification is skipped entirely — instant, keyless, no provider call:
// skip the LLM entirely — pass the path yourself:
memoir_remember({
content: "I prefer dark mode in every app",
path: "preferences.ui.theme"
}) // instant, keyless, no classifier Step 3 — commit to the prolly-tree
The classified fact is written into a prolly-tree store and committed — exactly like a git commit. That one design choice hands memory the whole git toolbox:
log— when did I learn this?blame— what's the provenance of this belief?- branches — diverge memory for a side conversation, merge later.
The big idea — front-load the intelligence
Here is the contrast that makes Memoir different from a vector store, and it comes down to when the model runs.
Memoir spends its LLM at write time — classify once into a meaningful path. Vector stores spend it at read time — embed the query and scan for similarity on every single recall.
Because the structure is meaningful, reading it back doesn't need a model at all — which is exactly why recall is LLM-free by default.
What you get
The payoff of "remembering is a well-named commit":
- Inspectable —
preferences.ui.theme, not vector #4823. - Attributable — every fact carries a commit you can
blame. - Reviewable & reversible — full history plus branches.
- Portable — it's a git-like store you own.
A memory you can read, blame, and rewind — because remembering is just a well-named commit.