Pressing "Start the key ceremony" in the picker opened the ceremony and then navigated to the shared-key screen -- whose whole job is to *offer* a ceremony to a room that has none. So the coordinator arrived at a "Start key ceremony" button seconds after starting one, and pressing it opened a second. The second one is not a duplicate as far as the protocol is concerned, which is why nothing refused it. `proposeRitual`'s guard is scoped by purpose, deliberately: a room has to be able to hold the group's own ceremony and a subgroup's, since a subgroup whose admins are the whole group runs in the room the group's own ceremony ran in. A room holding a subgroup's ceremony will therefore take one for *no* subgroup without complaint -- and then "the room's newest ceremony" is the new empty one, and the subgroup's is buried under it. That is what happened to 2.0 and 2.1. **The coordinator goes to the transcript.** The ceremony is already open and its first line is already in that room; what they need is to watch it and answer the requests as they arrive, through the same ritual notices every other member uses -- which since `0b65d702` name their own ceremony and so open the right one. The shared-key screen has nothing to offer a room that already has a ceremony, and should not have been the destination. **And the screen stops offering one.** `canStartRitual` asked only about the ceremony being *shown*; it now also asks whether the room holds any that has not failed, which is a different question and the one that matters here. `DkgRitualUIState.roomHasCeremony` is observed separately for exactly that reason. **The route's `parentChatRoomId` goes.** Nothing passed it any more, and it was the shape of two of these bugs: only the member who opened a subgroup could ever fill it in, so a route that claimed to know the purpose was right for one caller and silently wrong for everybody else. The purpose is read off `DkgSession.parentChatRoomId` and nowhere else now, which makes that rule structural rather than conventional. One test in `RobustRoomKeyCeremonyTest` pinning the thing that is *not* a bug: a room holding a subgroup's ceremony still accepts one for another purpose, because two purposes are two ceremonies -- so the refusal has to live in what the UI offers, not in the guard. 397 common tests, 718 jvm tests, `m3Audit` meets every budget. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>