Adding Someone Is Not A Row In A Table
In most software, adding a person to a shared space is a database write. Here, writing is cryptographic โ so letting someone in has to actually hand them the ability to sign. It turns out there are two different ways to do that, and which one you get depends on the space.
In most software, adding someone to a shared space is a row in a table. There is a members list, you append to it, and a permission check somewhere later reads that list and says yes.
That cannot work when writing is cryptographic. If every contribution to a space has to be signed, then "you're a member now" is an empty statement unless the person actually holds something they can sign with. The membership list isn't the permission. The key is the permission.
So letting someone in has to be a real ceremony โ something has to be handed over. The interesting part is that there turned out to be two quite different ceremonies, and for a while the system was trying to use one of them for both jobs.
Two shapes of shared space
Some spaces are jointly held. The space has one signing identity, shared across its members, and no one member can act alone โ a threshold of them has to agree. For those, the default is a supermajority: two-thirds of the members, rounded up.
Other spaces are open per-writer. Everyone writes under their own name. There is no shared key at all; each writer is, in the system's own words, its own 1-of-1 group, told apart by their identity rather than by a shared epoch.
These look identical from the outside. Both are "a space with people in it." Both have a members list in the panel. But what "add a member" has to do is not remotely the same thing.
Rotation, for the jointly-held ones
Where there is a genuine shared key, adding a member means re-deriving it. The group's public key changes, everyone gets a freshly minted envelope containing their piece of the new key, and the whole thing is stamped with a one-time random value so an old ceremony can't be replayed at you.
The detail I find most quietly considerate is what happens to everything written before the change. The rotation records the exact point in history where it takes effect, and anything committed before that point still verifies under the old key. Adding a person to a group does not cast doubt on everything the group did last month. History stays valid; only the future changes hands.
Admission, for the open ones
Doing that to an open per-writer space would be theatre. There is no shared key to re-derive. There is no group epoch to advance. Rotating something that doesn't exist just produces ceremony-shaped noise.
So for those, adding a member is admission: the new writer mints their own key, at the same stable starting point everyone else uses, and begins writing under their own identity. Nothing else in the space has to change. Nobody else's key moves. The new person can contribute immediately, because there was never a shared secret standing between them and the ability to sign.
That is the answer to the question this work was set: why must a member who joins an existing space be able to sign on it right away? Because any design where they can't is a design where "you've been added" was a lie for a while.
One predicate, on purpose
The part worth respecting is architectural rather than cryptographic. The choice between these two ceremonies is made by exactly one function โ a single predicate that answers "is this an open per-writer space?" โ and every site that admits or rotates is required to route through it.
The reasoning is written down in the code: so the distinction "stays at one source of truth and cannot sprawl."
That is a rule about the future. Two adjacent behaviours that look similar and differ in one important respect will, left alone, get copied slightly wrong into a dozen call sites, and then the difference between them stops being a decision anyone made and becomes an accident of whichever branch someone pasted. Pinning it to one predicate is a bet that the codebase will be edited by people who don't remember this article โ which is the correct bet.
When it doesn't know
There is one more case, and its handling is the tell. A space might have no recorded policy at all, in which case the system genuinely does not know which kind it is looking at.
It could quietly guess. Instead the guess is counted, refused at the gate, and logged under a name that says exactly what happened โ a policy fallback, not a policy. Somebody wanted to be able to measure how often the software was working from an assumption rather than a fact.
That is a small thing that tells you what the codebase is anxious about, and it is anxious about the right thing.
Written by AI agents from real project logs; owned and edited by Mujo.