Skip to content

🤖 fix(desktop): consolidate fresh mention action admission and stable choices - #7191

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

loganj merged 1 commit into
integration/mention-picker-stack-844abd33-basefrom
fix/mention-picker-stack-844abd33-2

Conversation

@loganj

@loganj loganj commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

🤖

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.

@loganj loganj changed the title fix(desktop): refresh agent discovery on live membership events fix(desktop): refresh @ search when channel membership changes Sep 2, 2026
@loganj
loganj force-pushed the fix/mention-picker-stack-844abd33-2 branch 3 times, most recently from 9164074 to b411da5 Compare September 4, 2026 11:17
@loganj
loganj force-pushed the fix/mention-picker-stack-844abd33-2 branch from b411da5 to 4316a13 Compare September 8, 2026 17:26
@loganj
loganj changed the base branch from fix/mention-picker-stack-844abd33-1 to integration/mention-picker-stack-844abd33-base September 8, 2026 17:27
@loganj
loganj force-pushed the fix/mention-picker-stack-844abd33-2 branch 3 times, most recently from 96c6d9c to ff2b68c Compare September 8, 2026 18:23
@loganj
loganj changed the base branch from integration/mention-picker-stack-844abd33-base to fix/mention-picker-stack-844abd33-1 September 8, 2026 18:23
@loganj
loganj marked this pull request as ready for review September 9, 2026 15:59
@loganj
loganj requested a review from a team as a code owner September 9, 2026 15:59

@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 — REQUEST CHANGES

Reviewed base bb8cca21e13099bc6206b18c62272b72928574ca through exact head ff2b68cb15bcd9d01ac37aedff5511b605166ad2.

1. Major — background third-party membership changes leave the mention directory stale

The global notification hook filters on the viewer's pubkey (desktop/src/features/channels/useMembershipNotifications.ts:52-60), while relay membership notifications p-tag only the changed member (crates/buzz-relay/src/handlers/side_effects.rs:913-928). Thus viewer V does not receive that path when actor A adds/removes target T. The mounted-channel path does refresh on membership system rows (desktop/src/features/messages/hooks.ts:375-390), but the all-channel subscription used for background channels accepts those rows without scheduling a refresh (desktop/src/features/channels/useLiveChannelUpdates.ts:232-335,385-401). V can therefore keep a removed agent visible, or omit a newly added agent, until polling despite already receiving the background-channel row.

Author action: detect membership rows in the all-channel live-event production path (or emit a genuinely viewer-addressed global event), invoke the coalescing scheduler there, and add a caller-bound regression for a background-channel A→T add/remove observed by V. Deleting the production invocation should make that test fail.

Verification owner: :bot: Jude’s code review agent will trace active/background delivery, run the full Desktop package, mutation-delete the invocation, and exercise V's first @ search after the background change.

2. Moderate — refresh/reorder can silently retarget keyboard selection

An open picker reranks when the directory changes (desktop/src/features/messages/lib/useMentions.ts:369-399), but selection is retained only as a numeric index and merely clamped (desktop/src/features/messages/lib/useMentionSelection.ts:7-23). Enter/Tab inserts whichever identity now occupies that index (useMentions.ts:776-815). A production-hook probe selected Bob in [Alice, Bob], then rerendered [Agent, Alice, Bob]; selection stayed at index 1 and therefore moved to Alice instead of following Bob to index 2. The next Enter/Tab can mention the wrong recipient without further navigation.

Author action: preserve selection by stable suggestion identity (normalized pubkey/persona ID/team ID) across refresh/reorder, with an explicit safe fallback if the identity disappears. Add a regression that changes ordering while the picker is open, asserts the visible highlight remains on the intended identity, and then verifies Enter/Tab inserts that identity. Restoring index-only clamping should fail the test.

Verification owner: :bot: Jude’s code review agent will verify keyboard/highlight/visible-row behavior and exact inserted recipient identity.

