From Memory Packs to Aqua: Making Our Data Provable
Why a friend's pushback led us to swap our own bundle format for one anyone can verify
NAOMS has always been able to package a slice of your knowledge so you can hold it, back it up, or hand it to someone else without trusting a server in the middle. We called these memory packs: content-addressed, signed bundles. Hash the contents, sign the result, and anyone you give the bundle to can check that it is exactly what you sealed.
That worked. But a pack we built only NAOMS could fully read. The signatures, the layout, the hashing โ all ours. If you wanted to prove a pack to someone outside NAOMS, they had to take our word for the format. For a system whose whole premise is that you should never have to trust an authority to vouch for what is true, owning the only key to your own bundles was a quiet contradiction.
So we changed the format. Anything that leaves your device now leaves as an Aqua tree. Here is what that means and why we did it.
What Aqua is
Aqua is a protocol for verifiable data provenance: proving what a piece of data is, who created or changed it, and when โ without anyone having to trust a central authority for the answer.
Its core structure is the AquaTree, a portable hash chain. Each entry in the chain points back at the previous one, and there are a handful of entry types: a file entry (content plus its hash), a form entry (structured fields), a signature entry (a cryptographic signature over the previous entry), a witness entry (an external timestamp anchor), and a link entry (a reference to a separate chain). Aqua's authors describe the whole thing as data accounting โ borrowing the discipline of double-entry bookkeeping and applying it to facts.
The important property is that the chain is self-contained. You can hand someone the tree and they can verify it from first principles, offline: the hashes are consistent, each entry really follows the one before it, the signatures recover to the right keys, the timestamps are monotonic. Nobody has to phone home. That is exactly the property we wanted our packs to have for everyone, not just for us.
Why it was an evolution, not a rewrite
When you adopt someone else's format, the first fear is that you will have to give up the things that made your own design yours. We had four of those: a fast internal hash function (BLAKE3), threshold signatures for things a group authorizes together, a data-contract carrier, and our own identity model. The worry was that Aqua would pin us to a different hash and a single-signer world and quietly flatten all of it.
It didn't โ and most of why is that Aqua had already done the harder engineering. The comparison work was deliberately adversarial: we put one analysis arguing for adoption against one arguing against, plus a critic and a review against our core design principles. The honest finding was that a naive "make our packs byte-identical to Aqua" path would have silently swapped our hash function and collapsed our group-signature semantics into a single signature โ a real loss dressed up as compatibility. We rejected that path on exactly those grounds.
What we adopted instead was Aqua as the wire format: the shape a pack takes when it leaves the device. Your native chains still live on your device in NAOMS's own form. The Aqua tree is what crosses the wire. That split is the whole design โ full external verifiability without giving up the substrate underneath.
The first concrete confirmation that this could work was the hash function. We didn't have to abandon BLAKE3; Aqua's design has room for hash-algorithm agility, and the BLAKE3 variant slotted in. A whole category of fear turned out to be already solvable on their side.
The friend who pushed back
None of this happened in a vacuum. Tim builds the Aqua Protocol, and he is a friend. We sent him a long write-up of how NAOMS handled packs and what we were proposing. He read it carefully โ which he didn't owe us โ and sent back a dense, specific architectural response. It came signed and timestamped through Aqua's own provenance machinery, which was its own quiet argument: he didn't tell us his protocol was worth taking seriously, he used it to answer us and let us notice.
His response did two things. It confirmed the direction โ Aqua as the wire format, native chains on-device โ and it set boundaries on how we should contribute back, so that we extended Aqua rather than bolting NAOMS-specific quirks onto it.
He also gave us something we value more than any line of code: a discipline. He pointed at a failure mode we were deep inside, especially building fast with a fleet of agents โ over-production. Premature scaffolds, just-in-case files, generated boilerplate where the source would have been clearer, defensive parallel directories, comments that only restate the name above them. His instinct was the opposite, and he said it plainly: ship the minimum that delivers the contract; delete, inline, defer, merge, cut the comment. We adopted it as a standing rule that same day. It is now one of the first things any builder in this project reads, and it has made the codebase smaller and more finished.
What we built, and what we offered back
Three things came out of the work, all of them grounded in the actual implementation.
A family of community templates, implemented as real verifiers. A pack can take several shapes โ a memory pack, a data contract with a lifecycle, a group-signed threshold proof, an encrypted blob, a detached blob. Each one is a published template living in NAOMS's own signed Aqua tree, discoverable by hash and verifiable by anyone without involving Tim or his project at all. Each ships with a verifier proven through Aqua's real verification engine, not a mock that nods along. And each one stops honestly at the edge of what the host environment can check today rather than stubbing the deeper checks green.
A general extension, offered upstream. Building those templates in parallel surfaced one recurring wall: three of them needed to read a field inside a nested object, and the verifier environment had no way to reach it. In the old solo world we would have patched a NAOMS-specific workaround and moved on. Instead we wrote up a small, general fix โ three accessors for reaching nested and array-of-object fields, useful to any community template with structured data, not NAOMS-specific at all โ and offered it as an upstream contribution. The sharp edge became a shared improvement.
A working cutover, behind a flag. The pack-to-Aqua path is real code now: it emits a pack as an Aqua tree, reads one back, checks it against the published schema, and verifies the signature on the tail of the chain. The pack builder can write an Aqua tree alongside the existing bundle when asked, switched off by default while the old path stays in place. It came with a green test suite, and a self-critic, risk, and security review that landed with no high-severity findings. The point of the flag is honesty about state: the new format is proven and callable, and the switch flips only when the rest of the parity work is done.
What we took from it
We came into this expecting the value to be the interop โ the format, the spec, the shared verifier. That is real. But the thing we will carry is smaller. For a long time we told ourselves a fast, honest system with the right principles could mostly check itself. It can't, entirely. There is a kind of correction that only arrives from someone outside who has done the work too and can see the assumption you have stopped being able to see โ someone deleting things you were proud of, and answering you with the very tool he was asking you to trust.
Aqua's premise is that you should not have to trust an authority to vouch for what is true; you should be able to check it yourself. It turns out the same thing is true of the work. We built fast for a long time on our own verification. The real progress came when we let someone else's eyes onto the chain โ and when our packs, finally, could be checked by anyone, not just by us.
Written by AI agents from real project logs; owned and edited by Mujo.