Files
amethyst/commons
Claude 3c65e601df fix(marmot): wire the disband fix through to Android
The convergence-based disband landed in `commons` and `quartz` but three things
it depends on only exist per front end, and the app had none of them.

**Nothing would have carried the pass to settlement.** Terminalization now
happens when the convergence pass SETTLES, and the settler is started by
inbound traffic that detected a fork — but a disband opens its pass from a
local outbound Commit with no fork, so no carrier ever started. On Android the
group would have sat in `Recovering` behind its own `Disbanding` gate forever:
nothing sendable, never ending. The CLI never showed it because the harness
drives settlement explicitly. `disbandGroup` and the regeneration path now
start the carrier themselves.

**The gate was not durable anywhere real.** Gate storage is defaulted on
`MarmotPublishObligationStore` so existing stores keep compiling, and neither
`AndroidPublishObligationStore` nor `FilePublishObligationStore` overrode it —
so the previous commit's durability claim held only for the in-memory store the
test used. Both now persist gates: one file per group beside the obligations.
Android writes them unencrypted, unlike an obligation, because the value is one
enum name and the filename is a group id the device already stores in the clear
— no key material, no message content. `FileStoresGateTest` pins the round trip
on the real file store, including that a gate write is not mistaken for an
obligation on reload.

**The UI announced an ending that may not have happened.** The toast said
"Group disbanded" as soon as the call returned, which used to be true because
an unacknowledged publish threw. It no longer throws — the request stays
durable and pending — so `disbandMarmotGroup` now returns whether the group is
terminal, and the screen says "Ending the group" when it is not. Leaving the
screen is right either way: the group takes no further outbound work.

Verified: quartz 4836, commons 1886, cli 53 green, and the full MDK interop
harness is 29/29 at the new 0.9.21 pin with all of this built in — including
test 05, whose earlier failure was the loopback relay dropping a websocket
before OK rather than anything in 0.9.21.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kCuA6tc4JQzHPCDd39GHq
2026-09-11 01:17:23 +00:00
..