Evidence and confidence

  • Full Desktop package: 6,028 passed, 0 failed at the exact head; HEAD unchanged and review trees clean afterward.
  • git diff --check passed.
  • Exact-head CI run 34262722726: Desktop Core, four smoke shards, relay-backed Desktop E2E/integration, macOS/Windows builds green; DCO, Semgrep, and zizmor green. Cancelled entries belong to a superseded run, not this head.
  • Confidence gap, not a separate defect: no native GUI/accessibility journey was run. After the fixes, exact-head native evidence should cover a background third-party membership change and open-picker reorder.

@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

Requesting changes on exact head ff2b68cb15bcd9d01ac37aedff5511b605166ad2 after reconciling both assigned lanes. Two independent author-actionable defects remain.

  1. Open-picker refresh can silently retarget keyboard selection. Membership refresh reranks suggestions (desktop/src/features/messages/lib/useMentions.ts:369-399), but selection persists only as a numeric index (desktop/src/features/messages/lib/useMentionSelection.ts:7-23); Enter/Tab inserts the identity now occupying that index (useMentions.ts:776-815). A production-hook probe selected Bob in [Alice, Bob], refreshed to [Agent, Alice, Bob], and retained index 1 (Alice) instead of Bob at index 2. This can mention the wrong recipient without further navigation.

    Required change: preserve selection by stable suggestion identity (normalized pubkey/persona/team identity) across reorder; use an explicit safe fallback if it disappears. Add a regression that reorders an open picker, asserts the same visible identity remains highlighted, then verifies Enter and Tab insert that identity.

  2. Third-party membership changes in background channels miss the refresh scheduler. The global notification hook filters #p to the viewer (desktop/src/features/channels/useMembershipNotifications.ts:52-60), but relay membership notifications tag the changed member (crates/buzz-relay/src/handlers/side_effects.rs:913-928). Mounted-channel rows refresh at desktop/src/features/messages/hooks.ts:375-390, while the all-channel background path receives system rows but never calls refreshDirectoryAfterMembershipChange (desktop/src/features/channels/useLiveChannelUpdates.ts:232-335,385-401). A viewer can therefore retain stale mention candidates after another actor changes a third party in a background channel.

    Required change: invoke the coalescing refresh scheduler from the all-channel production event path (or provide a viewer-addressed global event). Add a caller-bound behavioral regression for a background A→T add/remove observed by V; deleting the production invocation must fail it.

Baseline evidence was green: Desktop 6,028/6,028, clean git diff --check, and 17 successful/10 skipped exact-head checks. An older duplicate run is cancelled. Live head was unchanged immediately before review.

@loganj

loganj commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

On the open-picker reorder retargeting keyboard selection (Moderate finding) — valid at this PR's head; fix owned by #7197

Valid as reviewed at ff2b68cb: while the picker is open, selection persists only as a numeric index that is clamped on rerank (useMentionSelection.ts:7-23), and Enter/Tab then inserts suggestions[mentionSelectedIndex] — whichever identity occupies that index after the refresh (useMentions.ts:776-815). The probe's selected Bob silently becoming Alice in [Alice, Bob][Agent, Alice, Bob] is exactly this mechanism.

Per this stack's ownership split the fix is #7197's stable installed-snapshot chooser, not a backport here. At #7197's head 0464384b the picker installs a frozen row snapshot once per request (old?.request === request ? old : { request, rows: shallow-copy, index }useMentionSelection.ts:7-36), so background membership/directory/presence/ranking updates can neither replace nor reorder an installed list; that is the stated contract in docs/mention-editor.md ("Stable completion choices"). On top of that byte-identical chooser, #7239 only updates availability in place (useMentions.ts:479-500: identity, label and order stay frozen; only action/presence/Retry resolve live), and #7240's recent-choice history only ranks the next request (mentionSelectionHistory.ts) — never installed rows.

Existing coverage of this mechanism at #7239's head f1af1b88 (cited as written; not rerun for this comment):

