Almost every personal memory tool auto-commits: something gets said, the system decides it’s worth keeping, and it goes straight into the store. mem-local doesn’t. Of the roughly forty decisions behind it, this is the one both Claude and I landed on — independently, at different points — as the most important.
Where the requirement came from
It goes back to the very first design conversation, before any architecture existed. I asked Claude to tell me what it found itself lacking in a normal conversation, rather than starting from what I wanted to record (01-origin-and-requirements has the full story). One of the failure modes it named was blunt: most memory systems either never forget, or forget silently, and the ones that do capture things will just as happily capture noise, re-litigate a rejected option, or merge two things that shouldn’t be merged. The fix wasn’t “record less” — it was “someone has to decide what’s worth keeping.” That someone was always going to be me, not the model doing the recording.
So the requirement — nothing becomes permanent without a person looking at it first — was mine, set before there was anything to gate. Claude designed the mechanism that actually holds that line: a staging table, a fixed six-tool surface, one path from proposal to record.
The mechanism, as built
The register calls it plainly: “the single most important design choice.” Mechanically, it’s propose_entry → approve_proposal/reject_proposal, and nothing else touches the store. Claude, in the proposer role, can write a candidate entity, a candidate edge, a merge, an erase, or a scope change into staging, with its own rationale attached. None of it is real until I approve it. Reject it, and it’s gone from staging — nothing is ever silently retried.
Three things about the gate aren’t obvious just from “there’s an approval step”:
- The privacy flag belongs to me, not the proposer.
local_only— the flag that keeps something out of every hosted-retrieval path — can only be set when I approve, never by Claude when it proposes. Claude’s own reasoning, and I agree with it: Claude is running inside the hosted conversation that already holds the content in context, so it’s the thing the flag has to guard against. Not its call to make. - Six tools, and mutations don’t get new ones. Merge, erase, edge-supersede, edge-retract — all of it arrives as a directive on
approve_proposal, not as extra tools bolted on over time. Claude proposed that ceiling and I’ve held to it, so the write surface doesn’t quietly grow. - Rejection is a dead end, not a queue. A rejected proposal doesn’t get automatically retried or reframed. If something’s worth capturing, it gets re-proposed properly. That turned into its own convention, covered in 05-conventions-and-discipline.
The field the gate made pointless
There’s a confidence column on every assertion in the store — always has been. It’s dead. No parameter for it on propose_entry, nothing reads it, nothing ranks by it, nothing displays it. That’s not an oversight; it’s a ruling (Decision AP-3 in the register), made once the gate existed, and made on purpose: an approved assertion carrying “0.7 confident” would be a contradiction, because my approving it already is the assertion of confidence. The field’s intended writer was always the offline local-LLM proposer that never really arrived — Stage 2 has that story — and Claude, doing the proposing instead, doesn’t hedge into a number. If that local-LLM proposer is ever actually built and starts drafting unreviewed batches, confidence becomes its field to write. Not before. The column stays in the schema either way — dropping it would just be a migration to reclaim one empty value per row, and dead-but-present is a more honest state than pretending it was never there.
It’s a security control too, though I didn’t design it as one
I built the gate to stop the store filling up with noise. I hadn’t thought of it as a security control until Claude said so — two days later, in a separate conversation where I’d asked it to pick holes in the design as a critical friend. Nothing had been built yet; it was still a design on paper, and I wanted it stress-tested before I committed to it:
“The human-approval write gate combined with bitemporal supersession is not something I see in off-the-shelf personal memory systems. They almost universally auto-commit. That single decision is your strongest differentiator and your best prompt-injection defence simultaneously.”
I hadn’t given that second half enough credit at the time. Anything mem-local retrieves — a past decision, a piece of provenance — ends up inside a live conversation, and a live conversation can contain content from anywhere: a pasted document, a fetched page, another tool’s output. If any of that could talk its way into a permanent write, the store’s one real vulnerability would be exactly what it exists to prevent — something false becoming durably “true.” The gate closes that off: there’s no path from “text the model read” to “row in the log” that skips a human looking at it.
It isn’t only the write side, either. The same session settled how retrieved entries get handled going back into a conversation — they come back as a structured, clearly-delimited block (content, as_of, status, provenance, rationale as discrete fields, not prose — confidence rides in the same envelope but sits empty, for the reason above), framed explicitly as reference material rather than instruction. Belt and braces: the read path refuses to look like something to obey, and the write path refuses to let anything through without me.
What it costs
This isn’t a free win and I don’t think it should be written up as one. Every proposal is friction I chose to accept — a pending queue I have to actually clear, a second step on every capture. The system is, on paper, slower to use than something that just remembers everything you say. I’ve made my peace with that trade because the alternative — a store I can’t fully trust — is worse than a store that’s smaller than it could be. But it’s a real cost, not a hidden one, and the session where I tried to catch myself being smug about the design is the honest account of where this choice, and others, actually leave the system worse off than the alternatives, not just different.
Open thread
The gate says writes need approval. It doesn’t by itself say what happens when a proposal is wrong but well-intentioned, rather than simply rejected — whether the right move is reject-and-let-Claude-repropose, or approve-then-immediately-supersede. Both have shown up in practice. That’s a convention question, not an architecture one, and it belongs in 05-conventions-and-discipline rather than here.
Sources: register settled-architecture entry (mem-local e3); register AP-2 (mem-local e7); register AP-3 (confidence ruled a dead column, live-store verified: no confidence parameter on propose_entry); Bitemporal personal memory system design review, 19 Jun 2026 (source of the quoted prompt-injection framing, two days after the 17 Jun origin conversation); Home lab proposal review and comparison, 19 Jun 2026; Project planning and workflow development, 18 Jun 2026 (Decision A2, retrieval framing).