mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
## Summary In Desktop's standalone Forums, selecting an owned agent from another device could leave a post or reply unsendable if the agent had not joined the forum. This adds **Invite / Cancel** to the send flow so you can resolve membership without leaving your draft. - **Invite** checks response policy and your permission to add members, adds the agent to the forum, waits for refreshed membership, then rechecks authorization before posting to the original destination. Membership is forum-wide, not limited to one post. - **Cancel / Escape** keeps the text, attachments and selected recipients for retry. Unlike chat's **Do nothing / Send anyway**, this dialog has no reference-only send choice. Invite is disabled while pending; Cancel remains available. - Leaving the source post/reply cancels its pending invitation, even if you return. Errors remain visible, focus returns to the initiating editor when appropriate, and late completion cannot resume a cancelled post or interfere with a newer attempt. - A rejected send restores text, uploaded media and exact selected recipients to the source draft only if no newer edit, deletion, upload intent or send supersedes it. Clipboard verification settles before recipient capture, with stale edits/navigation fenced out. ### Related issue Targets `main` after #7124 merged. This PR reuses its publication checks and draft protection; the five forum commits have been replayed unchanged onto the merged parent. Owned-agent discovery (#7122) is already merged. Split from #7114. Forum creation/templates, channel-less Notes and local-agent management are unchanged. Duplicate-name binding from #7133 is already merged and retained by this stack. Inviting does not start a remote agent or promise that it is online or will reply. ### Testing Forum composer lifecycle tests, including clipboard-settlement cases, and TypeScript/changed-file formatting checks passed after the restack. Earlier invitation, focus and transport-recovery browser coverage is retained, not claimed as a fresh full browser run on this head. See [live CI](https://github.com/block/buzz/pull/7125/checks) for current-head results. Browser evidence uses mock IPC; no full local `just ci` pass or native/live-relay validation is claimed. To try it: open a forum post or reply, select an owned nonmember agent and send. Cancel, then retry without reselecting; Invite should add that agent before posting. Deny the add to check the visible error and retained draft. Navigate away/back during a pending invitation or rejected send; no stale publication or overwrite of a newer draft should occur.  *Earlier mock-browser capture, not current-head runtime proof. [Error and successful-post captures](https://github.com/block/buzz/pull/7125#issuecomment-5513883462); no before-state/native capture available.* **Limits:** cancellation cannot undo accepted membership changes or dispatched posts; authorization and publication are not atomic. Recovery is same-window, subject to browser storage limits, and is not a durable in-flight send journal: reload/crash can lose a pending snapshot. Cross-window coordination and in-flight upload custody are unchanged. The parent's legacy member-agent compatibility does not establish ownership for nonmember invitations. --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
53 lines
3.2 KiB
Markdown
53 lines
3.2 KiB
Markdown
# Standalone forum agent invitation
|
|
|
|
The standalone forum composer reuses the remote mention preparation/publication
|
|
contract (`docs/remote-mention-routing.md`). An eligible owned relay nonmember
|
|
opens an explicit Invite/Cancel dialog. There is no implicit reference-only send.
|
|
|
|
Invite revalidates the captured exact recipients in the preparation phase,
|
|
performs the existing authorized bot-member add, awaits membership invalidation,
|
|
then performs a fresh publication-phase check against the captured destination.
|
|
A successful add alone is never authorization to publish.
|
|
|
|
Cancel resolves the pending submission without clearing its text or selected
|
|
identity. Retry can use the same exact key. Rejected adds and preparation errors
|
|
remain visible inside the dialog; final authorization errors remain visible in
|
|
the composer and retain its draft. Channel change/unmount cancels pending work,
|
|
and completions must still belong to the mounted captured channel. An add already
|
|
accepted by the relay is not rolled back on cancellation; no message is sent.
|
|
|
|
This adapter does not create/manage local agents or change notes/channel-less
|
|
surfaces. Regression coverage in `forum-agent-invitation.spec.ts` covers exact
|
|
p-tags, membership refresh before final authorization, cancel/retry, three add
|
|
failures, policy revocation before Invite and during add, and navigation during
|
|
an outstanding add. Browser fixtures are mock IPC; signed native ownership and
|
|
membership validation live in PR6, not in the frontend bridge.
|
|
|
|
## Dispatched reply recovery
|
|
|
|
After authorized dispatch, transport rejection recovers the captured text,
|
|
completed/uploaded media and exact selected mention refs under the source draft
|
|
key. This extends the standalone-forum follow-up noted in the shared routing
|
|
document: a cached A → B → A visit with no new intent no longer loses its reply.
|
|
The departed editor is never called. A pristine, empty current source visit may
|
|
adopt the recovered store entry; B cannot receive A's text or attachments.
|
|
|
|
The existing same-window draft authority fences recovery across visits. New text
|
|
(including edit → delete), completed-media changes/upload intent, selected refs,
|
|
explicit draft deletion, a new send or a community/identity reset revoke older
|
|
recovery. A different existing stored payload is not overwritten. Optimistic
|
|
clear and recovery are programmatic, not authored deletion; synchronous media
|
|
snapshots protect cleanup immediately after recovery. No recovery path repeats
|
|
publication, undoes an accepted add or releases another visit's pending send.
|
|
|
|
`ForumComposer.lifecycle.test.mjs` exercises ordinary and invited sends,
|
|
source-key re-entry, newer intent/deletion/media/refs, scope reset and late
|
|
completion. The browser spec additionally rejects deferred `send_channel_message`
|
|
after cached A → B → A with uploaded media and verifies recovery versus newer
|
|
text/deletion, B isolation and exact recipients on an explicit retry.
|
|
|
|
Recovery is not a durable in-flight send journal: renderer reload/crash while the
|
|
transport is pending can still lose the in-memory snapshot. Local in-flight
|
|
upload custody, cross-window coordination, native authorization and atomic
|
|
relay publication are outside this correction.
|