Scope, stated plainly: standalone #7191 at ff2b68cb still carries the old moving-list model. This finding is closed at the combined stack state — the single #7197 request/snapshot owner (with #7239/#7240 layered on it) also carrying this PR's membership refresh — and nothing here has been verified on a combined head. Keeping one snapshot chooser instead of backporting a second copy into #7191 is the deliberate cross-PR resolution for this stack. The background third-party membership refresh finding is separate and remains open on this PR.

@loganj

loganj commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

On the background third-party membership change leaving the mention directory stale (Major finding) — fixed at this PR's new head f66687ef, pending CI and re-review

Valid as reviewed at ff2b68cb (both review bodies, e.g. 5156991744): the app-wide background receiver — useLiveChannelUpdates' handleIncomingMessage, mounted via AppShell → useUnreadChannels — merged kind-40099 channel-event rows into the timeline cache but never refreshed the mention directory. The mounted-channel refresh only covers the channel on screen, and the global membership hook only sees viewer-addressed 44100/44101 rows, so a third-party add/remove in a subscribed background channel left candidates stale (or missing) until the focused directory poll.

Fix published as commit f66687ef989f14bfa026b16d4a35def9beb74b58, the new head of this PR: handleIncomingMessage now parses the member_joined/member_left/member_removed payload of kind-40099 rows and calls the existing refreshDirectoryAfterMembershipChange(queryClient, event.id) — the same one-liner the mounted-channel path makes, with the same payload gate and member set (useLiveChannelUpdates.ts:327-347, invocation at line 341). The helper's coalesce/cancel/event-id-dedup semantics are unchanged; no wire-format or relay change.

New mounted-caller regression, useLiveChannelUpdatesMembershipDirectory.test.mjs: mounts the real background receiver (createRoot/act inside a QueryClientProvider; relayClient subscription entry points mocked, no socket) and drives it with ordinary relay-wire kind-40099 rows — relay-keypair-signed, h-tagged, content {"type":…,"actor":A,"target":T} per side_effects.rs. The emit helper refuses to deliver a row the subscription filter would not carry, so the fixture cannot pass through a kind the hook never receives. The viewer subscribes to two channels and views the other one, so the membership channel is background.

Red / green / deletion control — actual runs bound to this exact candidate (the validated dirty state, now byte-identical to the published commit):

  • RED — pristine ff2b68cb handler + new test only: 2 fail / 1 pass, failing exactly at member_joined|member_removed row must invalidate the mention directory (false !== true); the negative control (non-membership 40099 topic_changed + plain stream message) passes unpatched.
  • GREEN — fix applied: 3/3 pass (add: directory invalidated synchronously, the 200 ms-coalesced refetch picks up the new roster; remove: roster drops the member).
  • Deletion control — deleting only the refreshDirectoryAfterMembershipChange(queryClient, event.id) invocation (detection block kept): 2 fail / 1 pass, the same wiring assertions; restoring the invocation returns to 3/3. The regression binds the production seam, not a test-only shortcut.
  • Combined focused suites across this production file and the helper it calls: 39/39 pass.

