Skip to content

Consume Bot Social’s hold_reason instead of inferring a blanket hold from reasons #865

Closed

Description

@Birfy

What is asked

Bot Social now returns a machine-readable hold_reason on an approval row (bot-social #51, merged as 461e04e2): risk | attachment | policy | blanket_outbound, strongest first. FlyBot still infers the same thing from reasons — plugins/social/src/social.js:122-132, holdIsBlanket — which is the fragile "exactly one reason, and it is the blanket marker" test #847 had to lean on.

Replace the inference with the field, and keep the old rule as the compatibility path for a server that does not send it yet.

Why it matters

  • blanket_outbound is the only value the connector may clear by itself; every other value means a human decides. reasons cannot draw that line once a hold of another kind also reports blanket-shaped reasons.
  • The face-room value face_room_auto_send_off (bot-social #53) is exactly that case: it is raised when the room's Auto-send switch is the only thing blocking a draftFaceRoomMessage send, and a DLP/risk finding on the same path still reports risk instead. A connector that clears it self-serves a bypass of the owner's switch.
  • The predicate already has three callers (autoSendRemoteLine, autoSendRoomEnvelope, and the face Auto-send path). One predicate reading one field is what keeps them from drifting.

Scope

  • plugins/social/src/social.js — the predicate (holdIsBlanket or its successor).
  • Make sure the field survives the path that decides: the decision reads a list_approvals row, and the view in between (approvalView) must not drop hold_reason.
  • docs/subsystems/social.md — the hold section names the field and the rule "only blanket_outbound is connector-decidable".
  • Tests in plugins/social/test/social.test.js; one changelog.d/ fragment; Fixes #<this>.

Acceptance

  1. Self-clear only when hold_reason === 'blanket_outbound'.
  2. risk, attachment, policy, face_room_auto_send_off, and any value this build does not know keep their card and wait for the owner. face_room_auto_send_off must be treated exactly like risk/attachment/policy — there is no second allow-list for it.
  3. A server that sends no hold_reason still gets today's rule: reasons exactly the blanket marker and no risk flags. New field absent must not turn into "not blanket" (that would strand every hold on an older server).
  4. When the field and reasons disagree, the field wins: hold_reason: 'policy' with blanket-looking reasons keeps its card.
  5. Negative controls: reverting to reasons-only reds case 4; treating a missing field as non-blanket reds case 3; allowing a non-blanket_outbound value reds case 2 — and that same control must red the face_room_auto_send_off case too, so the new value is pinned by a predicate, not by a name list.
  6. One predicate. No call site may keep its own copy of "is this blanket".

Note

The face-room value's name is now fixed: face_room_auto_send_off (bot-social #53 @ da6b13cd, base 461e04e2). It appears only when the room Auto-send switch alone blocks the send — with a DLP finding the same path reports risk, and with auto_approve_face_rooms on there is no hold at all. Because the rule is "only blanket_outbound", the new value needs no code of its own: add it to the test table, keep it out of the self-clear branch.

Activity

  1. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:socialFriends, invites, grants, Bot Social
    enhancementNew feature or request
    on Oct 23, 2026
  2. Birfy commented on Oct 23, 2026

    @Birfy
    CollaboratorAuthor

    Acceptance is now pinned to the real value name: face_room_auto_send_off (bot-social #53 @ da6b13cd, base 461e04e2). It is treated exactly like risk/attachment/policy — card stays, owner decides, no second allow-list. Still agent-ready; nothing else moved.

  3. self-assigned this
    on Oct 23, 2026
  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 23, 2026
  5. Birfy commented on Oct 23, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev4

    Claimed. Branch fix/865-hold-reason, based on fdecbfa0.

    What I am replacing, at plugins/social/src/social.js:128: holdIsBlanket infers the hold from reasons
    ("exactly one entry and it is the blanket marker, and no risk flags"). Bot Social now says it in one field
    (bot-social #51 + #53, merged as 31431c97), so the predicate reads hold_reason first and keeps the
    reasons allow-list only as the compatibility path for a server that sends no field.

    Rules I am implementing, in the order the issue states them:

    1. self-clear only when hold_reason === 'blanket_outbound';
    2. risk / attachment / policy and any value this build does not know — including the face-room
      face_room_auto_send_off that #53 adds — keep their card;
    3. no field on the row: today's reasons rule, so an older server's holds are not stranded;
    4. the field wins when the two disagree.

    One predicate stays: the three callers (autoSendRemoteLine, autoSendRoomEnvelope,
    autoSendFaceLine) all go through holdIsBlanket, and approvalView keeps hold_reason on the view
    as holdReason so nothing re-infers it.

  6. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 23, 2026
  7. Birfy commented on Oct 23, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev4

    PR is #869 @ ef37d0bd, based on 699b650d (after #867), 4 files:

    • plugins/social/src/social.js — the predicate reads hold_reason, and approvalView keeps the field as holdReason;
    • plugins/social/test/social.test.js — three #865 tests plus the mock sending hold_reason;
    • docs/subsystems/social.md, changelog.d/865-consume-hold-reason.fixed.md.
  8. Birfy commented on Oct 23, 2026

    @Birfy
    CollaboratorAuthor

    This issue and #879 are the same change seen from two sides: #879 is the defect on main today (an attachment or suspected-injection hold self-clears because holdIsBlanket reads reasons, while the finding lives only in hold_reason), and this issue is the work that fixes it. #869 is the vehicle for both — it is the shared predicate change.

    So: no second PR, and when #869 merges it closes both. Whoever edits the PR body should carry Fixes #879 and Fixes #865, so neither issue is left open on a merged fix. The acceptance here and there does not conflict; #879 adds the four-row truth table that this issue's case 2 and case 5 describe in prose.

  9. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    on Oct 23, 2026
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 SocialenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions