Picking "robust" made a NIP-17 room and left it at that. The quorum the user
had just set was read, explained, coerced into range -- and then dropped on
the floor, with a TODO where it should have gone saying so: NIP-17 has no
group state to change and so nothing to approve, and a different member set
is simply a different room.
That TODO had an answer the app has been able to give since ChillDkgRitual-
Manager landed. The one thing a t-of-n rule can attach to here is a key the
members generate together and cannot sign with unless t of n of them are
present, and everything a ceremony needs is settled the moment the room
exists: who is in it, and how many of them have to agree. So the room now
opens one, and the proposal is its first message.
## Why at creation rather than behind the button
The button is still there on the shared-key screen, and this changes nothing
about it. What it cannot do is be found. A group that picked robust and got
a plain NIP-17 room has the thing that makes it robust sitting one unmarked
navigation away, and until somebody takes it the group's governance is a
number nobody enforces.
It is also how the rest of the group hears of the room at all. Standing up a
NIP-17 room sends nothing to anybody -- there is no invite, no welcome, no
key package -- so before this the first anyone learned of a robust group was
whenever somebody happened to type into it. The proposal is now the first
event out, and NostrDao already builds the room on the receiving side from a
DKG payload's p-tags for exactly this reason.
## The order this runs in
The room is created first, then the ceremony is proposed, then the screen
navigates. createdChatRoomId is set the moment the room exists, before the
proposal, so a second tap reuses that room rather than minting another --
and it is what freezes the type and quorum pickers, both of which are
answered by then.
Proposing before navigating means the chat opens with the ceremony already
in it rather than filling in underneath the user. It costs no round trip:
proposeRitual writes rows and queues a gift-wrap payload, and NotaryViewModel
seals and broadcasts on its own schedule.
The quorum is passed through as the threshold with no coercion. The screen
derives its range from the picked members plus the creator, and
createNip17ChatRoom stores exactly that set as the room's participants, so
the range proposeRitual validates against is the same one the picker was
bounded by.
## When the ceremony does not open
Nothing is rolled back. The room is real, the group can talk in it, and the
ceremony can be opened later from the group's details -- so failing the
whole creation would be throwing away the part that worked.
But it is not navigated past either. The screen stays put and says what
happened, the way it already does when a Marmot group is created without
some of its members; the button flips to "Open chat", which is what the user
is left with. A robust group quietly without a key is the one outcome here
worth interrupting for.
## Elsewhere
The robust card's footnote now says that creating the group starts a key
ceremony every member takes part in. Members are about to be asked to
approve joining it, contributing to the key, and confirming the result, and
none of that should be the first they hear of it.
MantraNavHost hands the screen the DkgRepository it already builds for the
ritual and approval routes; the preview takes the no-op.
Left alone: DkgRitualViewModel still cannot read back the quorum a room was
created with, because ChatRoom does not persist it. Its threshold picker
re-derives a majority default, which now only matters for rooms made before
this change or after a failed ceremony.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>