Full-suite proof scope: the entire desktop package suite was run once at this exact candidate — 6031/6031 tests pass, 87 suites, exit 0 (just desktop-test; this claim1 regression 3/3 and the helper's own coalesce/cancel/dedup suite 6/6 green inside it), plus desktop tsc --noEmit exit 0 and Biome clean on both changed files. These are local runs; remote CI is not yet asserted.

Stack note: the identical fix is mechanically replayed onto #7192's new head e7b8434 (range-diff content-identical, no other changes), and both heads were pushed atomically; #7192's CI is likewise dispatched and pending.

Status, stated plainly: the claim-1 code is fixed and published at f66687ef, CI on the new heads is dispatched and not waited for, and the changes-requested decision stands until re-reviewed — this is not an all-resolved or ready-to-merge claim. The selection-retargeting finding is answered separately in the F2 response and remains owned by its own PRs (#7197/#7239).

Update — 2026-09-09 20:13Z, current-CI evidence addendum (supersedes the "CI dispatched / pending" wording above; all original claims above are unchanged): the failed-jobs-only retries of both runs, on the same two heads with no new commits pushed, have since completed green.

@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 — REQUEST CHANGES

Reviewed: bb8cca21e13099bc6206b18c62272b72928574ca..f66687ef989f14bfa026b16d4a35def9beb74b58.

The changed head fixes the prior background-channel membership refresh defect: the all-channel production callback now invokes the coalescing directory scheduler, with a caller-bound regression that fails when that invocation is removed. One independent wrong-recipient defect remains.

[P2] Preserve the selected identity when membership refresh reranks the open picker

Membership refresh can reorder suggestions, but selection remains only a numeric index and is merely clamped (desktop/src/features/messages/lib/useMentionSelection.ts:7-23). The visible highlight follows the item occupying that index (MentionAutocomplete.tsx:363-373), and Enter/Tab insert suggestions[mentionSelectedIndex] (useMentions.ts:776-815).

At this exact head, a production-hook probe selected Bob at index 1 in [Alice, Bob], refreshed to [Agent, Alice, Bob], and retained index 1—now Alice. The next Enter/Tab therefore targets a different recipient without user navigation.

Author action: preserve selection by stable suggestion identity (normalized pubkey, persona ID, or team ID) across refresh/reorder. If the identity disappears, use an explicit safe fallback. Add a production-path regression that reorders an open picker, asserts the same identity stays highlighted, and verifies both Enter and Tab insert that exact identity; mutation-prove against index-only clamping.

Verification owner: reviewer — rerun highlight/Enter/Tab and disappearance recovery behavior, full Desktop package, and exact-head gates.

Validation: full Desktop package passed 6,031/6,031; typecheck, check, git diff --check, repo-policy audit, and exact-head CI run 34382606766 passed. The background callback regression failed causally when its new production invocation was removed, then passed after restoration. Residual confidence gap: native Desktop/AX observation was not run; reviewer/tooling-owned and not the reason for this verdict.

@loganj
loganj force-pushed the fix/mention-picker-stack-844abd33-2 branch from f66687e to 0973992 Compare September 11, 2026 14:01
@loganj loganj changed the title fix(desktop): refresh @ search when channel membership changes 🤖 fix(desktop): consolidate fresh mention action admission and stable choices Sep 11, 2026
@loganj

loganj commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

Published consolidated head 0973992d (tree 37197dcf), parent unchanged #7190 bb8cca21; it replaces prior head f66687ef. Before committing, every reviewed diff binding was re-verified byte-exact by SHA256: published7191→candidate b8dc2ebf…, #7190→candidate 3bb9e224…, candidate7191→candidate7192 4f671a69…, published7192→candidate7192 530be5c6…, fixed802→candidate7192 e655d895…, published7542→candidate7192 a4e4cf5c…. Identity verified under the exact committing invocation: Logan Johnson loganj@squareup.com; DCO Signed-off-by and the Larry co-author trailer are present, matching prior published commits in this stack (no cryptographic signing is configured for this identity, consistent with the existing stack commits).

Exact-tree evidence (tree 37197dcf): full desktop package 6,164/6,164 (87 suites), focused admission journey 31/31, tsc --noEmit and desktop check exit 0; causal live-row mutation fails both Enter/Tab background-reorder regressions (2 fail, 0 pass) and was restored before final gates; independent review of these exact trees re-ran 97/97 focused tests plus typecheck read-only. Browser evidence ran on the final descendant tree (#7192 80122d79): 6/6 picker smoke plus 16 additional existing workflows, zero retries, mock-bridge Chromium. Initial 6,167/4 membership-contract failures before reconciliation are preserved as history, not relabeled green.

Feedback mapping at this head: review 5168528058's P2 wrong-recipient selection is addressed in this unit's installed-rows/identity selection (useMentionSelection.ts, useMentions.ts) with Enter/Tab regressions; the fresh-action boundary demanded by #7196 reviews 5168495309/5168492716 ships in this unit, which is why #7196/#7323/#7197/#7239/#7240/#7542 are closed as superseded (branches and PR text retained; not a claim their old defects/CI cleared).

Limits: no native Tauri/WebKit, VoiceOver, IME or live-relay execution claimed; evidence binds currently installed dependencies. Exact-head CI is pending at 0973992d.

Re-review of this changed head is requested — prior CHANGES_REQUESTED at f66687ef/ff2b68cb does not cover 0973992d, and no existing approval elsewhere certifies this head.

@loganj
loganj requested a review from jedwards27 September 11, 2026 14:03

@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 bb8cca21e13099bc6206b18c62272b72928574ca..0973992daf750590225dd9a0b1d2cf5874eb71d3 at exact head 0973992daf750590225dd9a0b1d2cf5874eb71d3.

Risk: High — this changes messaging recipient correctness across asynchronous directory refresh, community/identity lifecycle, selection, pinning, and publication boundaries. A stale or retargeted same-name choice could silently notify the wrong person.

Behavior/contracts traced: membership-driven refresh and coalescing; cancellation and stale-response fences; community/identity reset; stable installed autocomplete choices during background rerank; exact-pubkey/channel admission at pointer, Enter, Tab, pin, and publication boundaries; persistence and editor lifecycle; unavailable/Retry behavior; same-name identity presentation; keyboard, pointer, and focus behavior.

Findings: No blocking or non-blocking code defect found. The prior wrong-recipient Enter/Tab blocker is resolved: the displayed request snapshot remains identity-stable while current evidence updates availability, and action-time admission rechecks the exact displayed destination. The regression moves selection to the second of two same-name rows, injects reordered results, and proves Enter and Tab still bind the originally selected pubkey (desktop/src/features/messages/lib/useMentionSelection.ts:7-43, desktop/src/features/messages/lib/useMentions.ts:499-599,793-844,909-941, desktop/src/features/messages/lib/mentionAdmissionJourney.test.mjs:564-610). Mutation back to live reranked candidates made both regressions fail; restored production code passed.

Unavailable identities retain their installed row rather than transferring the old index to another recipient, become disabled with a truthful reason and Retry, and Retry preserves keyboard focus (desktop/src/features/messages/lib/useMentions.ts:516-535; desktop/src/features/messages/ui/MentionAutocomplete.tsx:337-404,511-554).

Author action: none.

Verification owner: CI/release gate for required merge checks; reviewer/tooling for any additional native accessibility assurance.

Validation at exact head:

  • Full Desktop unit suite: 6,164/6,164 passed.
  • Focused consolidated mention/lifecycle suite: 97/97 passed.
  • Same-name mutation suite: restored code 31/31 passed; deliberate unstable-candidate mutation failed the Enter and Tab regressions.
  • Membership-refresh mutation: removing refresh scheduling failed joined/removed-member regressions; restored tree passed.
  • Desktop typecheck: passed.
  • pnpm check: passed with pre-existing non-fatal warnings.
  • Full just test: passed, including 2,019 mobile tests.
  • Browser picker journey: 3/3 passed; inspected distinct same-name and Checking/Unavailable/Retry states.
  • Exact-head GitHub checks: 17 successful, 10 path-filtered/skipped, 0 failed, including Desktop Core, Desktop smoke/relay/integration E2E, Windows/macOS builds, Semgrep, zizmor, and DCO.

Manual/native evidence: Browser Chromium/mock-bridge journey and screenshots were inspected. Native Tauri/WebKit, VoiceOver, and IME were not run.

Residual risk: OS-delivered keyboard, screen-reader announcement, and IME behavior remain unwitnessed natively. Source, mutation-resistant tests, browser interaction evidence, full package tests, and platform builds found no author-actionable defect. Local just check could not resolve origin/main in the review checkout because the file-size script strips the MCP checkout's required GIT_CONFIG_*; this is reviewer-environment contamination, not a PR-caused gate failure, and the corresponding exact-head GitHub checks are green.

— :bot: Jude’s code review agent

loganj added a commit that referenced this pull request Sep 11, 2026
…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>
Base automatically changed from fix/mention-picker-stack-844abd33-1 to integration/mention-picker-stack-844abd33-base September 11, 2026 16:51
…hoices

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
@loganj
loganj force-pushed the fix/mention-picker-stack-844abd33-2 branch from 0973992 to 4b0a3e8 Compare September 11, 2026 16:56
@loganj
loganj merged commit 1c33575 into integration/mention-picker-stack-844abd33-base Sep 11, 2026
27 checks passed
@loganj
loganj deleted the fix/mention-picker-stack-844abd33-2 branch September 11, 2026 17:28

@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 — APPROVE

Reviewed: 65e814f7286063143ce95022ae0f3705de9ec4d3..4b0a3e8dbafadeea14a8155c3d0e269328400cf6 (exact head 4b0a3e8dbafadeea14a8155c3d0e269328400cf6). The PR merged at this immutable head while final evidence was being reconciled, so this is the exact-head review verdict; author action: none.

Risk: High — this affects recipient correctness across asynchronous directory refresh, membership/community lifecycle, stable selection, pinning, and publication. A stale or silently retargeted same-name choice can notify the wrong person.

Behavior/contracts traced: background membership-event delivery; refresh coalescing, cancellation, and stale-response fencing; community/identity reset; stable installed choices through rerank or disappearance; exact-pubkey/channel admission for pointer, Enter, Tab, pin, and publication; unavailable/Retry and focus behavior; same-name presentation; persistence and editor lifecycle.

Findings: No blocking or non-blocking code, product/UI, accessibility-contract, or regression-causality defect found. The restack introduced no implementation delta: prior reviewed head 0973992daf750590225dd9a0b1d2cf5874eb71d3 and this head both resolve to tree 37197dcfc70d80225ca15e0d7b78d58d1bb0ea09; their diff is empty. Full revalidation at the new SHA still confirmed that stable installed identity survives rerank/disappearance, unavailable rows remain disabled with truthful reasons, Retry restores editor focus, and Enter/Tab/pointer admit the exact displayed destination.

Author action: none.

Verification owner: CI/release owned required gates, all green before merge. Reviewer/tooling owns optional additional native Tauri/WebKit, VoiceOver, IME, and live-relay assurance.

Validation at exact head, clean worktrees:

  • Full Desktop unit package: 6,164/6,164 passed.
  • Focused product/mention/lifecycle suite: 183/183 passed.
  • Focused systems/lifecycle suite: 157/157 passed.
  • Browser Playwright picker journey: 3/3 passed.
  • Desktop typecheck and pnpm check: passed; only pre-existing non-fatal diagnostics were reported.
  • Membership-refresh mutation: deleting the background all-channel refreshDirectoryAfterMembershipChange call made joined/removed regressions fail; restored code passed.
  • Stable-choice mutation: replacing installed snapshots with live reranked candidates failed 8/31, including same-name Enter and Tab identity contracts; restored code passed.
  • Exact-head checks: 17 successful / 10 path-filtered skipped / 0 failed, including Desktop core, smoke, relay/integration E2E, macOS/Windows builds, Semgrep, zizmor, and DCO.

Manual/native evidence: Browser Chromium/mock-bridge interaction was rerun. Native Tauri/WebKit, VoiceOver, IME, and a new live-relay journey were not rerun.

Residual risk: OS-delivered keyboard, screen-reader announcement, IME, and native WebKit behavior remain unwitnessed at this restacked SHA. This is a reviewer/tooling confidence gap, not an author-actionable defect: the source tree is identical to the previously approved implementation, causal regressions and full Desktop tests pass, browser interaction was exercised, platform builds and exact-head CI are green.

— :bot: Jude’s code review agent

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