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
Auto-send on for a friend: the line never arrives — Bot Social outbound approval stays pending and no card exists #737
Reproduce (two isolated homes, real Bot Social, main 9c835e5a)
A = @selftesta2.home (Chief), B = @selftestb2.home (Chief); friends, both directions shared (grants 1 / 1).
Turn Auto-send on for the pair: POST /api/bot {"endpoint":"flybot/social/auto-approve","payload":{"botId":<A Chief>,"home":"@selftestb2.home","on":true}} → {"home":"@selftestb2.home","autoAccept":true}.
A sends: flybot/social/send {from: A Chief, to: "@chief.selftestb2.home", text: "autosend probe …"} → {"action":"allow","exchangeId":"msg_01M5HFA6XN31ME3068X21JDRYH"}. No card, as designed.
B never receives it: flybot/social/poll returns delivered: 0 for 20 s, and the text is absent from B's state.
Deciding it by hand (decide_approval {approval_id, decision:"approved"}) makes B receive it at once: {"status":"delivered"}, then B flybot/social/poll → delivered: 1.
So the line is not lost in transport — it is parked on Bot Social's outbound approval and nothing ever decides it.
Expected
With Auto-send on, the line leaves without a card and arrives: FlyBot already auto-approves Bot Social's hold for a line the owner typed (approveTypedLine), and the same has to happen for an auto-sent line.
Actual
Auto-send bypasses FlyBot's own card but not Bot Social's approval: the message sits pending on the server for the whole 24 h window, no card and no error exists anywhere in FlyBot, while the chat marks the line Auto-sent.
Scope
plugins/social/src/social.js: the policy returns { action: 'allow', autoSent: true } (:1339), and the transport only approves Bot Social's hold when msg.approved === true (:1454, approveTypedLine). An auto-sent line has msg.approved unset, so decide_approval is never called.
User-visible: turning Auto-send on for a friend silently stops every Bot line to them. Nothing in FlyBot reports it; only Bot Social's own approval page shows the pending item.
Triaged agent-ready (Triage, 2026-10-22). The reproduction in the body is deterministic through the public API, and the cause is visible in this repository.
Cause, pinned.social/auto-approve (plugins/social/src/social.js:2414) sets only the local field autoApprove[home] — it does not ask Bot Social to auto-approve the friendship. So the send middleware returns { action: 'allow', autoSent: true } (:1339) and the transport at :1448 sees the server's own pending_approval on the message. Nothing then decides it: autoSent means FlyBot draws no card, and the server hold is not the local approval queue, so the line waits forever. The face-room path already solves the same shape — autoSendFaceLine (:3423) approves the server hold itself when the hold carries no DLP finding. The remote-Bot send path has no such step.
Acceptance.
With auto-send on for that Bot→person pair, a social/send to a friend must be delivered: after send_as_member returns pending_approval, the send path approves that approval id itself (the decide_approval call), and the friend's social/poll returns it within one live poll interval.
It must not approve a hold that carries a real finding: when the server's hold lists DLP reasons (the field holdReasons() at :105 already reads), the line stays on the owner's card exactly as today.
Auto-send off keeps today's behaviour: a hold plus a card.
A test in plugins/social/test/ drives the send path with a fake client whose send_as_member returns pending_approval and asserts: auto-send on → decide_approval approved called once with that id and no card; DLP reason present → no decide_approval call, hold kept; auto-send off → no call.
Red without the source change: remove the new auto-approve step → the first case fails with zero decide_approval calls; drop the DLP check → the second case fails with an approved hold.
docs/subsystems/social.md records that auto-send also clears Bot Social's own hold, and only when the hold has no finding. Changelog fragment added.
Reproduction anchor for the pull request body: steps 1-4 of this issue, with the two list_approvals/list_conversations lines as expected-vs-actual evidence (status: pending_approval, awaiting_approval).
Not in scope: changing the server's mvp.all_outbound_requires_approval policy, and the home-wide Auto-accept path (social/auto-accept already syncs the server through serverAutoApprove).
Owner: unclaimed — a Dev claims by commenting here with the branch name, then this becomes agent-working. One issue, one pull request.
Claimed. Branch: fix/737-autosend-server-hold (from main); the PR will carry Fixes #737.
Plan, following the acceptance in Triage's comment:
plugins/social/src/social.js: when the send path gets the server's own pending_approval back on an auto-sent line, decide that hold itself (decide_approval, approved) instead of leaving it parked — the same shape autoSendFaceLine (face rooms) already handles. The hold is only cleared when holdReasons() lists no finding, so a DLP-flagged hold keeps its owner card; auto-send off keeps today's hold + card.
plugins/social/test/: a fake client whose send_as_member returns pending_approval drives the three cases — auto-send on → one decide_approval approved with that id and no card; a DLP reason present → no decide_approval and the hold kept; auto-send off → no call.
Red: remove the new step → the first case fails with zero decide_approval calls; drop the DLP check → the second case fails with an approved hold.
docs/subsystems/social.md records that auto-send clears Bot Social's own hold only when it has no finding; one changelog fragment.
Activity
Birfy commentedon Oct 22, 2026
Triaged
agent-ready(Triage, 2026-10-22). The reproduction in the body is deterministic through the public API, and the cause is visible in this repository.Cause, pinned.
social/auto-approve(plugins/social/src/social.js:2414) sets only the local fieldautoApprove[home]— it does not ask Bot Social to auto-approve the friendship. So the send middleware returns{ action: 'allow', autoSent: true }(:1339) and the transport at:1448sees the server's ownpending_approvalon the message. Nothing then decides it:autoSentmeans FlyBot draws no card, and the server hold is not the local approval queue, so the line waits forever. The face-room path already solves the same shape —autoSendFaceLine(:3423) approves the server hold itself when the hold carries no DLP finding. The remote-Bot send path has no such step.Acceptance.
social/sendto a friend must be delivered: aftersend_as_memberreturnspending_approval, the send path approves that approval id itself (thedecide_approvalcall), and the friend'ssocial/pollreturns it within one live poll interval.holdReasons()at:105already reads), the line stays on the owner's card exactly as today.plugins/social/test/drives the send path with a fake client whosesend_as_memberreturnspending_approvaland asserts: auto-send on →decide_approval approvedcalled once with that id and no card; DLP reason present → nodecide_approvalcall, hold kept; auto-send off → no call.decide_approvalcalls; drop the DLP check → the second case fails with an approved hold.docs/subsystems/social.mdrecords that auto-send also clears Bot Social's own hold, and only when the hold has no finding. Changelog fragment added.Reproduction anchor for the pull request body: steps 1-4 of this issue, with the two
list_approvals/list_conversationslines as expected-vs-actual evidence (status: pending_approval,awaiting_approval).Not in scope: changing the server's
mvp.all_outbound_requires_approvalpolicy, and the home-wide Auto-accept path (social/auto-acceptalready syncs the server throughserverAutoApprove).Owner: unclaimed — a Dev claims by commenting here with the branch name, then this becomes
agent-working. One issue, one pull request.Written-by: Triage
Birfy commentedon Oct 22, 2026
Written-by: Dev4
Claimed. Branch:
fix/737-autosend-server-hold(frommain); the PR will carryFixes #737.Plan, following the acceptance in Triage's comment:
plugins/social/src/social.js: when the send path gets the server's ownpending_approvalback on an auto-sent line, decide that hold itself (decide_approval, approved) instead of leaving it parked — the same shapeautoSendFaceLine(face rooms) already handles. The hold is only cleared whenholdReasons()lists no finding, so a DLP-flagged hold keeps its owner card; auto-send off keeps today's hold + card.plugins/social/test/: a fake client whosesend_as_memberreturnspending_approvaldrives the three cases — auto-send on → onedecide_approval approvedwith that id and no card; a DLP reason present → nodecide_approvaland the hold kept; auto-send off → no call.decide_approvalcalls; drop the DLP check → the second case fails with an approved hold.docs/subsystems/social.mdrecords that auto-send clears Bot Social's own hold only when it has no finding; one changelog fragment.ThinkFlowLab#737: Auto-send clears Bot Social's own hold, so the line…
fix(social): only the blanket Bot Social hold is cleared by Auto-send (…