Repository navigation
Conversation
Add RelayRecovery.register for dynamic sources, createRecoverableRead for stores and useRecoverableRead for React surfaces, so a passive read's connectivity failure feeds the one recovery notice instead of its own error. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
The Solo groups read rethrew the kit's error as a plain Error, so a 5xx or timeout lost its connectivity classification: the store never flagged it transient, session recovery treated it as settled and never retried, and "Retry workspaces" stayed until a reload. Keep the kit's verdict as a ReadError, and hide the workspaces error and both Retry workspaces controls while the failure is transient. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…-activity reads Visibility exhausted its quiet retries without a transient flag, so its recovery source never retried and the sidebar showed its own error. Flag a connectivity failure transient and hide the inline error and Retry. Recent activity gets the same: report transient failures, register a recovery source that re-reads the roster, and hide its own toast so only the one recovery notice shows. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…sion recovery An older page that fails for connectivity now joins session recovery, which pages again on its own: the timeline edge shows "Loading older…" instead of the reason and Retry, and the offline "load older once Buzz reconnects" copy is gone. A first window read that fails for connectivity does the same in the channel body. The window snapshot gains `transient` to say so. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
Opening a thread starts its read by itself. A connectivity failure of the thread read, an older page or the selected message no longer shows "This thread didn’t load." or Try again; recovery retries it and the thread fills in. Unavailable and not-found variants are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
The profile panel's kind 0 read, owner evidence read and channel list no longer show "Could not load this profile.", Retry profile or Retry channels for a connectivity failure; recovery retries and fills them in. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
Opening Manage members starts the roster, names, roles, owners and general access reads by itself. A connectivity failure of any of them no longer shows its own message, Retry member data or Reload access; recovery retries them and the dialog fills in. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…recovery notice Opening the emoji, mention and recipient pickers loads catalogs, agent inventory, archive evidence and people. A connectivity failure in those passive loads no longer shows the picker's own error text or Retry; each joins session recovery through useRecoverableRead and fills in when the relay answers. Stores report `transient` (emoji directory, identity archives, agent library and choices) so the pickers can classify without parsing strings. The emoji directory stores the error message rather than String(error), so no raw "ReadError:" prefix appears, including in the send-time preparation error, which keeps its error and Retry. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
The Sent view and the draft preview showed their own "could not be loaded" error and Retry on a 503 or timeout. Observed views now flag connectivity failures (additive `transient` on EventViewSnapshot); the Sent view joins session recovery with useRecoverableRead and the preview defers to head recovery. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
Workflow discovery ("Workflow discovery paused" + Retry), the per-channel
configuration and run-history reads, and the channel list ("Retry channels")
showed their own error on a 503 or timeout. Workflow views and the channel list
now flag connectivity failures (additive `transient`); the page joins session
recovery with useRecoverableRead, reads as loading meanwhile and refills on its
own when the connection returns.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Signed-off-by: Matt Toohey <[email protected]>
The Todos panel showed "ReadError: Relay request failed (503)" and "Couldn't load todos. Try Refresh." for a failed Canvas read, plus its own "Channel members unavailable" and "Retry users" for the channel list and profile reads. It now joins session recovery for those passive reads, reads as loading meanwhile and fills in on its own. Save errors and denials are unchanged. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
The socket-interruption snapshot is a deliberate editor message that retains the draft (covered by the workflows journey), so it is not flagged transient. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…ures to the recovery notice The agent inventory and the archive list load when the members dialog opens. Under a connectivity failure they showed "Some agents could not load." and "Archived identities could not be checked." beside Retry until a reload. Read them with useRecoverableRead like the rest of the dialog, so they hide while quiet and recovery retries them and clears the messages on its own. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…overy The inbox, mention feed and reaction feed snapshots now say when their error is a connectivity failure (transient). The Activity page and its sidebar preview register those reads with session recovery and hide their own error text, Retry activity and the Refresh prompts while recovery retries, so only the recovery notice reports the outage. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…o session recovery The agent library snapshot and the merged inventory carry transient when the relay's own read failed for connectivity. Shared notes hides the inventory error and Retry agents (and the notes errors) for it, and the Agents marketplace hides Try again; both retry through recovery and fill in when the relay answers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…ssion recovery The joined-conversation list and the channel directory that load when Command-K opens no longer show Couldn't load... or Retry channels for a connectivity failure; recovery retries them and the recovery notice is the one report. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
Mount the recovery toast at the app level so cached/offline mode and a retrying connect show "Buzz is having trouble connecting" after the same 30 s quiet delay, once, and clear when connected. A visit that failed only because the connection is retrying keeps loading instead of adding a second "Can't connect" card. The sidebar's Offline strip with Retry stays only for a failure nothing retries. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…ce pages Search, Activity, Shared notes, Workflows, Bestie and Channels no longer show their own offline copy, raw error or Retry while the connection retries by itself. Saved-conversation search results stay. A failure nothing retries keeps its own state. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
When the identity read fails for a reason that clears by itself, retry it on the recovery backoff and on online/focus, read the connection as failing and retrying, and open the shell instead of claiming the account has no access. A wrong answer from the broker is still not retried. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
…ading and reopen it A visit opened while the session is live but its reads are failing (a full relay outage after load) timed out into "This page isn't available" with Try again, replacing the page and any open dialog, and never reopened when the relay returned. Session recovery already retries those reads and the one notice reports them, so treat "recovery is retrying" like a reconnecting connection: the timed-out visit keeps its loading view and reopens once, by itself, when recovery settles and the connection is ready. Denied, removed and unknown visits, host-decided failures and Settings keep their cards. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Signed-off-by: Matt Toohey <[email protected]>
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Required typecheck and new recovery tests fail at this head. Three concrete fixes below.
| key={createdRun ?? ""} | ||
| capability={capability} | ||
| workflow={history} | ||
| recovery={session.recovery} |
There was a problem hiding this comment.
🤖 [P2] Preserve the optional-session contract. session is RelaySession | undefined, so this dereference fails typecheck (TS18048) and crashes existing session-less component callers with Cannot read properties of undefined (reading 'recovery'). It reproduces in 51 WorkflowLanding tests. Use session?.recovery, as the other call site does. Production WorkflowsPage supplies a session; the demonstrated defect is the optional component contract and required build gate.
| * the notice timer, retryNow and retryAll like a static source. The returned | ||
| * function removes it and re-evaluates, so a failed source that goes away | ||
| * cannot keep the notice up. Registering twice adds it once. */ | ||
| register(source: RecoverySource): () => void; |
There was a problem hiding this comment.
🤖 [P2] Migrate the typed recovery doubles when requiring register. Nine LiveStatus.test.tsx implementations (lines 59, 332, 341, 361, 396, 453, 516, 581 and 649) still omit this method and produce TS2741. All six JavaScript CI shards stop at typecheck before Vitest, and local typecheck reproduces it. Update those implementations, using the real recovery owner where practical.
| loadingOlder: loadingOlder || accepted, | ||
| historyLimited, | ||
| error, | ||
| ...(transient ? { transient: true as const } : {}), |
There was a problem hiding this comment.
🤖 [P2] Forward transient state into the rendered window. The fixture adds this flag to its store snapshot, but render() separately constructs the ChannelTimeline window at lines 323–332 without it. Both new older-page recovery cases consequently retain Relay request failed (503) and fail at line 2113. Pass the snapshot or transient flag to the actual component so these tests exercise the intended recovery state.
## TL;DR Captured explicit reads now check the current saved manual-unread journal inside the replacing transaction, so a newer local choice—including one saved by another window—is not erased. Retries retain their original cut; the additive `unread.prepareThreadRead(channelId, rootId)` captures only retained incoming replies without reading the root or advancing the channel. The fence also preserves earlier same-window queued manual actions, authorizing their revisions only after a successful save whose prior same-key intent is also captured. An earlier queued save cannot mask an intervening unread choice from another window. It leaves reading-lease ownership, passive observations, remote-marker ordering, journal format and relay protocol unchanged. Mark all now reserves one shared saved revision cut before queued writes. Each predicate retains only the revision, not a full journal copy. ### Validation - Shared-cut correction: pinned Linux Blox run of both complete owner files passed 383 tests (174 read-state; 209 unread). The per-sweep capture-budget and capture-failure regressions fail on the prior implementation; older queued-save controls pass. No new browser cases. - Linux Blox, pinned tools: both owner files passed 366 tests on the initial head. After review fixes, `pnpm exec vitest run src/features/relay/unread.test.ts` passed all 206 tests. The final queue-ordering fix passes all 174 tests in `src/features/relay/read-state.test.ts`, typecheck and the commit/push hooks. - Pre-fix channel regressions: six failures; bypassing the new transaction fences makes eleven targeted concurrency regressions fail. Replacing canonical thread selection with parent-edge traversal makes the narrow-thread regression fail. Restoring the implementation passes both owner files. - Three successful-save interleavings fail before the final fix and pass afterward, with three matching controls: channel, thread and message marks overwritten by an older queued save after another window marks unread. - Eight additional regressions fail before the review fixes and pass afterward: root/reply deletion before or after persistence, and shared sidebar hints with absent, present or cross-window forced-message overlays. - Touched-file Biome, `pnpm typecheck`, `pnpm author:build`, strict generated-SDK consumer compilation and repository commit/push hooks. - Deterministic fixture gates cover newer channel/thread/message marks, second-window saves at the transaction boundary, queued ordering, retry cuts, later arrivals, independent root/thread markers and access/lifecycle expiry. No browser tests were added or removed. Generated type-only SDK declarations expose the additive method through the existing `UnreadCapability` export; existing channel and message APIs remain compatible. Capture requires initialized read-state storage. The thread API does not discover history; receipts remain device-local. A narrow read leaves the shared sidebar hint until channel open reconciles it, since that hint has no subtree ownership. Its shared message-force fence is conservative: a newer mark elsewhere in the same channel can also reject the save. This does not establish native runtime behavior, identical remote-tuple ordering or atomicity through an operation's eventual return. Related independent work remains with #2060 (quiet Solo/Inbox), #2610 (selected-message UI), #3181 (passive recovery), and #2939/#1666/#2956 (notification/audience behavior). This change is limited to the explicit mutation/preparation seam. Fixes NEXUS-4426 [Initiative status](https://g2.sqprod.co/apps/kylez-buzz-improvements-status) *Posted by Codex (gpt-6.1-sol) on behalf of kylez.* Signed-off-by: Kyle Zemek <[email protected]> Co-authored-by: Codex <[email protected]>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s team source review, with independent Rocket, Mantis and Groot lanes and Star Lord integration across the 89 changed files.
Reviewed head f6b89e95d105f95aabad44a439ba0fe90c0421ec against target/merge-base 157bbb464c529a42cf16be077079441b1cac7fd9.
Four new P2 findings are attached inline:
- Automatic recovery after a failed Todos Refresh can discard newer local work or invalidate an active save.
- Typed recipient searches lose their own error and Retry feedback.
- A transient profile-retry failure can remove the focused Retry control without transferring focus.
- Non-transient activity HTTP 4xx responses enter indefinite quiet recovery and produce a misleading connection notice.
We also confirmed the source paths behind the existing optional WorkflowLanding session, required recovery.register test doubles, and timeline transient fixture findings. Those are not duplicated inline.
Coverage: Rocket reviewed recovery/session/store lifetimes and classification; Mantis reviewed identity, agents, member administration, workflows, drafts, inbox, todos and notes; Groot reviewed consumer recovery, search/pickers and focus; Star Lord reviewed app/navigation/sidebar integration, cross-lane findings and supplemental test diffs. Relevant design, navigation, relay and vision contracts informed the review.
Source-only limitations: no tests, typecheck, builds or apps were run, and no live behavior was reproduced. A single hosted-check snapshot showed required CI failing at this head; we did not establish the cause of every failing job. The PR description’s 38 video attachments remain uninspected. Test-source inspection does not establish runtime correctness or approval.
| const { quiet: loadQuiet } = useRecoverableRead( | ||
| recovery, | ||
| { | ||
| status: busy === "load" ? "loading" : loadFailure ? "error" : "ready", |
There was a problem hiding this comment.
🤖 [P2] Preserve newer todo edits when retrying a failed refresh
After an already-loaded panel’s Refresh fails transiently, loaded stays true and busy clears, so the person can type a new todo while recovery backs off. This callback then calls load() without the dirty/input confirmation used by the Refresh button. On success, load rebuilds the draft from the mount-time saved/savedDirty values (lines 250–270), clearing that newly typed input and potentially replacing newer unsaved content. It can also increment operation.current during an active save, invalidating its completion. Limit automatic recovery to the initial, not-yet-loaded read; keep a loaded panel’s explicit Refresh failures visible and under the existing confirmation/write guards. This also preserves the design guide’s requirement to merge refresh results into the latest draft.
| ? "loading" | ||
| : "ready", | ||
| error: directory.error || undefined, | ||
| transient: directory.transient, |
There was a problem hiding this comment.
🤖 [P2] Keep typed recipient searches out of passive recovery
usePeople(session, query) also executes the text typed into “Message recipients”, but this registration treats every query as passive. If a typed search fails transiently, it hides both its alert and Retry; directory.loading is false between attempts, while directory.error also suppresses “No matching people”, so an uncached query leaves an empty chooser until the next automatic retry. This violates the stated contract that typed searches keep their own errors. Restrict this registration to the empty-query listing, as MentionPicker does with directory.passive, and retain the existing error/Retry for typed queries.
| {((!profile && shown !== "loading") || | ||
| (profile?.verified && shown === "error") || | ||
| retrying || | ||
| ownership.failed) && ( | ||
| (ownership.failed && !ownerRead.quiet)) && ( |
There was a problem hiding this comment.
🤖 [P2] Transfer focus before quieting a failed profile retry
A keyboard user can focus “Retry profile” after an empty profile result or a non-transient failure. If that retry then fails transiently, the rejection handler clears retrying and shown becomes loading; with no owner error, this condition removes the focused button. The success handler transfers focus to the stable region, but the transient-failure handler does not, leaving focus on the document body even when a later automatic retry succeeds. Preserve the design guide’s focused-retry contract by handing focus to the region before hiding this control (without stealing focus if the person already moved), and cover this failure-to-recovery transition.
| // Batches that landed before the failure still apply. | ||
| values = merge(ids.slice(0, offset)); | ||
| status = "error"; | ||
| transient = isTransientFailure(error); |
There was a problem hiding this comment.
🤖 [P2] Keep permanent activity HTTP errors out of indefinite recovery
The browser activity transport throws httpReadError(result.status) (transport.ts:1295), which maps non-authentication 4xx such as 400/404/422 to ReadError("unavailable"). isTransientFailure returns true for all such errors regardless of status. With the newly registered activity source, a rejected or unsupported activity request now retries indefinitely, hides the activity warning in ChannelInventory, and eventually shows a misleading connection notice, even while other relay reads work. Honor the promised non-transient-4xx boundary when setting this recovery flag; retain retries for 408/429/5xx and transport outages. This does not require changing the existing bounded edge-error retry policy used by retryRead.
## TL;DR Let the optional Undo from `markCapturedMessagesRead` restore ordinary unread messages, not just saved reminders. Restore only that action’s local receipts and cleared visit overlays, without rewinding synced channel or thread prefixes. Full captured inverses carry `undoScope: "captured-action"` alongside `undo`. Untagged older handles may restore saved reminders only, so callers can check coverage without host-version allowlists. The handle expires after any later durable journal write or loss of captured access/lifecycle evidence. This conservative boundary preserves newer reads and manual unread intent, including writes that leave the journal revision unchanged. Failed inverse transactions remain retryable; repeat Undo rejects. Synthetic regressions cover exact IDs across channels, already-read and own messages, forced overlays, later and overlapping actions, storage failure, and access/deletion/visit/session changes. They also verify that restored ordinary unread can auto-read normally rather than becoming a sticky manual reminder. Deterministic commit-return cases failed before the fix and pass afterward: a change to one captured row no longer suppresses a valid overlay on another. No browser journeys were added or removed. Native app and live-relay behavior have not been exercised. Related work touches the same owner or documentation: [#3340](#3340), [#3181](#3181), [#3009](#3009), and [#3434](#3434). This change does not alter their divider, disconnect, row-receipt, or layout behavior. Generated with Codex (gpt-6.1-sol) on behalf of kylez. Signed-off-by: Kyle Zemek <[email protected]> Co-authored-by: Codex <[email protected]>
Why
During a relay outage the app reports the problem many times over. The recovery toast appears, and the sidebar, pickers, panels and pages each add their own inline error and Retry button, often with raw text such as
ReadError: Relay request failed (500)orTypeError: Load failed. Several of those errors stay after the relay comes back until the user reloads. Offline mode has no app-level notice at all, and a broker that is unreachable at launch is shown as an access denial.What
On the main surface, a connectivity failure now produces one message: the toast "Buzz is having trouble connecting / Retrying automatically." Passive reads (anything the app loads by itself, including what a picker, panel or dialog loads on open) hide their own disconnect error and Retry, join session recovery, and fill in on their own once the relay answers. Nothing needs a click or a reload.
Unchanged by design:
Surfaces covered: the connection itself (offline mode, a failing connect, launch with an unreachable broker, a visit that times out during an outage), the sidebar (hidden conversations, Solo workspaces, recent activity), the channel view (older messages), thread/profile/members panels, the composer pickers (emoji, GIF, mentions, recipients), Activity, Shared notes, the Agents marketplace, the ⌘K lists, Drafts & sent, Workflows and Todos.
How
feat(relay):RelayRecovery.register(source)lets any read join session recovery while it fails.useRecoverableRead(React) andcreateRecoverableRead(stores) returnquiet; while quiet, a surface hides its own error and Retry. The rule is documented at the top ofsrc/features/relay/recoverable-read.ts.Error, which dropped the transient classification so recovery never retried them. Those stores now carry an optionaltransientflag.ConnectionNoticeis mounted once inApp.tsx(no longer in the sidebar). It shows the toast after 30 s when either session recovery's notice is due or the connection itself is erroring/retrying or serving cached data.Native-only surfaces (Reminders, Huddles) have equivalent fixes on stream branches but are held back from this PR until they can be recorded natively.
Testing
Not run locally; relying on CI. Unit tests were updated/added for the behaviour changes. Every change below has a side-by-side recording: Before is
ba3455d52, After is this branch, both driven by the same fault timeline in WebKit. Long waits are fast-forwarded (badge shown).Whole app (merged branch)
Full relay outage with a reload, visiting the mention picker, #general, Activity and the members dialog. Before stacks inline errors and Retry buttons under the toast; After shows loading states and the toast only.
01-full-outage-tour.mp4
Same tour without a reload. After restore, Before stays stuck; After fills in on its own.
01b-full-outage-tour-no-reload.mp4
Offline mode after a reload. Before shows "Offline · Showing saved conversations.", the ⌘K note and "TypeError: Load failed", each with Retry connection, and no toast. After shows only the toast and recovers on its own.
03-cached-offline-tour.mp4
Opening #general during an outage. Before gets stuck on "This page isn't available". After keeps loading, shows the toast and opens #general by itself.
05-visit-during-outage.mp4
Members dialog during an outage. Before keeps "Some agents could not load." and "Archived identities could not be checked." after restore; After shows neither.
02-members-dialog-outage.mp4
Solo workspaces with a 503 on the channel-kit read. Before keeps "ReadError: Relay request failed (503)" + Retry workspaces; After never shows them.
04-solo-workspaces-retry.mp4
Connection, offline mode and launch (7 videos)
Offline mode. Before: the "Offline" row with Retry. After: only the toast at ~30 s.
01-cached-offline-notice.mp4
Full outage: one toast, cleared on restore (confirms a single mount).
02-relay-outage-notice.mp4
Broker unreachable at launch. Before: "You don't have access to this", never recovers. After: "Connecting…", the toast, then the community loads.
03-broker-unreachable-at-launch.mp4
Connect failure with nothing cached. Before: the "Can't connect" card and no toast. After: loading and the toast, then reopens by itself.
04-no-cache-connect-failure.mp4
Offline mode on Workflows, Bestie, pinned Bestie and the Activity preview. Before: "TypeError: Load failed" + Retry connection on each. After: "Connecting…" and the one toast.
05-cached-pages-tour.mp4
A malformed session response (not a disconnect). Both sides keep their notes and Retry; no toast. Confirms non-connectivity errors are untouched.
06-cached-nonretrying-error-keeps-retry.mp4
Fresh profile with a failing connection, open Agents, return to Messages. Before: a second "Can't connect" card. After: loading and the toast.
07-visit-settled-no-second-card.mp4
Sidebar (4 videos)
Full outage with a reload. Before: hidden-conversations and workspaces errors; the workspaces error sticks after restore. After: only the toast.
01-full-outage-whole-sidebar.mp4
503 on the hidden-conversations read. Before keeps the error and Retry; After shows nothing inline.
02-hidden-conversations-503.mp4
503 on the preferences and templates reads. Neither side errors; these were already gated.
03-preferences-503.mp4
Recent-activity read held. Before: the "Couldn't refresh recent activity" toast with Retry. After: only the recovery toast.
04-recent-activity-hold.mp4
Channel view (3 videos)
Older messages during an outage. Before: "Retry older messages". After: "Loading older…", then the page loads itself after restore.
03-older-messages-outage.mp4
An uncached channel with its window read failing. Both sides stay on loading and fill in; the new owner is a safeguard.
01-uncached-channel-window-503.mp4
A cached channel through a 30+ s outage. No strip or edge error on either side; a new message arrives after restore.
02-cached-channel-outage-restore.mp4
Thread, profile and members panels (3 videos)
An uncached thread. Before: "This thread didn't load." + Try again, stuck. After: loads, toast, fills in.
01-thread-uncached.mp4
A profile with the kind 0 read failing. Before: key-only panel with Retry profile. After: "Loading profile…", then name and bio.
02-profile-kind0.mp4
Members dialog with the member-list read failing. Before: "Relay request failed (503)" twice and "The member list could not load." After: cached list, then access details fill in.
03-members-dialog.mp4
Composer pickers (6 videos)
Emoji picker with the catalog read held. Before: "ReadError: Relay read timed out" + Retry emoji, even after the fault clears. After: Unicode grid, toast, recovers.
01-emoji-picker-held-read.mp4
Mention picker with a 503 on agent and archive reads. Before: textless "Retry agent list" and "Retry archive information", never clears. After: neither.
02-mention-picker-503.mp4
Mention picker left open through an outage. Before keeps "Retry community search" and three people. After fills in five people on its own.
03-mention-picker-outage.mp4
Legacy teams row with a 503. Before: "Could not load legacy teams." + Retry. After: no row error. (The Solo error here is fixed by the sidebar commits.)
04-mention-picker-legacy-teams.mp4
New DM recipient picker. Before: "Could not load people." + Retry and no toast. After: placeholder rows, toast, then eight people.
05-recipient-picker-people.mp4
Emoji
:completion and GIF availability. Before: "Community emoji unavailable…" and "Could not check GIF availability." + Retry. After: neither; the GIF check answers once the relay returns.06-emoji-completion-and-gif-availability.mp4
Activity, Shared notes, Agents and ⌘K (6 videos)
Activity with a 503 on the mentions feed. Before: "Relay request failed (503)" + Retry activity, stuck. After: neither.
01-activity-mentions-503.mp4
Activity through a 45 s outage. Before: "Showing retained activity. Refresh" prompts kept after restore. After: only the toast.
02-activity-outage.mp4
Activity preview card on hover. Before: error + Retry, stuck. After: "Checking recent activity…", then the summary.
06-inbox-preview-503.mp4
Shared notes with the agent inventory failing. Before: "Relay inventory unavailable…" + Retry agents. After: "Loading your agents…", then fills in.
03-shared-notes-inventory-503.mp4
Agents marketplace tab. Before: "Couldn't load shared agents." + Try again, stuck. After: fills in by itself.
04-agents-marketplace-503.mp4
⌘K lists on open. Before: "Couldn't load all channels." + Retry channels. After: "Loading channels…", then the list.
05-command-k-channels-503.mp4
Drafts & sent, Workflows, Todos (3 videos)
Drafts & sent. Before keeps "Sent messages could not be loaded." + Retry after the fault clears. After: toast, clears itself.
01-drafts-sent-503.mp4
Workflows. Before stays on "Workflow discovery paused" + Retry. After: "Reading workflows…", toast, then the page.
02-workflows-discovery-503.mp4
Todos panel. Before stuck on "ReadError: Relay request failed (503)". After: "Loading todos…", toast, then "No todos yet".
03-todos-canvas-503.mp4
🤖 Generated with Claude Code