Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 5fbe53113e8a43969c8f22f513253910
Branch: dev/3-settings-seat-join-dedupe
Base: b7fa18c
At: 2026-11-01T08:41:20Z
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.
Written-by: FlyBot Lead
What happens
A seat change saved from the group-settings page moves the room's name twice to the same guest: the guest already seated receives two identical join envelopes instead of one.
Measured on 2aa88a8c (the #2004 PR head) against its base b7fa18c7, same probe both sides:
updateRoom({ addParticipants })→ a guest already seated gets 1 join on the base, 2 on the tip;updateRoom({ removeParticipants })→ same, 1 → 2;- the two envelopes are byte-identical (
seq,name,rosterall equal).
The receiver is idempotent (roster overwritten, history keyed by seq), so nothing is visible to the user; what is wrong is the host sending the same broadcast twice for one seat change.
Cause
core/src/host/roster.js:471 takes const before = room.name before the participant loop. The seat loop (:480-485) now goes through addRoomParticipant / removeRoomParticipant, which rename the room and broadcast once themselves (#2004). Then :486 recomputes autoRoomName, :488 computes nameChanged = room.name !== before — still true, because before predates the seat change — and :501 if (nameChanged || noticeChanged) void rt.notifyRoomShare?.(room, { op: 'join' }) sends the second copy.
Expected
- One settings-page seat change (add or remove) delivers exactly one
jointo a guest already seated in the room, carrying the final name — base parity (1), not 2. - A newly arriving seat gets no more than the base delivers on this path.
#1949keeps working: an explicit rename (patch.name) or a notice edit saved from the settings page still reaches the guests.- Other callers of
addRoomParticipant/removeRoomParticipantkeep today's single broadcast; this must not regress them to the base behaviour of sending nothing.
Scope
- Dedupe only: let the settings path own its single
joinand suppress the seat path's broadcast when it is called fromupdateRoom's participant loop (an option on the call, e.g.{ broadcast: false }), becauseupdateRoomalready sends onejoinafter the save. - Do not fix this by moving
beforelater: that would swallow the explicit rename's broadcast, which is#1949's whole point. - Do not restructure
updateRoom,roster.js's other paths or the naming formula; no new envelope op, no client change. - The new test must be able to go red on its own: with the dedupe removed, only it fails.
- Assertion caveat, measured, not guessed: after the suppression,
updateRoom's ownvoid rt.notifyRoomShare(...)is not awaited, so "how many joins a newly arriving seat gets" is microtask-timing dependent (a run on2aa88a8cgave 1 where the base gives 2). Pin the already-seated guest at 1 (stable). If the test must assert the settings path's own send, either await it in the implementation or flush explicitly once, then assert. - Failure shape to state in the PR: the suppressed broadcast is a no-op (not a swallowed error); the settings path's send stays
void … .catch(warn)after the save.
Duplicate check (live main b7fa18c7, 2026-11-01)
duplicate join guest→ 6 issues:#2010,#2004,#2009,#1939,#1949,#1945; only#2004is the PR that introduced this, and this follow-up is not inside its scope (its tip is frozen with aVerdict: PASS).two joins notifyRoomShare→#2004,#1949,#1952; none about a doubled broadcast from one save.updateRoom participants join→#1970,#1968(automatic rename on member rename/removal),#1821(unrelated RFC).seat change two joins→#2004/#1995/#1999(the name itself),#1082(claim seating),#1949/#1952(the rename must reach guests).- Nothing open or closed covers "one settings-page seat change sends the same
jointwice", so this is not a duplicate.
Activity
HugoXK commentedon Nov 1, 2026
Release
Written-by: FlyBot Lead
Released: 5fbe53113e8a43969c8f22f513253910
Reason: merged as #2013 (6891cd9); Lead asked to stop the heartbeat
At: 2026-11-01T09:17:33Z
HugoXK commentedon Nov 1, 2026
Heartbeat
Written-by: FlyBot Lead
Still-working: 5fbe53113e8a43969c8f22f513253910
At: 2026-11-01T08:48:07Z
HugoXK commentedon Nov 1, 2026
Heartbeat
Written-by: FlyBot Lead
Still-working: 5fbe53113e8a43969c8f22f513253910
At: 2026-11-01T08:51:29Z
host: a settings-page seat change tells the guest already seated once (…