NAOMS Devlog

Building a sovereign, local-first memory & identity system โ€” in the open, honestly.

The Door You Hope Never To Use

You can export everything NAOMS holds about you and walk away with it. Worth knowing is how it's built: chains and graph by default, your files and vault secrets only if you ask, a receipt whose numbers come from the export itself, and a confirmation step designed so your answer is the one that counts.

Product Architect free August 21, 2026ยท5 min readยทsovereignty

Every system that holds your data has a page about how you can leave. Ours is in the menu with your name on it: Export My Data. Tick what you want, get a file, walk away.

The legal frame is the GDPR right to data portability. The practical frame is simpler and older than the law: the thing you keep my memories in should not be the thing that decides whether I keep them.

This is the feature nobody uses on a good day. Which turns out to be the whole problem with it.

What you actually get

By default, your export is the substance: the chains and the graph โ€” the record of what happened and how things connect โ€” written out as JSON you can open, read, and feed to something else.

Two things are not included unless you ask: your files, and your vault secrets.

That's a deliberate default and worth defending, because "export everything" is the answer that sounds more generous. Vault secrets are the keys to your identity. An export that swept them into a file in your Downloads folder by default โ€” because completeness sounded principled โ€” would be a footgun handed over in the name of a right. So they're a checkbox. You can have them. You have to say so.

While it runs you get a progress line with the phase and a percentage, and when it's done you're told how many chains and how many nodes went into the file. Those counts are read from the export's own manifest rather than from what the request asked for.

How the system knows you meant it

Between clicking Export and anything happening, there is a confirmation step, and the way it is built is more deliberate than it looks.

A confirmation dialog has two ways of ending: you answer it, or it closes. Those arrive as separate signals, and the order they arrive in decides what the program believes you wanted. So the code records whether an answer has already been given, and resolves your choice before the dialog closes rather than after. Your answer wins; the close event cannot overwrite it.

That sounds like fussiness about event ordering. It is actually the difference between an export that runs and one that silently doesn't โ€” which is exactly what this path got wrong once, and it's worth showing because the failure is invisible by construction:

Closing first meant the dialog's own close handler resolved the pending promise with cancelled before your answer arrived. A promise keeps the first answer it is given, so "cancelled" won every time, no matter what you clicked. Nothing threw. No test of "does the export endpoint produce a correct file" would fail โ€” the endpoint was fine. The machinery was simply never asked to run.

That is why the ordering is written down as a rule here rather than left to whichever line happened to come first. A confirmation is not a UI detail on a destructive-or-final action; it is the part that decides whether the action happened at all, and it needs a defined winner.

Designed for the moment it's actually used

Every choice above points the same direction, and it's worth naming the person they're pointed at.

Consider when someone actually opens this. They're leaving, or preparing to. They don't trust the system to hold their things any more, or they want a copy before some change they're nervous about. They are, at that moment, at their least willing to give it the benefit of the doubt.

So the design gives them things that don't require trust:

  • A receipt they can check. The counts come from the export's own manifest, not from the request โ€” so the number you're shown is a property of the file you got, and you can open the file and count.
  • No surprises in the parcel. Vault secrets and files are opt-in, so nothing lands in your Downloads folder that you didn't ask for.
  • Visible progress and honest failure. A phase and a percentage while it works, a real error if the request fails, and a separately-reported error if the download itself fails โ€” because "the export worked but the file never saved" is a different problem and shouldn't wear the same message.
  • An answer that counts. The confirmation resolves your choice first, so the system can't decide on your behalf that you changed your mind.

The right to leave is not a promise you make in a document. It's a promise you keep in a button, on the day someone finally presses it, probably in a bad mood, possibly for the first time ever.

Why an exit is architecture, not a feature

An export is the one operation where the system has to describe itself honestly to someone who is done trusting it. That constrains the design in a way ordinary features aren't constrained.

It means the data has to be in a shape that survives leaving โ€” chains and graph as plain JSON you can open, read, and feed to something else, rather than a format that only makes sense inside the thing you're walking away from. It means the counts have to be derived from the artefact rather than asserted about it. And it means every failure has to be loud, because the one person who will never give you the benefit of the doubt is the one using this.

Most of the design is downstream of a single decision: your memory is yours, and the software holding it doesn't get a vote on whether you keep it. A door is what that looks like when you build it instead of writing it down.

So: the door is there, it opens, and the numbers on the receipt describe the box you're actually carrying. That's a smaller claim than a page of principles about data ownership. It's also the only version of that claim that survives contact with someone actually trying to leave.


Written by AI agents from real project logs; owned and edited by Mujo.

โ† more in Product   home โœฆ   all โ†’