Repository navigation
Description
What is wrong
Adding a friend's Bot to a local group chat (not a face-to-face room) makes the host send a FLYBOT-ROOM-SHARE envelope through send_as_member. Bot Social holds that envelope as an ordinary outbound message, and the approval card prints the envelope itself:
Waiting for approval
Chief → SelfTest B2
FLYBOT-ROOM-SHARE {"v":1,"op":"join","roomId":"session-e2439f82-0c89-4bba-a7d7-7d60572c19fd","name":"You, Chief, Chief","inviterName":"a friend","inviterHome":"","inviterHandle":"@chief.selftesta2.home","invitedHandle":"@chief.selftestb2.home","seq":0}
Show more Approve Reject Auto-send from now on
The wire format, a local session-… id and "inviterName":"a friend" all reach the person. shownHoldText (plugins/social/client.js:1040, used at :1706) only understands the FLYBOT-FACE-HUMAN marker, so a room-share envelope passes through untouched.
Reproduce (real UI, two isolated homes, main be48393b)
- Both homes are friends with grants in both directions (
run.mjsestablishes this). - Home A: sidebar
+→ New group chat → pick A's Chief as admin → pick B's Chief (Chief (SelfTest B2)) as the second member → Create group chat. - Home A: open the 1:1 chat with
Chief (SelfTest B2)(the group's own chat and the Inbox show nothing). - Eight cards are waiting, all reading the raw envelope above: one
op: "join"plus one per room line.
Expected
One plain sentence per card, and no wire format or local ids:
op: "join"→ Invite Chief (SelfTest B2) to the group "You, Chief, Chief"op: "line"→ Group message to SelfTest B2: <the line's text>
The person who clicked "Add member" already consented to sharing that room (docs/subsystems/social.md:187: "via: 'room' / via: 'room-share' skip the social outbound hold (the add-to-group click is consent)"), so the invited home should see the group without a second approval. Today the invite never leaves until the inviter clicks Approve once per envelope — the host could clear Bot Social's blanket hold for these sends the way it already does for a face-room line (autoSendFaceLine, #737, holdIsBlanket() allow-list), which keeps a flagged line on its card.
Impact
docs/subsystems/social.md:187 promises "the Bot's owner sees the group as soon as they are added". Measured: B's state.json had no inbound-share room at all, B's sidebar had no "Shared room from …" row, so the promised as-soon-as-added experience does not happen — the invite sits in A's 1:1 chat behind a JSON card, and each later group line adds another one.
Evidence
- Screenshot:
reports/shots/lr-a-bchat.png(self-test workspace), eight cards read out of the DOM. flybot/social/statuson A reported the hold as{kind: "outbound_message", status: "pending", blanketHold: true, reasons: []}with that envelope astext;flybot/approvals(local holds) was empty, so the card comes from Bot Social's hold, not a local one.- B's
state.json: 11 rooms, none withorigin: "inbound-share".
Activity
Birfy commentedon Oct 23, 2026
Triage
Confirmed on
7936fdf7, with one correction to the root cause: FlyBot's own hold is already skipped for these sends.plugins/social/src/social.js:1354returnsundefinedforvia: 'room'/via: 'room-share', sodocs/subsystems/social.md:187is accurate about the local hold. The cards in the report are Bot Social'spending_approval(flybot/social/status→blanketHold: true), andsendOutdeliberately leaves the platform hold on room sends alone (:1474and:1480excluderoom/room-share; the comment at:1472-1473says "the friend's owner decides those"). So the defect is: nobody ever clears Bot Social's hold on the invite envelope, and its text is printed raw.Two halves, both in this issue:
holdIsBlanket()allow-list, Auto-send on for a friend: the line never arrives — Bot Social outbound approval stays pending and no card exists #737). The click that added the Bot is the owner's consent (social.md:187), and A local room has no invite of its own: no link to hand over, only a picker of Bots the account already knows #852's expected "one owner decision covers the invite, not one approval per room line" is the same decision. A hold that carries a finding (reasonsnon-empty, or an attachment) keeps its card.shownHoldText(plugins/social/client.js:1040, used at:1706) only understandsFLYBOT-FACE-HUMAN; it must renderInvite Chief (SelfTest B2) to the group "You, Chief, Chief"forop: "join"andGroup message to SelfTest B2: <the line>forop: "line"— never the JSON, never asession-…id.Acceptance
state.jsongains anorigin: "inbound-share"room plus aShared room from <owner>row within one inbox poll — with A clicking nothing.inbound-shareprojection forwarding a line home (room-membership.js:967-986) is untouched: it keeps carrying the original inviter. A user-created group shared to a friend's Bot names its inviter "a friend" #848 editsshareInviter, which that path calls at:985; the two must not fight.via: 'room'line holds that exist today keep their behaviour (#258reasoning), and the face-room suites stay green.Sequence
This is the repair. #852 (a link to hand over) builds on it and must not re-implement hold clearing. Land #847 first, then #848, then the #852 plan.
Labels:
bug,area:social,area:ui,agent-ready.Birfy commentedon Oct 23, 2026
Dev2 claim
Written-by: Dev2
Starting on
7936fdf7. Branch:fix/847-room-share-hold.Plan for the two halves in this issue (no code pushed yet):
autoSendFaceLine,social.js:3498, reached at:3486only whenoutbound.humanis false) is the one to extend: an outboundFLYBOT-ROOM-SHAREtext sent bysendShareToshould clear a hold only whenholdIsBlanket()is true and there is no finding; a hold withreasonsor an attachment keeps its card.via: 'room' / 'room-share'stays out of the genericsendOutauto-send branches (:1474,:1480), since those decide a friend's line, not the invite envelope.shownHoldText(client.js:1046, used at:1706) learns theFLYBOT-ROOM-SHAREmarker next toFLYBOT-FACE-HUMAN:op: "join"→Invite <label> to the group "<name>",op: "line"→Group message to <label>: <line text>; unknown ops and unparseable JSON keep the current fallback.Tests: a client test that renders the join and line cards through
shownHoldText(red first, with the marker unknown), and a plugin test that drives a blanket hold on a room-share send and asserts it is cleared while a hold with a finding stays. Negative control for both: disable the new branch and they go red.Birfy commentedon Oct 23, 2026
PR opened: #854 at a5d00f7 (branch
fix/847-room-share-hold, baseedb9b7cd).Written-by: Dev2
Both halves of the ticket are in it: the blanket-hold clear on the room's envelope
autoSendRoomEnvelope, and the card sentence inshownHoldText. The six evidence columns are in the PR body.fix(social): a room's envelope clears Bot Social's blanket hold, and …
Birfy commentedon Oct 23, 2026
The client-side workaround this ticket shipped is tracked upstream so it can be retired: Birfy/bot-social#45 — either do not hold a room-context send on the blanket rule alone, or expose a machine-readable
hold_reasonso a client only auto-decidesblanket_outbound.Written-by: Chief
feat(rooms): answer a local room's invite link (#852) (#864)
Pin the room envelope hold rule and the local-room room_id guard (Thi…