Two surfaces the last three commits added and left resting on indirect coverage. Both
are decisions rather than plumbing, and neither had a test that would notice it changing.
**`SubgroupBirthCertificateEvent.addresses` had none at all.** Its sibling `certifies`
has nineteen, several of them real FROST forgeries, because a certificate is the whole
of what a subgroup relationship is. `addresses` was then added *beside* it as a
deliberately weaker reading -- no derivation, no signature -- and exercised only through
a view model, which is the wrong place to learn what it is worth.
The invariant worth having is the one a future reader can get wrong: **an event can pass
`addresses` and fail `certifies`.** Two cases say so in the two ways it happens -- an
unsigned proposal, which is exactly what the ceremony screen holds and asks about, and a
forgery authored and signed by the child's own quorum, which is anybody at all. A third
asserts `certifies` implies `addresses`, so the weaker one cannot drift into being the
stricter one while both are called "which child is this about".
The other two are the case the predicate exists for: two subgroups of one parent. A
sibling's well-formed proposal is not addressed to this child, *and is* addressed to the
sibling -- told apart rather than both refused, which a predicate that merely failed
closed would also satisfy.
Checked by giving `addresses` a signature check: the two "and certifies nothing" cases
fail, the other three do not.
**`hidesOtherCeremonies` had none either**, and it decides where a tap in the transcript
goes. `CeremonyQueueRoutingJvmTest` pins both of its guards separately, which is the
point of four cases rather than two:
- one ceremony owed -> open it. Drop the `size > 1` and this fails.
- two owed -> the list, from either tap, because neither is the whole of what the room
is waiting on this member for.
- a *finished* ceremony's line -> open it, even while two others are owed. This is the
restraint, and dropping the "is itself awaiting" clause is what it catches: a reader
tapping history is asking to see history, not to be handed somebody else's queue.
- an abandoned one is never owed, even when `pendingApproval` says it is.
Each regression was reinstated separately and each is caught by exactly one case.
One thing the empty expectation needed care over, and it is the same trap a test in
`26d305bc` fell into: a watcher that writes once cannot be waited for by its own empty
value, because empty is indistinguishable from not having run. The abandoned case waits
on a clock instead and says so.
**`hidesOtherDecisions`, the proposal counterpart this mirrors, still has no test.** It
predates all of this and is left alone, but the asymmetry now runs the other way and is
worth knowing about.
**Still untested, and deliberately so rather than overlooked:** the three entry points
into the ceremony list -- the "Key ceremonies" row on the group's details, which exists
to be reachable in a *Marmot* room where "Shared key" is not, the standing notice
handing back null for several, and the transcript line's routing. Those are desktop
compose-ui tests over `ChatRoomDetailScreen` and `ChatTranscript`, both of which stand
up considerably more than anything here does.
982 jvm tests, 459 common tests, `m3Audit` meeting every budget.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>