Skip to content

reach: linkSeats reads invite.homes only, so a link accepted before homes was written still enumerates no pair #929

Closed

Description

@Birfy

What happens

#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 before invite.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:209 linkSeats(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:1205 homesOf(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

  1. 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.
  2. The new shape (with homes) enumerates exactly as today.
  3. a link-admitted guest still needs a friendship: its room envelopes are carded, and approving the card ends in no_relationship #923's negative control still holds: a friend's Bot added by hand (named by no link) is not a pair.
  4. 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.
  5. 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

  1. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:socialFriends, invites, grants, Bot Social
    agent-prPull request opened by an agent
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 24, 2026
  2. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 24, 2026
  3. added a commit that references this issue on Oct 24, 2026
    c426020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:socialFriends, invites, grants, Bot SocialbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions