You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
reach: linkSeats reads invite.homes only, so a link accepted before homes was written still enumerates no pair #929
#923 fixed the pair enumeration by reading the link's own record of who it seated, but it reads only one of the two places that record keeps that fact. A room whose invite was accepted beforeinvite.homes was written still enumerates no pair, so its group envelopes still fall back to a friendship the two homes never had — the exact symptom #923 closed, surviving on rooms that already existed when it merged.
Lines (main 137cd2fd)
core/src/host/reach.js:209linkSeats(room) walks room.localInvite / room.localInvites and reads Object.values(invite.homes ?? {}) only (:213-219). ticketPeers uses it at :241 (linkOf.get(handleOf(p))?.ticket), so a seat whose handle appears in no homes entry gets ticket === undefined and is skipped (:248-249).
core/src/host/room-membership.js:1205homesOf(invite) is the same fact with the older shape recovered: if invite.homes has no entry for a home, invite.acceptedBy supplies one, with invite.seats (or [acceptedBy]) as its handles (:1207). The writer paths delete acceptedBy once homes is written (:1608-1609, :1710), which is exactly why a record that has acceptedBy is one that never got homes.
So the two halves disagree: room-membership.js treats acceptedBy + seats as "this home was seated", reach.js does not.
What to change
Make linkSeats see the same records homesOf sees. Either export homesOf from core/src/host/room-membership.js and use it (one source of truth, preferred), or repeat its one-line recovery in reach.js with a comment naming homesOf as the authority. Whichever: keep linkSeats read-only — no state writes, no events, no roster re-send, and loading a room must not mutate it (#923's constraint).
Acceptance
A room whose invite record is the old shape — acceptedBy plus seats, no homes — has its seat enumerated by ticketPeers(), with scope the room id and the ticket from the invite.
The new shape (with homes) enumerates exactly as today.
Both halves agree on the same fixture: a record for which homesOf(invite) is non-empty must produce a pair, and one for which it is empty must not — a test that asserts the two functions cannot drift apart again.
The new test is red on pristine 137cd2fd (it must, since linkSeats today reads homes only) and the rest of the room tests stay green.
Why it matters beyond tidiness
Rooms that predate this work are exactly the ones a user already belongs to; a fix that only covers newly accepted links leaves the reported "cannot send into the group" symptom in place for them, and the code gives no sign of it (the pair just is not there).
Activity
Read a link's seats through homesOf, so a room older than the field e…