fix(desktop): authorize remote mentions at publication - #7124
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
jedwards27
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Reviewed f3ad8ad2d202047da1170516ba8d072ecec777e0..7ffead0f8ae128782991153054abd388e4ff04d9 (exact head 7ffead0f8ae128782991153054abd388e4ff04d9).
Risk: high — this changes mention authorization, membership mutation, publication recipients, async cancellation, and draft recovery across renderer→Tauri→relay boundaries.
Behavior/contracts traced: owned relay-agent discovery vs local custody; preparation-time invitation eligibility vs publication-time destination membership; channel/thread/new-DM destination binding; member/bot adds; notifying p recipients vs reference-only mention tags; edits and media continuation; Escape/navigation/unmount/replacement cancellation; cross-visit draft ownership and buffered timeline catch-up.
Findings: no blocking or non-blocking code/product defects found. Fresh relay evidence and fresh local-runtime evidence authorize only their own identities; unavailable directories fail closed. Selected recipients are not silently discarded. Final validation binds the eventual destination, while reference-only send strips notification recipients but retains textual references. Cancellation and late failure cannot revive abandoned intent or overwrite a newer/explicitly cleared draft.
Author action: none.
Verification owner: CI/release gate for the remaining broad/package-native confidence gaps; no author rework.
Validation at the reviewed exact head:
- Independent systems lane: desktop typecheck passed; 87 focused revalidation/draft/edit/cancellation tests passed.
- Independent product/UI lane: 124 focused unit tests and 18 isolated production-seam Playwright tests passed, including invite/pending/failure, policy and membership revocation, add/publish failures, both DM variants, navigation/unmount, duplicate action, reference-only/media, and cross-thread/cross-visit recovery.
- Additional reviewer run: the full Desktop JS test command completed with 5,882/5,882 passing.
- GitHub exact-head checks are successful: Desktop Core, all four Desktop Smoke E2E shards, Desktop E2E Relay, both Desktop E2E Integration shards and aggregate, macOS build, Semgrep, zizmor, and DCO. PR remains mergeable at the pinned base/head.
Manual/native evidence: reviewed the supplied invite, pending, and authorization-error captures; the distinct actions and failure state are clear. No independent packaged Tauri/hardware journey was completed.
Residual risk: one independent broad Desktop run timed out/interrupted without an observed assertion failure, and the first Playwright attempt collided with another reviewer server before the isolated rerun passed. Packaged-native behavior was not independently witnessed. Exact-head CI plus the isolated production-seam coverage owns those confidence gaps; neither establishes an author-actionable defect.
— :bot: Jude’s code review agent
jedwards27
left a comment
There was a problem hiding this comment.
Review verdict: approve
Reviewed the exact live head 7ffead0f8ae128782991153054abd388e4ff04d9 and integrated both assigned review lanes. No author-actionable defect remains.
The change closes the publication boundary correctly: remotely supplied mentions are re-authorized before publication rather than trusting stale draft state, while the existing local/exact-recipient behavior remains intact. Both independent lanes reported clear.
Verification
- Full Desktop package suite at this exact head: 5,882/5,882 passed.
- Focused changed-path evidence: 124/124 passed.
- Browser E2E evidence: 18/18 passed.
- Mutation/regression proof exercised the authorization fence and failed when the protective behavior was removed.
Residual native/Tauri and live-relay observation is a reviewer/release confidence gap, not author rework.
— :bot: Jude’s code review agent
f3ad8ad to
ae23c1c
Compare
7ffead0 to
1144465
Compare
|
@jedwards27 — requesting renewed formal review of exact published head This is the independently scoped-approved routing integration: seven original patches replay unchanged; two reconciliations preserve root's generic publication-error toast alongside authorization errors and preserve programmatic editability updates. Two added production-hook tests require the generic error, recovered draft and released pending state for normal and queued-media publication. No other source change was made during publication. Validation/provenance is detailed in the updated PR body: 5,995 Desktop / 42 focused / 22 isolated mock-IPC browser + 1 voice-note tests passed on the integration candidate before its semantics-preserving formatting amendment; independent AST comparison plus 4 fresh final-head assertions cover that amendment. Final publication typecheck, amended-test formatting and diff checks pass. These are not live-native/relay certification, and no new full No inline review threads or author-actionable comments existed at publication. The two older informational screenshot comments were minimized as outdated while keeping the evidence linked in the body and retaining their audit history. Formal reviews were not modified. |
jedwards27
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Reviewed 3a56d17824522580fe04cae463b54f4c7ba66021..1144465d00273cf74b7c22544ae5a3299bd98560 (exact head 1144465d00273cf74b7c22544ae5a3299bd98560). This supersedes my prior approval at 7ffead0f8ae128782991153054abd388e4ff04d9.
Risk: high — mention authorization, membership mutation, publication recipients, async cancellation, and draft recovery cross renderer→Tauri→relay boundaries.
Behavior/contracts traced: reconciliation onto the newly approved discovery root; preparation eligibility vs publication-time membership; channel/thread/new-DM destination binding; member/bot adds; notifying recipients vs reference-only tags; generic vs authorization errors; edit/media continuations; Escape/navigation/unmount/replacement cancellation; cross-visit draft authority; buffered timeline catch-up.
Findings: no blocking or non-blocking code/product defects found. Range-diff preserves the prior routing/recovery series; the meaningful reconciliation delta keeps the base branch's generic formatMessageSendError behavior while retaining the specific authorization error. Publication re-fetches selected identities for the eventual destination, unavailable evidence fails closed, and selected recipients are not silently discarded. Reference-only send remains distinct from Invite and Cancel. Late cancellation/failure cannot revive abandoned intent or overwrite a newer or explicitly cleared draft.
Author action: none.
Verification owner: CI/release gate for completion of any still-running required jobs and any desired packaged-native/live-relay observation; no author rework.
Validation at the reviewed exact head:
- Two independent full Desktop JS runs passed
5,995/5,995; exact-head E2E app build passed. - Isolated
remote-owned-mentions.spec.tspassed18/18, covering revocation/no-send, invite/reference-only, delayed add/publish cancellation, A→B→A draft authority, media, and catch-up routing. - Additional focused rerun passed
42/42cancellation/recovery/publication-error tests. git diff --checkand review preflight passed; base/head remained exact, clean, mergeable, with no unresolved review threads.- At submission, relay/integration E2E, both integration shards, macOS and Windows builds, Semgrep, zizmor, and DCO were green; Desktop Core and four smoke shards were still running, with no failed required gate.
Manual/native evidence: source and renderer/browser evidence cover the visible states and production renderer flow. No independent packaged Tauri/live-relay native authorization journey was completed for this changed head.
Residual risk: browser tests use mock IPC and therefore do not independently certify the live Tauri relay-directory query. Initial focused Playwright attempts collided with an unrelated process on port 4173; the isolated port 4184 rerun passed. These are confidence/tooling gaps, not author-actionable defects.
— :bot: Jude’s code review agent
🤖 ## Summary An agent you own could be missing from **New message → To:** and **Channel members → Add people and agents** on a machine that has never managed it. This PR lets those existing lists find your agent without requiring a shared channel first. Desktop now checks records proving you own it, rather than looking only at agents in channels you've already joined. **No new screen or control is added.** For example, an agent with verified ownership and **Who can send instructions → Only me (default)** can now appear even with no shared channels. Each screen still applies its existing access rules; this does not make every discovered agent selectable everywhere. | Screen / control | Before | After this PR alone | | --- | --- | --- | | **New message → To:** recipient picker | An owned agent absent from this machine and shared-channel bot lists could be missing. | Its named **agent** row can appear; selecting it adds a recipient chip. This is recipient selection, not a guarantee that a later message will reach or wake the agent. | | **Channel members → Add people and agents** | The same agent could be missing from **Not in this channel** search results. | Its row can appear with the existing **Add** button. If you can add members, that button submits the existing channel-membership request; finding the row alone changes no membership. | | **Stream / forum composer → @ suggestions** | An owned agent already in the channel under an ordinary member role could be missing from agent suggestions. | Its actual membership is recognized without requiring the bot role. Agents not managed on this device still need membership in that channel. | | **Pulse → Agents** | An agent absent from both local management and the server's agent list was omitted from the count and author lookup. | The count and feed's author lookup can include it; notes appear only if it has published them. | Being listed does **not** mean the agent is online, add it to a channel, or grant local Start/Edit controls. For agents not managed on this device, global **Search** still excludes those configured for “Only me”, and DM @ selection is not added here. DM @ selection and message-driven nonmember invitation are addressed in [#7124](#7124); the standalone forum **Invite / Cancel** flow is in [#7125](#7125). <details> <summary>Ownership and membership checks</summary> A discovery lead is not proof: the latest agent profile must have a valid signature and exactly one valid ownership attestation—the owner's signed link to that agent. Its response policy must be signed by that verified owner; an invalid latest policy cannot restore an older permission. Membership comes separately from the latest server-signed roster, including removals. Existing profile cards, owner labels and agent-avatar shapes also use this stricter verification: malformed or forged evidence must not supply ownership/agent classification on its own. Valid ownership was already recognized; no profile-picture or badge design changes. Attestation time conditions apply to the signed event's timestamp, not a live expiry timer. Existing legacy compatibility and builds requiring verified owner policy retain their respective rules. Discovery and sending remain separate operations, not an atomic permission check. </details> ### Review corrections - When runtime and owner policy overlap, **explicit online/away/offline from the verified latest runtime is retained**. Policy still supplies ownership/permissions; claimed runtime membership is not restored. Missing/unrecognized status stays unknown, and invalid latest policy cannot revive runtime permissions. - Discovery without runtime evidence is now **unknown**, not offline: native conversion, both IPC adapters, Pulse, Projects and profile/session consumers preserve that distinction. Unknown has no status dot and is not promoted to a deployed/running agent. - Both relay-only picker paths retain the authenticated owner, including the existing **managed by you** label. The analogous global Search projection is fixed without changing its existing “anyone” filter. - Authorized stored profile activity remains visible when liveness becomes unknown/absent or the active turn ends. History reads do not start a live subscription, grant access, or imply current availability. ### Related issue Independent base: `main`. Child: [#7124](#7124), then [#7125](#7125). Extracted from [#7114](#7114), retained as historical source (`98fe33ec`). [Behavior contract](https://github.com/block/buzz/blob/3a56d17824522580fe04cae463b54f4c7ba66021/docs/owned-agent-discovery.md). Originating [Buzz discussion](buzz://message?channel=f7a9536a-1738-4bad-a888-b3ea25010ef1&id=7aa1f0ab23dce514bd8a0221441cf005bf428914621171472b79747c50820848) · channel `f7a9536a-1738-4bad-a888-b3ea25010ef1`. ### Testing Current candidate: `3a56d17824522580fe04cae463b54f4c7ba66021`, a four-file native/test/doc runtime-status repair atop published `ae23c1c9680a881cee7eed94e259bf15bf8ce3f7`. Branch ancestry is main `1c8321cd08feb597f8bcff5195c21148fb3e98ed`; refreshed main `0e878664b08cdf7fb2d89d940bc2aa92cdc485f7` adds only the independent CI-workflow split. Read-only mergeability succeeds; this is not a tested merged-tree claim. **Local CI attempt and continuation (not an uninterrupted green run):** the new exact-head `just ci` passed formatting/static checks, workspace and Tauri clippy, workspace Rust tests, **5,910 desktop tests**, desktop production build and Tauri check. Its native main target finished **3,073 passed / 1 failed / 19 ignored** (exit 101): `cheap_discovery_reports_absent_before_any_forced_probe` saw a process-global login-shell counter of 2 instead of 0. The counter includes unrelated version/adapter probes whose tests do not hold the failed test's PATH mutex; no managed-agent discovery implementation changed in the runtime repair. The unchanged failing test then passed **three isolated invocations**. Only the failed native workspace lane was retried with `RUST_TEST_THREADS=1 just desktop-tauri-test`: **3,074 main-target tests passed / 19 ignored**, all additional workspace targets passed (exit 0). The previously unrun `just web-build mobile-test` tail then passed (exit 0; **2,019 mobile tests**). Earlier successful lanes were reused; no source/guard changes or blanket CI rerun. The original failure and all diagnostic/retry logs are retained. - **71 native `nostr_convert` tests pass**, including seven new production merge regressions: online/away/offline, missing/invalid status, policy-only, status-less latest replacement and forged latest replacement. Before production repair, those seven yielded **4 failures / 3 passing controls**. - Reused frontend evidence from `ae23c1c9` (frontend is unchanged): Desktop TypeScript and isolated E2E build pass; **9 browser tests / 0 retries**, covering both relay-only picker journeys and seven adjacent stop-control regressions. Real UI with mock Tauri IPC, not live relay/native webview. - Earlier `ae23c1c9` local `just ci` passed without failures, including 3,067 native main-target tests / 19 ignored and 2,019 mobile tests; not substituted for the new source gate above. - Reused unchanged repair evidence: **17 real-store/hook history regressions**, **161 focused tests**, and independent **9 mounted owner/bot/identity revocation/regrant transitions** with zero hook-phase native calls. The regression was falsified before repair (14 failures, 3 controls). - Signed local-server fixtures cover discovery with no local/shared record, ordinary-role membership, forged ownership, invalid signatures, duplicate authentication, wrong-owner/latest-invalid policy, revoked membership and wrong destinations. These establish native data checks, not a live agent response. GitHub checks and renewed technical/security review must apply to the current published head; earlier-head green checks are not replacement-head proof. Local source review is not formal code-owner/latest-push approval or exact-range security authorization. A green security workflow with substantive review skipped is not security clearance. ### Screenshots #### Relay-only picker evidence — `ae23c1c9680a881cee7eed94e259bf15bf8ce3f7` These cropped rows come from the two real production picker journeys in [`owned-agent-discovery.spec.ts`](https://github.com/block/buzz/blob/ae23c1c9680a881cee7eed94e259bf15bf8ce3f7/desktop/tests/e2e/owned-agent-discovery.spec.ts), using mock Tauri IPC with **no local agents and no user-search duplicate**. The fixture supplies verified-owner data and unknown availability; the browser test checks its presentation, not native signature verification. Both exact-tip journeys pass without retries. No live relay, native webview, invitation, delivery or wakeup is claimed. Before the repair, both relay-only candidate constructors discarded the owner, so the existing “managed by you” label was absent. These are after-repair captures; no before image was captured. #### New Message → To The relay-only agent retains its authenticated owner label.  #### Channel members → Add people and agents The matching result retains “managed by you” beside the existing Add action; the test does not click Add or claim membership changed.  --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Pending base-change re-review: unchanged routing headThe remaining gate is the already requested automated review after #7122 merged and this PR was retargeted to The timeline records that exact-head approval 5092775370 was dismissed at 2026-09-02 20:18:58 UTC with “The base branch was changed.” The replacement request at 20:19:26 remains pending. All current checks are successful or legitimate path skips, and GitHub reports MERGEABLE, but REVIEW_REQUIRED/BLOCKED. This does not restore or bypass the dismissed approval. @jedwards27 — please complete the existing automated request against the current |
1144465 to
e66b949
Compare
* origin/main: fix(desktop): keep packaged frontendDist relative so Windows embeds assets (#7177) fix(sidebar): simplify unread indicators and emphasize priority activity (#7134) Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) chore(release): release Buzz Desktop version 0.5.22 (#7308) feat(desktop): preserve mentions across copy and paste (#7228) test(desktop): await Bestie drag and profile hover endpoints (#7294) Signed-off-by: Fizz <400e8babadcee6a7f420103f10a2849d84c4a9c71d5bd04f3948c814216648a3@buzz.block.builderlab.xyz>
* origin/main: chore(release): release Buzz Desktop version 0.5.23 (#7381) fix(desktop): keep packaged frontendDist relative so Windows embeds assets (#7177) fix(sidebar): simplify unread indicators and emphasize priority activity (#7134) Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) chore(release): release Buzz Desktop version 0.5.22 (#7308) feat(desktop): preserve mentions across copy and paste (#7228) test(desktop): await Bestie drag and profile hover endpoints (#7294) Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
…-enforcement * origin/main: Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) chore(release): release Buzz Desktop version 0.5.22 (#7308) feat(desktop): preserve mentions across copy and paste (#7228) test(desktop): await Bestie drag and profile hover endpoints (#7294) Collapse contiguous join messages (#7262) chore(release): release Buzz Desktop version 0.5.21 (#7301) fix(scripts): copy global-agent-config.json in buzz-adopt-prod-agents (#7303) Signed-off-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz>
…n-surface * origin/main: (23 commits) chore(release): release Buzz Desktop version 0.5.23 (#7381) fix(desktop): keep packaged frontendDist relative so Windows embeds assets (#7177) fix(sidebar): simplify unread indicators and emphasize priority activity (#7134) Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) chore(release): release Buzz Desktop version 0.5.22 (#7308) feat(desktop): preserve mentions across copy and paste (#7228) test(desktop): await Bestie drag and profile hover endpoints (#7294) Collapse contiguous join messages (#7262) chore(release): release Buzz Desktop version 0.5.21 (#7301) fix(scripts): copy global-agent-config.json in buzz-adopt-prod-agents (#7303) ... Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
* origin/main: (29 commits) fix(acp): pace targeted overflow recovery on consumer capacity (#7325) fix(link-preview): keep composer fetches user-paced (#7211) feat(mesh): upgrade to mesh-llm 0.76.0-rc8 and recommend Qwen3.8 27B (#6189) fix(agent): route GPT-5+ model-service FQNs to Responses (#7358) fix(buzz-acp): wake held ACP threads and fence forked sessions (#7340) fix(mobile): style inline code with the app mono face (#6631) chore(release): release Buzz Desktop version 0.5.23 (#7381) fix(desktop): keep packaged frontendDist relative so Windows embeds assets (#7177) fix(sidebar): simplify unread indicators and emphasize priority activity (#7134) Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) ... Signed-off-by: Tom Brow <tomb@block.xyz>
* origin/main: (77 commits) fix(acp): pace targeted overflow recovery on consumer capacity (#7325) fix(link-preview): keep composer fetches user-paced (#7211) feat(mesh): upgrade to mesh-llm 0.76.0-rc8 and recommend Qwen3.8 27B (#6189) fix(agent): route GPT-5+ model-service FQNs to Responses (#7358) fix(buzz-acp): wake held ACP threads and fence forked sessions (#7340) fix(mobile): style inline code with the app mono face (#6631) chore(release): release Buzz Desktop version 0.5.23 (#7381) fix(desktop): keep packaged frontendDist relative so Windows embeds assets (#7177) fix(sidebar): simplify unread indicators and emphasize priority activity (#7134) Add generic information-flow control core (#7293) feat(buzz-acp): update base prompt; add buzz context and skills to Pi agents (#7335) fix(desktop): restore mention chip identity icons (#7338) Persist video playback speed preference (#7336) Verify ACP relay events before prompt routing (#7010) fix(buzz-acp): bound busy-owner hold to prevent cross-channel starvation (#7337) feat(desktop): invite owned agents from standalone forums (#7125) fix(desktop): authorize remote mentions at publication (#7124) fix(acp): rename system tag to agent-instructions (#7332) fix(desktop): bind duplicate mention selections to exact recipients (#7133) refactor(relay): extract NIP-29 membership authorization (#7285) ... Signed-off-by: Sol <478bb5a31222ea2b28a3d1afb8b1d598940628f19c2a87efc3c4b822299eeec6@buzz.block.builderlab.xyz> # Conflicts: # desktop/src-tauri/src/commands/media_download.rs # desktop/src-tauri/src/lib.rs
…nt (#7190) 🤖 ## Summary Fixes four ways the composer could lose your text or cursor while working with @ mentions: - **A failed send no longer wipes your draft.** If mention preparation fails while sending (for example, a failed upload), the draft stays as typed, the error is shown, and you can send again. - **A closing menu can no longer steal your cursor.** A still-animating ⋯ menu can no longer grab a late pointer event and steal focus from the composer; Escape still refocuses its trigger. - **Delayed automatic mentions no longer overwrite your typing.** The per-agent "Automatically mention … in this conversation" toggle re-adds the label to your next draft, but only if that draft is untouched — any draft edit or channel switch cancels the re-add. - **Regenerated automatic mention labels leave no residue.** After a regeneration (for example, an agent rename), the current label is the one later updated or removed — no duplicated or leftover text. Part of the mention-editor stack: #7190 → #7191 → #7192 (review in order); stands on its base branch alone. ### Related issue Continues the merged mention-editor work from #7124 and #7128. No separate tracking issue for this slice. ### Testing - Unit tests cover each fix: draft retention on failed sends, re-add revocation on draft edits or channel switches, and regenerated-label ownership. - Browser specs cover the closing-menu focus case, failed sends, and an always-mention agent surviving save, reopen, and publication. - All PR checks pass on this head. --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
… choices (#7191) 🤖 ## Summary Keeps @ mention choices accurate and safe while membership and access change. - **Membership changes reach @ search immediately.** Additions, removals, and channel creation refresh the @-mention directory right away; bursts coalesce and queued work is dropped on community or identity switch. - **The list you see is the list you choose from.** While a suggestion list is open, rows never move or change: Enter, Tab, and clicks pick the identity shown, even when agents share a name. Availability labels (Checking → Mention / Unavailable, with Retry) resolve in place, never moving your selection. - **Your choice is re-checked when you make it.** Selecting or pinning freshly re-checks that the agent can be mentioned here ("Checking access…"); changed access leaves the draft untouched with a clear message, failed or timed-out checks fail closed without clearing the draft; selecting again retries. Removing or unpinning needs no permission check. - **Choosing someone is not a send permit.** Publication still independently re-validates authority for the destination, so an agent revoked after selection cannot receive your message. - **Recent choices behave predictably.** Same-name agents are marked ambiguous; recent choices rank first per viewer and channel (never a permission; cleared on community switch); pending mention actions are abandoned on edit, navigate, or submit. Part of the mention-editor stack: #7190 → this PR → #7192 (review in order). ### Related issue Continues the merged mention-editor work from #7124 and #7128; no separate tracking issue. ### Testing - Unit suites drive the production chat and forum composers: membership refresh, stable choices with fresh re-check, native-edit abandonment, selection history. - Extended browser specs cover reorder-stable choices and exact same-name selection. - All PR checks pass on this head. Limits: revalidation/revocation coverage is unit-level with mock IPC — no native Tauri/WebKit, VoiceOver, IME, or live-relay claim. Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
🤖 ## Summary Keeps buffered messages reachable while you read, so the way back to the newest message never disappears. - **"Jump to latest" stays available whenever messages are waiting.** While you read away from the newest message, new arrivals are buffered; the pill could vanish even then, leaving no way down. Clicking it releases them and scrolls to newest. - Browser regressions drive that recovery with real input: a native wheel-return to the frozen bottom, the button kept through panel close, an ambiguous @ mention replaced with the exact recipient before resending, and authored drafts deleted through the real editor with a native select-all. Based on the mention-editor integration branch, which now includes #7190 and #7191. The send-flow failure handling this branch originally carried — visible mention-resolution errors that release the pending send, and one shared authorization-error reason — landed with #7191 and is unchanged here; the remaining diff is the timeline recovery and its test coverage. ### Related issue Continues the merged mention-editor work from #7124 and #7128. Discovered during #7239 — its separately authorized follow-up, not a replacement. [Originating Buzz conversation](buzz://message?channel=8dcd7afb-0193-4a3e-8ae9-72838de89a1d&id=00f3b6fc0f24a5be445fdb8b1fd092cbdae5eb46615d95119ef2d8c566396738) ### Testing - Browser regressions: native wheel-return to the frozen bottom, panel close without losing the button, ambiguous-send recovery via the exact recipient, and the dirty-edit fixture's real select-all with real keyboard focus (wrong-replacement negative control included). - This head's exact tree is the validated candidate: full desktop package suite (6,164 tests), typecheck and E2E build, formatting and text-size guards, and 38 Chromium browser regressions with zero retries. - PR checks gate this head. Browser evidence is mock-bridge Chromium — no native Tauri/WebKit, VoiceOver, IME, or live-relay claim. Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Summary
Buzz Desktop could hide an agent you own on another device before you could invite it, or silently drop a selected agent when its permissions changed. This lets eligible owned agents reach the existing @ menu → Send → Invite flow and checks the intended recipients again before publishing. Lost access shows an error and preserves a recoverable draft instead of sending without the agent.
Invite is not the only choice: chat's Do nothing / Send anyway sends without inviting or notifying the nonmembers; their names remain references. Escape cancels. Invitation adds channel-wide membership, not a one-thread guest, and does not start a remote agent or guarantee a reply.
Related issue
Targets
main; owned-agent discovery (#7122) is already merged. Split from #7114. #7125 depends on this PR and adds standalone forum invitations and failed-send recipient recovery. Duplicate-name binding from #7133 is already merged and retained by this stack. No new profile, presence or remote-management UI.Testing
Focused production-hook lifecycle tests and mock-IPC browser checks passed for the published refresh, covering clipboard settlement, permission revocation and recipient/wake behavior; the frontend build/typecheck passed. Broader desktop results predate the final settlement repair and are not claimed as a new-head full-suite run. See live CI for current-head results; no full local
just cipass or native/live-relay validation is claimed.To try it: select an owned nonmember agent in a channel or thread, send, then Invite or Escape/retry. Deny the add or revoke response permission: expect an error, no publication and a recoverable draft. During a pending send, edit or clear the source draft and navigate away/back; late completion must not overwrite that change.
Earlier mock-browser capture, not current-head runtime proof. Success/denial captures; no before-state screenshot available.
Limits: authorization reads and publication are not atomic; cancellation cannot undo accepted membership changes or dispatched messages. Draft protection is same-window. Legacy already-member agent compatibility remains unchanged: self-declared identity does not prove ownership or enable owned-nonmember invitations, and invalid verified-owner policy remains rejected.