Skip to content

fix(desktop): keep your draft editable when an @ mention cannot be sent - #7190

Merged
loganj merged 4 commits into
integration/mention-picker-stack-844abd33-basefrom
fix/mention-picker-stack-844abd33-1
Sep 11, 2026
Merged

loganj merged 4 commits into
integration/mention-picker-stack-844abd33-basefrom
fix/mention-picker-stack-844abd33-1

Conversation

@loganj

@loganj loganj commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

🤖

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.

Replay the approved first slice from 857ed203 and e0cc5522 (aggregate 58db416d). Keep extraction within failure cleanup; use the existing runtime lookup and upload error rendering through size-gate helper extractions. Remove the inherited unused markdown import for strict builds.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
@loganj loganj changed the title fix(desktop): retain drafts after synchronous mention extraction failure fix(desktop): keep your draft editable when an @ mention cannot be sent Sep 2, 2026
Backport the independently reviewed 646f30febd436d8a10a2f531f38a4ac9d2912064 fix and its regression to published PR1 db566eb. Keep the closed-menu production owner and browser assertions unchanged; register the test next to mention-recipients on this base.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
loganj and others added 2 commits September 2, 2026 11:35
Package existing reviewed repairs in the authorized seven-slice dependency stack. Preserved model A; experiment excluded.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
Keep one full storage-to-transport witness and both local restoration checks. Select the destination fixture by pointer so this prefix does not depend on the later native Enter repair.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Reviewed base 802ba6170e57ac71d1ecfd6cf6fb12f02ecf910c → exact live head bb8cca21e13099bc6206b18c62272b72928574ca across systems/integration and product/UI behavior. No material defects found; no author action required.

Findings

  • Recipient identity is captured before asynchronous send work, normalized to exact pubkeys, and revalidated against the actual destination before preparation and again before publication (desktop/src/lib/hooks/useMentionSendFlow.ts:460-465,577-603,756-764,829-836,863-891). Publication and address tags use that final admitted set.
  • Composer recovery is revision/owner fenced (desktop/src/lib/hooks/useMentionSendFlow.ts:391-430), while delayed automatic restoration is fenced by frame identity and shared revision (desktop/src/lib/hooks/useAddressedAgentMentionRestore.ts:45-78).
  • E2E coverage verifies signed channel/recipient identity through mid-send navigation (desktop/e2e/send-channel-binding.spec.ts:120-170) and persisted audience storage → restoration → signed/wire identity (desktop/e2e/persistent-agent-audience.spec.ts:126-199).
  • Product/UI coverage exercises pointer/menu focus retention, Escape-trigger restoration, same-name exact-recipient publication, separator/caret/highlight stability after style removal, draft persistence/reopen, reduced motion, narrow layout, send-failure recovery, and channel switching.

Exact-head evidence

At clean bb8cca21e13099bc6206b18c62272b72928574ca:

  • Full Desktop package suite: 6021/6021 passed.
  • Desktop check/typecheck/build: passed; reported warning/info diagnostics were outside changed lines.
  • Independent isolated E2E selections: 48/48 and 50/50 passed across affected specs.
  • Differential file-size policy and git diff --check: passed.
  • No added production unwrap/expect; exported helper documentation and DCO trailers present.
  • Live exact-head CI is green for Desktop Core, macOS/Windows builds, smoke shards, relay E2E, integration shards, Semgrep, zizmor, and DCO.

Residual risk

No native Tauri/OS accessibility-tree journey or independent mutation run was completed. This is a reviewer/tooling-owned confidence gap, not an author-actionable defect: the isolated E2E coverage directly exercises the relevant focus, restoration, failure-recovery, navigation, and signed-recipient behavior.

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:bot: Jude’s code review agent

Both assigned review lanes clear exact head bb8cca21e13099bc6206b18c62272b72928574ca.

Recipient identity is captured before asynchronous work, carried as normalized exact pubkeys, and revalidated against the actual destination before preparation and publication. Draft recovery is owner/revision fenced, and delayed automatic restoration is frame-identity/revision fenced. Product validation covered focus retention, keyboard restoration, exact same-name recipient publication, separator/caret stability, persistent audience restoration, failure retry, and channel-switch behavior.

Validation: full Desktop package 6,021/6,021; typecheck, lint, and build; 50/50 affected E2E tests; clean git diff --check. The live head remained unchanged immediately before this review, with 17 successful and 10 skipped exact-head checks.

Residual risk: no native Tauri/OS accessibility-tree run and no independent mutation run. These are reviewer/tooling confidence gaps, not author defects.

@loganj
loganj merged commit 65e814f into integration/mention-picker-stack-844abd33-base Sep 11, 2026
49 of 51 checks passed
@loganj
loganj deleted the fix/mention-picker-stack-844abd33-1 branch September 11, 2026 16:51
loganj added a commit that referenced this pull request Sep 11, 2026
… 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>
loganj added a commit that referenced this pull request Sep 11, 2026
🤖
## 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants