updateGroupChat's inline durable-map builder (the local-mutation persist
path) skips tombstoned rooms and carries roomId — but durableGroupChatRooms,
the SEPARATE builder persistGroupChatRooms uses for the remote-merge path
(every pullGroupChatServerState / gateway-swap sync), has neither.
Two independent gaps in the same function:
1. Tombstone resurrection. Disband sets a runtime-only tombstone
({tombstone: true, log: [], ...}) while a drive may still be mid-turn,
with no roomId. mergeRemoteGroupChatSnapshotIntoRooms spreads
...existing before its explicit field overrides (none of which touch
tombstone), so if a remote gateway hasn't received the delete yet
(plausible now that sync fans out to every reachable default-profile
gateway with independent per-connection backoff) and still has a live
copy of the room, the tombstone flag survives into the merged room.
That merged map is handed straight to persistGroupChatRooms, which
wrote it to storage because durableGroupChatRooms had no tombstone
check. On the next cold hydrate the persisted tombstone reads back as
an empty, non-tombstoned room, resurrecting the original bug
(recreating a room under the same name silently becomes "<name> 2")
through a path the earlier tombstone fix didn't cover.
2. roomId loss. mergeRemoteGroupChatSnapshotIntoRooms correctly carries
roomId into the merged in-memory room, but durableGroupChatRooms never
included it in the persisted snapshot. Every room merged in via the
remote-sync path therefore loses its immutable room identity on the
next cold hydrate (comes back with roomId: null) and falls back to
legacy name-keyed identity — breaking id-based rename/merge resolution
and member-session titling ("Group: <roomId>").
Fix: durableGroupChatRooms now mirrors updateGroupChat's inline map
exactly — skip tombstones, carry roomId.
Tests: durableGroupChatRooms unit tests for both gaps, plus an
end-to-end reachability test (tombstone -> mergeRemoteGroupChatSnapshot-
IntoRooms -> persistGroupChatRooms -> storage) proving the merge really
does forward the tombstone and the fix really does keep it out of
storage. Mutation-verified against pre-fix code (all 3 new tests fail).
Full hermes-bots plugin test suite (60+ files) green.