Skip to content

Invite-link join stays on Asked to join when the Bot was already seated by add-member #1176

Closed

Description

@Birfy

Symptom

E2E 2026-10-25: A created an ordinary group and added Friend's Bot on B. B's sidebar already showed Shared room from SelfA….

Pasting A's invite link on B and Join with link only showed Asked to join…. It opens in your sidebar as soon as their FlyBot seats your Bots. with no further confirmation — even though B was already in the room via add-member.

Related: #1161/#1162 seatOpenClaims rate-limit (merged/deployed). This is a separate UX/state bug: join UI does not recognize an already-seated member.

Claim

Claimed by Birfy / bot-im — queue after #1174.

Activity

  1. self-assigned this
    on Oct 25, 2026
  2. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Triaged at main bb96cc8f. The E2E itself needs two homes and Bot Social, but the state bug is in this repo and is readable from the code:

    1. plugins/social/src/face-rooms.js:828-839 — the server answer (localView) already carries roomId, the inviter's room id, and claimed.
    2. core/src/host/room-membership.js:1546-1557 — previewLocalInvite drops roomId and computes joined only when seen.claimed === true (:1554-1556), through joinedByTicket (:1564-1565), which matches only sharedFrom.ticket.
    3. A room this home was added to by add-member carries sharedFrom.remoteRoomId (:2439) and no ticket, so it matches neither: the link reads as a room we are not in.
    4. plugins/social/client.js:1698-1702 handles only claimed && joined; :1703-1707 only claimed. This case falls through to the preview card, and joinLocal (:1716-1749) ends with Asked to join … (:1745) after a claim that changes nothing, because the room is already in the sidebar.

    Acceptance

    1. Carry the room id: previewLocalInvite returns roomId: seen.roomId next to ticket/claimed (room-membership.js:1546-1557).
    2. joined stops depending on claimed: a room counts as here when it is origin === 'inbound-share', not hidden, holds a local (non-remote) Bot, and sharedFrom.ticket === ticket or sharedFrom.remoteRoomId === roomId. claimed keeps its server meaning — :1703-1707 still needs it for a claim whose room is not here.
    3. Client: branch on seen?.joined before seen?.claimed in previewLocal, with its own sentence (This group is already in your sidebar.), drawing no Join card and sending no claim. Re-pasting the same link repeats that sentence — Asked to join must never appear for a room that is already here.
    4. Tests: core/test/room-ticket-seat.test.js — the fake server's preview already returns roomId (:122-127); build the mirror through the ordinary add-member path (applyInboundRoomShare with { op: 'join', roomId: 'war', … }, no ticket — the shape :248 shows for the ticket path) and assert previewLocalInvite(link) gives claimed: false, joined: true. Knives: drop the remoteRoomId match → red; drop roomId from the reply → red.
    5. Client half is tested by source text, the way this repo already tests the shipped bundle (plugins/social/test/group-phone.test.js reads client.js): assert the joined branch precedes the claim and carries the new sentence. Do not build a browser harness for it.
    6. Unchanged on purpose: claimed-elsewhere (:1571) and the "Waiting for …" copy for a claim with no room here; no new endpoint, no change to seatOpenClaims (Join group stuck on "Asked to join…": host never seats Bots, joiner gets no sidebar row #1064/Seat an invite-link claim the host poll could no longer read #1162).
    7. Mirror: room-membership.js and the test both have twins under patches/ds-bot/files/; scripts/ds-bot-patches.mjs check exit 0.

    Owner: Dev3
    Reviewer: named in the PR body (must not be Dev3)

  3. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:socialFriends, invites, grants, Bot Social
    on Oct 25, 2026
  4. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev3

    Claimed. Branch: dev3/fix/1176-invite-link-already-seated, cut from bb96cc8f8d1a162985a061517e916c7cdd392d2b.

    Plan, in this order:

    1. Red first in core/test/room-ticket-seat.test.js — mirror the room through the ordinary add-member path (applyInboundRoomShare with { op: 'join', roomId: 'war', … }, no ticket) and assert previewLocalInvite(link) gives { claimed: false, joined: true }, with roomId in the reply. It should fail on joined before the fix.
    2. Fix core/src/host/room-membership.js: carry roomId, and compute joined from origin === 'inbound-share' + visible + a local Bot + (sharedFrom.ticket === ticket or sharedFrom.remoteRoomId === roomId), not from claimed. Then mirror both files under patches/ds-bot/files/ and run scripts/ds-bot-patches.mjs generate/check.
    3. Client: seen?.joined branch before seen?.claimed in previewLocal, sentence This group is already in your sidebar., no Join card, no claim. Checked by source text in the shipped client.js, no browser harness.
    4. Knives: drop the remoteRoomId match → red; drop roomId from the reply → red; client branch moved after claimed → red.
    5. docs/subsystems/social.md gets the sentence for the new state, changelog.d/1176-*.fixed.md added.
  5. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 25, 2026
  6. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 25, 2026
  7. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev3

    Done — merged as 96abd5ceb906cbaba6c12dad29f5a74e9e047da9 (PR #1187, PASS by Reviewer2 at c87ae808).

    Checked on main after the merge:

    • this issue is closed/completed, Fixes #1176 on its own line in the PR body;
    • changelog.d/1176-invite-link-already-seated.fixed.md is in main;
    • core-host.md says joined is decided by this home's own room (ticket or sharedFrom.remoteRoomId) and social.md says the dialog names the state before it reads claimed;
    • the fix itself is on main: roomIsHere in core/src/host/room-membership.js, the seen?.joined branch ahead of seen?.claimed in plugins/social/client.js, and the source-text case in plugins/social/test/invite-joined.test.js.

    agent-working / agent-ready / agent-pr cleared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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