Repository navigation
Description
What happened
If I click Settle too quickly after an agent finishes responding, the "Thread completed" toast still pops up for the thread I just settled.
Diagnosis
The completion notification waits out WORKING_EXIT_GRACE_MS (2s) before it fires. The wait was added for #24477, so that a thread doesn't notify between orchestrator runs. createThreadNotificationGate (apps/web/src/components/ThreadNotificationCoordinator.logic.ts) only cancels the pending timer when an observation stops being settled, the thread is archived, or a stop was requested.
Settling a thread doesn't cancel the timer:
- In
ThreadNotificationCoordinator.tsx,settledisstatus === "ready" && latestRun.status === "completed".resolveSidebarThreadStatusignoressettledAt/settledOverride, so a settled thread is still "ready" and its observation stayssettled: true. The gate sees an unchangedcompletedAtand keeps the timer running (pending.get(key)?.at === at). - The sidebar row's Settle button and the
thread.settleshortcut (⌘⇧S, viasettleAndAdvance) both go throughSidebar.attemptSettle. If the settled thread is the one open, it navigates to the next thread after the settle succeeds. - When the timer fires,
present()checks the active route. The settled thread is no longer active (or never was, when settled from another thread's sidebar row), so it shows the in-app "Thread completed" toast (or a desktop notification when the window isn't focused) for a thread the user has already dealt with.
If the user settles after the 2s window, the notification has already been skipped because they were viewing the thread, so the bug only shows up inside that window.
Suggested fix: treat a settled thread as not notifiable in the gate. For example, pass settledOverride === "settled" / settledAt >= completedAt as quiet, or cancel and skip the pending completion when the thread becomes settled.
Steps to reproduce
- Enable in-app notifications.
- Open a thread and send a prompt. Stay on the thread.
- Within ~2s of the agent finishing, click Settle on that thread's sidebar row (or press ⌘⇧S). The app advances to another thread.
- About 2s after the run completed, a "Thread completed" toast appears for the settled thread.
Version
0.1.5-nightly.20261029.3867 (6d82a22). The gate code is unchanged since 0.1.4-nightly.20261029.3853.
Environment
macOS 27.0.1, T3 Code (Nightly) desktop app against its local server, Claude Code 2.1.312
Evidence
# Threads settled 0–3s after their latest run completed (statev2.sqlite, read-only)
thread run completed_at settledAt delta
600cd4e8 2026-10-29T09:08:55.724Z 2026-10-29T09:08:57.464Z 1.74s
e3b365ea 2026-10-28T09:28:03.979Z 2026-10-28T09:28:05.754Z 1.78s
9ae9e6a4 2026-10-22T19:14:12.509Z 2026-10-22T19:14:13.994Z 1.49s
1d1b74ae 2026-10-22T09:08:24.367Z 2026-10-22T09:08:25.522Z 1.15sEach of these settles landed 1–2s after completion, inside the 2s grace window, which is the case that leaks the toast. Auto-settles in the same database land at a delta of exactly 0s.
Related issues
#24477 introduced the 2s completion grace that this escapes. #20883 (the done toast stays open after opening the thread) is a different code path. I found no existing report of a settled thread still notifying.
Fix applied or workaround
None. Workaround: wait ~2s after a run finishes before settling.
Filed by
claude (claude-opus-5-5) via t3 triage
Activity