Skip to content

Held reply to a friend in the replying Bot's own chat: draft looks sent, card detached and names the Bot not the person, no trace after Approve/Reject (regression of #226) #418

Closed

Description

@Birfy

Summary

When a friend's line makes my Bot reply and the reply is held for my approval (A side), the held draft already looks like a sent reply, the card floats detached at the bottom right and names the wrong recipient, and after Approve or Reject nothing in the chat says what happened. A rejected reply and a sent reply look the same forever. This is the direct-chat state model #226 asked for (held bubble, controls attached, clear after-state), now seen in the replying Bot's own chat (the #254 path), so it is partly a regression of #226.

Environment

Common setup (B talks to A's Chief)

On B, open the sidebar row for A's Chief (Chief + grey SelfA1238 + globe) and send, one at a time, waiting for each answer:

  1. Hi Chief, this is B. What is 2+2? Reply in one short line. → A's Chief drafts 4.; on A click Reject.
  2. Second test: what is 3+3? One line. → draft 6.; on A click Approve.
  3. Third test: what is 4+4? One line. → draft 8.; on A click Always approve.
  4. Fourth test: 5+5? One line. and Fifth test: 6+6? One line. → 10. and 12. go out without a card.

Repro

  1. Run the common setup steps 1–2. Stay on A's own Chief chat (where B's line lands, see Friend DM: a shared Bot's reply to the grantee is silently denied (grantee's Bot not shared back), never held or delivered #272/A friend Bot's reply to a typed DM is held on its owner and no approval card ever shows (overlay hook crash, no in-chat card for the replying Bot) #254) while each reply is drafted.
  2. Before deciding, read the chat and the card. Click Reject on 4., then Approve on 6..
  3. After each decision, read the chat, the sidebar row and B's chat.

Actual (A, the approver)

  • The held draft looks sent. After › Thought it through, the draft 4. is an ordinary grey Bot bubble, the same as any delivered reply. No held style, no "waiting" mark on it.
  • The card is detached and names the wrong party. It floats at the bottom right above the composer, far from the bubble, and reads Waiting for approval / Chief → Chief / 4., with a blue Always approve text link on the left and Approve (primary) and Reject on the right. The recipient is B's talk-through Bot; the person who gets the line is SelfB1238, and the card does not say the line goes to SelfB1238. Screenshot 06-A-second-card-before-approve.png: A's Chief chat with B's two lines (labelled SelfB1238, grey person icon), the NEW divider, bubbles 4. and 6. that look identical, and the card for 6. alone at the bottom right.
  • After Reject: the card shows Rejected for a moment and disappears. The bubble 4. stays and still looks sent; the sidebar row preview still reads 4.. Screenshot 04-A-after-reject.png: chat ends with the plain bubble 4., row preview 4., no card, no note.
  • After Approve: the card disappears with no Sent trace. Screenshot 08-A-after-approve-no-status.png: bubbles 4. (rejected) and 6. (sent) look exactly the same.
  • No waiting marker in the list. The only mark on the Chief row is a small orange dot on its avatar, which is there in every screenshot before and after the decisions (04, 06, 08, 09), so it does not read as "waiting for you".
  • B got nothing for 4. (rejected) and 6. arrived once approved. B never sees that a reply is waiting. Per social.md invariant 8 ("The sender sees nothing until it is approved") that part is by design; noted only so a maintainer can confirm.

Why (code read on a7f51e8; hunch)

  • The held style exists only for face rooms: core/src/client/user-message.js L147 (held requires room.origin === 'face-to-face') and the GroupMessage held-line state (Face-to-face join/waiting/leave polish: silent disabled Join, frozen countdown, waiting card twice, Leave next to Auto-send and unconfirmed in waiting, held lines shown twice #306, core/src/client/cells.js). A local hold of a Bot's own auto-reply in its own chat has no bubble state, so the DSH assistant turn renders the draft as a normal reply.
  • The card is the flybot.session.dock slot social-approval (plugins/social/client.js L1927, ChatApproval ~L898–931), always drawn in the dock above the composer, not next to the bubble. After a decision it renders Approved/Rejected briefly and then the item leaves the list, so nothing persists.
  • Chief → Chief: holdParties (~L870) uses item.toName (the receiving Bot) instead of the person (owner of @chief.selfb1238.home).
  • docs/subsystems/social.md disagrees with itself on card placement (L72 "left-aligned like a bubble", L104 "right-aligned bubbles").

Expected (FlyBot design: in-chat approval with explicit buttons, simplicity/consistency)

Suggested scope / files

  • core/src/client/user-message.js, core/src/client/cells.js (held state for a local Bot reply held by flybot/approvals; match by approval id like room.pendingApprovals).
  • plugins/social/client.js: ChatApproval, ChatApprovalDock, holdParties, approvalsForOpenChat (~L933).
  • core/src/host/hooks.js (release / reject path) so a decided hold leaves a marker on the turn.
  • docs/subsystems/social.md (one card-placement rule).
  • Tests: plugins/social/test/social.test.js, core client tests for the held/decided bubble.

Acceptance criteria

  • Before a decision the held reply is visibly different from a sent one and carries the decision buttons in place.
  • The card names the person who will receive it (SelfB1238).
  • After Reject the reply is shown as not sent, and the list preview does not show it as the last message.
  • After Approve the reply looks sent; rejected and sent replies are distinguishable.
  • The Bot's sidebar row shows a wait badge while a hold is open and clears immediately on decide.

Related: #226 (closed, same model for the friend's chat), #254, #271, #278, #306, #371, #349.

Activity

  1. added
    bugSomething isn't working
    area:socialFriends, invites, grants, Bot Social
    area:uiWeb/desktop UI and copy
    self-testFiled by the product self-test routine (issues only)
    on Oct 19, 2026
  2. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Triage on main a7f51e8, 2026-10-19 ~14:15 Asia/Shanghai: design conflicts resolved, spec clear; ready to develop. Checked: #226 (same held-bubble model for the friend chat), #306/#168 (face-room held line), #349 (explicit buttons only), #384 (naming), social.md invariant 8 (sender sees nothing until approved; that part stays). Owner-delegated decision on the open detail: one card-placement rule, the decision buttons sit on the held bubble in place (no floating copy in the dock for that chat); docs/subsystems/social.md is made to say the same.

  3. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 19, 2026
  4. self-assigned this
    on Oct 19, 2026
  5. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Claimed by the maintenance routine (2026-10-19 17:00 Asia/Shanghai). Branch: Birfy:fix/418-held-reply-in-place off main 31c4c2a. Scope per the 06:07 UTC triage: held reply visibly held in place with the decision buttons on it (no floating dock copy for that chat), card names the person, Sent / Not sent after-state, wait badge on the Bot's row; social.md gets one card-placement rule.

  6. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Minor details decided while implementing (PR #430):

    • The decision sits on the reply's closing bubble (the turn's last text); an earlier text of the same turn is only marked held.
    • No dock copy in either chat (the Bot's own chat or the friend's chat): one place per approval, the bubble. The overlay pointer, when away, leads to the chat the reply answers.
    • Inline card: Waiting for approval, Chief → SelfB1238, Approve / Reject and the quiet Always approve link (same as the dock card), without repeating the text (the bubble is the text).
    • After-state: approved → quiet Sent to SelfB1238; rejected / stale / denied → muted bubble + Not sent; failed → Not sent: delivery failed + Retry.
    • Recipient: the friend's owner name (server roster, else the owner on that Bot's last inbound line); a listed friend chat keeps Friend's Bot rows: two name formats ('Helper · SelfB0023's Bot' vs 'SelfA0023's Chief'), two-line wrap, no preview, inset highlight, faint marker, same avatar as own Chief #384 naming (Chief (SelfB1238)).
    • Older holds without the turn tag keep their dock card.
  7. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 20, 2026
  8. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 21, 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 Socialarea:uiWeb/desktop UI and copybugSomething isn't workingself-testFiled by the product self-test routine (issues only)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions