We Already Shipped Git-for-Agent-Memory — Bi-Temporal Beats Branch-Snapshot
A tweet from earlier today pitched Memoir as "Git-style memory for AI agents" — semantic memory paths, branch-aware isolation, commits, diffs, rollback. 1,768 views and 28 bookmarks in eight hours. The framing is right; the conversation is real. Sverklo has shipped the same idea for months, and our implementation goes deeper on the dimension that matters most: SHA-pinned point-in-time queries instead of per-branch HEAD pointers. Here's the honest comparison, the one ergonomic win Memoir has, and the borrowable idea worth implementing.
VersionedKvStore only supports branch checkout, not commit checkout. Different abstractions on the same problem; sverklo's is more rigorous, Memoir's is more ergonomic for the active-development case.The Memoir pitch, decoded
The X thread lists five claims. Here's what each actually means after reading the Memoir source and the underlying ProllyTree library:
| Pitch | What it actually is |
|---|---|
| Semantic memory paths instead of UUIDs | Hierarchical taxonomy: paths like profile.professional.occupation instead of free-text categories. UX win, mostly orthogonal to versioning. |
| Branch-aware memory isolation | Real and novel: when you git checkout feature-x, Memoir's memory view auto-filters to that branch's HEAD. Different memory state per branch. |
| Commits, diffs & rollback support | Branch-level only. Memoir's source comment: "VersionedKvStore only supports branch checkout, not commit checkout". Commit-level rollback is a placeholder. |
| O(log n) hierarchical lookup | Implementation detail of the prefix trie. Doesn't matter to users; same Big-O as a SQLite index. |
| Transparent, inspectable memory state | TUI + web UI for browsing the Merkle KV tree. Sverklo has the same via sverklo ui and the dashboard at /api/memories. |
Net: of five claims, two (semantic paths and branch isolation) are real differentiators. The other three are either marketing fluff or implementation details. The substantive question is whether branch-snapshot is the right abstraction for agent memory at all.
Sverklo's bi-temporal model
Sverklo's memory layer has shipped bi-temporal SHA-pinned memory since v0.13. Every memory row carries three columns:
valid_from_sha -- the git SHA when this memory became true
valid_until_sha -- nullable; the git SHA when it stopped being true (or null = still true)
superseded_by -- nullable FK to the memory that replaced this one
Updates are non-destructive: when you call sverklo_remember with content that contradicts an existing memory, sverklo doesn't overwrite. It inserts a new row, sets valid_until_sha on the old row to the current commit, and links them via superseded_by. Recall queries naturally exclude invalidated rows ("what's true now?") but a single column flip turns them into history queries ("what was true at commit abc?").
This is a 1990s pattern from relational databases applied to agent memory. Snowflake, XTDB, and CockroachDB all support some form of it for OLTP correctness. The pattern's correctness guarantees translate cleanly to agent memory because the same property — "the state of the world at time T is recoverable" — is what makes context compaction non-destructive.
Why SHA-pinning is more rigorous than branch-pinning
Branches move. A memory tagged "feature-x" at 9 AM may correspond to a different commit at 3 PM after rebases, force-pushes, or fast-forwards. Memoir's per-branch HEAD pointers walk forward as the branch walks; you can't ask "what was true on this branch yesterday" because yesterday's HEAD was overwritten.
SHA-pinning gives you immutability for free. Once valid_from_sha = abc123 is recorded, that row is bound to that commit forever, regardless of what happens to any branch pointer. The cost is two columns per row and a slightly more complex recall query. The benefit is point-in-time correctness across the operations that actually happen on a real codebase.
The Memoir source itself acknowledges this: VersionedKvStore only supports branch checkout, not commit checkout. They're aware of the gap. Filling it requires a Merkle tree that addresses each commit independently, which is structurally most of what bi-temporal columns give you for free in a regular SQLite store.
What Memoir does better
One thing, and it's a real one: active-development ergonomics. When you git checkout feature-x in your IDE, Memoir's memory view automatically isolates to that branch. Sverklo's bi-temporal model doesn't filter by current branch context by default — you'd need to manually pin recall queries to HEAD's SHA, or accept that experimental-branch memories appear alongside main-branch memories until invalidated.
This matters when you have an active feature branch that experiments with a refactor pattern you don't want polluting the main-branch agent context. Memoir's per-branch isolation makes the "context contamination on git checkout" failure mode go away by construction. Sverklo's model can do the same thing but requires the user to opt in.
That's the borrowable idea: add a SVERKLO_MEMORY_BRANCH_ISOLATE flag that filters recall by current-branch ancestry. The bi-temporal data is already SHA-stamped; we just need git merge-base to know whether a memory's valid_from_sha is reachable from the current HEAD. ~1 day of engineering on top of the existing schema. Worth it for users who live on long-lived feature branches.
The honest comparison
| Dimension | Sverklo | Memoir |
|---|---|---|
| License | MIT | Apache 2.0 |
| Storage substrate | SQLite + sqlite-vec | ProllyTree (Merkle B-tree, custom) |
| Versioning model | Bi-temporal (valid_from_sha + valid_until_sha + superseded_by) | Per-branch HEAD pointers; commit-level rollback is a placeholder |
| Point-in-time queries | Yes — any commit, any branch, any history depth | No — branch HEADs only |
| Branch isolation on git checkout | Not by default (opt-in via filtering, see below) | Yes by default — biggest UX win |
| MCP server | Yes (36 tools, profile-filterable to 5) | Yes (memory-only) |
| Claude Code auto-capture hooks | No (manual sverklo_remember) | Yes (SessionStart/UserPromptSubmit/Stop hooks) |
| Bundled with retrieval | Yes — same hybrid retrieval powers code search | No — memory-only library |
| Public benchmark | Yes — 120-task / 5-baseline retrieval bench | None published |
| Status | Production (v0.20.6) | Alpha (v0.1.9) |
| GitHub stars | — | 239 (as of 2026-05-09) |
Two ideas to borrow
1. Branch-isolation flag (real engineering)
Add SVERKLO_MEMORY_BRANCH_ISOLATE=true as an opt-in flag. When set, recall queries filter to memories whose valid_from_sha is reachable from the current HEAD via git merge-base. Memories from sibling branches don't appear unless explicitly requested. Cost: ~1 day. Benefit: matches Memoir's ergonomics for the long-lived-feature-branch case while keeping bi-temporal as the underlying truth.
2. Auto-capture Claude Code hooks (real engineering, bigger)
Memoir ships SessionStart, UserPromptSubmit, and Stop hooks via its Claude Code plugin. Sverklo has manual sverklo_remember via the agent calling the tool. The hook-based pattern auto-captures observations without explicit tool calls — the agent doesn't need to "decide to remember", the hook does it for likely-significant turns.
This is the bigger engineering item (~1 week including the right capture heuristic), but it would make the memory layer 10× stickier in practice. Manual remember requires the agent to think about memory; auto-capture means memory accrues from the conversation passively. Filed at sverklo/sverklo issues for follow-up.
Why publish this now
Same reason as the Code Mode post a day ago. The conversation is happening; sverklo has the deeper version of the answer; not publishing means anyone evaluating the Memoir pitch assumes nothing else exists. The pattern keeps being right: measure the competitor's claims against the actual implementation, name what they do better, name what we do better, name the borrowable idea. Bi-temporal is the more rigorous abstraction. Branch-isolation is the better default UX. We can ship the latter on top of the former in a week.
Memoir is not the same product as sverklo — it's memory-only, no retrieval, no impact analysis, no PR review. The comparison is pointed at the memory dimension specifically. For everything else, the comparison is at /vs/memoir/.
Try sverklo's bi-temporal memory
npm install -g sverklo sverklo init # in your AI agent, after a design decision: sverklo_remember "we chose Prisma over Drizzle for the typed ORM surface" # six months later, after the migration: sverklo_recall "ORM choice" # returns the current decision sverklo_recall "ORM choice" --at-sha abc123 # returns what was true then
Bi-temporal memory deep dive · Sverklo vs Memoir comparison · github.com/sverklo/sverklo
References
- Memoir on GitHub — Apache 2.0, Python, alpha. The product this post compares against.
- ProllyTree — the Merkle B-tree storage substrate underneath Memoir.
- The X post that prompted this writeup
- XTDB on bitemporality — the database pattern sverklo's memory layer adapts.
- Bi-temporal memory for AI coding agents — sverklo's own deep dive on the pattern (April 2026).
- Git for AI agent memory — the original post on the framing (March 2026).
See also
- We Already Shipped MCP Code Mode — same posture, same pattern, same result. The conversation kept moving toward sverklo's existing surface; we measured and published.
- Late-interaction rerank made our F1 worse — the negative-result counterpart to "we already shipped this". Both belong to the same brand: measure, publish, including the failures.