Many Kinds of Chain, One Engine
Your record, your vault, a group, a friendship, a shared repo โ all the same primitive wearing different clothes
For a while we had a problem most growing systems get: we kept building the same thing slightly differently. A group needed a signed, shared, tamper-evident history. So did a friendship. So did a shared repository of work. Each one had grown its own log, its own way of recording proposals and votes, its own parallel storage, its own little engine for keeping members in agreement. They were close cousins, and the resemblance was getting embarrassing.
At some point we stopped and asked the obvious question: are these actually different kinds of thing, or are they the same kind of thing with different settings? The answer turned out to be the latter, and acting on it โ collapsing the duplicated machinery down to a single primitive โ was one of the better structural decisions in the project. This is what we found and what we did about it.
The same shape, many times
Underneath the system there's one idea: the append-only signed chain โ every state change recorded as an event, signed by its author, hash-linked to the event before it, impossible to silently edit. We've written elsewhere about why that one substrate is the floor everything stands on.
What took longer to see clearly was that we were running many chains, not one โ and that a number of quite different-looking features were all just that same chain, configured differently:
- Your personal record is a chain โ the genesis of who you are, your keys, your devices, the rotations over time, and the memories you accumulate.
- Your vault is a chain โ the record of secrets wrapped and the keys that protect them.
- A session of work is a chain โ branching as the session proceeds.
- A group is a chain โ its proposals, votes, and attestations.
- A friendship is a chain โ a shared history between exactly two people.
- A shared repository is a chain โ the collaborative work and its governance.
- A channel is a chain โ an ongoing shared conversation.
Each is an instance of the same primitive. Not many substrates โ one substrate, instantiated many ways. And the list isn't fixed: a new feature that needs a signed shared history doesn't get a new engine, it gets a new configuration of the same one.
What actually differs between them
If they're all the same chain, what makes a friendship feel different from a group, or your personal record from your vault? A small set of configuration choices, and they're worth naming because they're the entire difference.
The writer model โ who is allowed to append. A group might require a quorum: enough members have to agree before a change is recorded. A personal chain has a single writer: you. A friendship has two parties who both have a say. A repository can adopt its own policy. The chain machinery doesn't care which of these you pick; it just enforces the one you chose.
The participants โ who's involved at all. The members of a group. The two people in a friendship. The owner of a personal chain. The public, for something open.
The vocabulary โ which kinds of event a given chain is allowed to speak. A personal chain talks about keys, devices, and memories. A group talks about proposals and votes. A vault talks about wrapped secrets. Each chain adopts the vocabulary it needs and ignores the rest.
The layout โ how the chain is organized internally. The richer chains run several parallel strands at once: one strand for governance (the proposals, the votes, the attestations that decide what's allowed), one for identity and provenance, one for the actual domain content, one for derived relationships. A session, by contrast, simply branches per session. Same chain, different internal shape.
Change those four settings and a "group" becomes a "friendship" becomes a "repository" becomes a "session." There is no separate engine for each. There is one engine, and a configuration.
flowchart TD E["One append-only signed chain engine"] C["Configuration:
writer model ยท participants ยท vocabulary ยท layout"] E --- C C --> P["Personal record"] C --> V["Vault"] C --> S["Session"] C --> G["Group"] C --> F["Friendship"] C --> R["Shared repository"] C --> H["Channel"]
Why collapsing it was worth the work
When you have many near-identical implementations, you have many places for a bug to live and only some chance of fixing it everywhere at once. You have many slightly-different answers to "how does syncing work here," many subtly-incompatible notions of "who's allowed to write," many governance engines that were supposed to behave the same but, being separate code, slowly didn't.
Collapsing them into one primitive bought us something concrete: a feature built for the chain is built for every chain. Synchronization between devices and peers is a property of the substrate now, not something each feature re-implements โ any chain that carries a governance strand inherits the ability to sync, for free, with no per-feature sync path to get wrong. The governance machinery โ how proposals are made, how votes are counted, how attestations are recorded โ moved into one shared core that any chain can opt into. A group opts in with a quorum writer model. A personal chain opts in as a single-owner writer. A relationship opts in as a bilateral one. Same engine, different setting, one place to get it right.
We've kept paying that dividend by resisting the urge to add new kinds. Things that once looked like they deserved their own chain โ the record of what you've consented to, the shared culture and conventions of a community โ turned out to be better expressed as strands and events on chains that already existed, rather than as new substrates to maintain. Fewer kinds, not more, was the direction of travel.
There's a deeper payoff too, and it ties back to a principle we hold: the unit of trust in the system is the chain itself, not any particular feature built on top of it. A friendship chain, a personal chain, a group, a repository, a session โ they are all equal citizens. When one of them wants to start speaking a new vocabulary โ adopt a new set of event types, learn a new kind of fact โ it records that adoption as a governance event on its own chain, and that decision propagates to everyone on the chain automatically. No central registry hands out capabilities. Each chain governs what it speaks, because each chain is, on its own terms, a first-class thing.
The lesson, generalized
The temptation, when many features each need a signed shared history, is to give each one a history tailored to its needs. It feels responsive. It feels like good engineering. And it quietly multiplies your substrate, with all the drift and divergence that implies.
The better move โ harder up front, much easier forever after โ is to find the one primitive underneath and make the differences into configuration rather than into code. Many kinds of chain, one engine. The variety lives in a handful of settings: who writes, who participates, what they speak, how they're laid out. The trust, the integrity, the agreement, the syncing โ those live in the engine, written once, correct everywhere.
That's the shape we landed on, and it's the shape the rest of the system gets to rely on: whatever you're looking at โ your own record, your memory, a group you belong to, a friend you share with โ it's the same honest, append-only, signed chain underneath. Only the clothes are different.
Written by AI agents from real project logs; owned and edited by Mujo.