fix(threads): Working holds only background work the agent waits on#24610

merged5
main
takeover/pr-22055
opened4d agobyTtheo
View on GitHubTwo-way sync enabledPR last imported 4d ago

With the Working section on, threads came back to the inbox while the agent was only waiting on something: tests, benchmarks, CI, a data backfill. In two weeks of real use this happened 121 times, all from Claude background shells, so threads sat in the inbox for about 28 hours in total with nothing to act on. The opposite happened too: a dev server's watchdog Monitor kept a finished thread stuck in Working.

Both came from deciding by task kind. A background shell never held a thread and a monitor always did, but either one can be a wait or a process left running. Only the agent knows which.

Change

  • The agent says what it waits on. A new MCP tool, t3_background_wait, marks the background commands or Monitors the agent will act on when it is woken. waiting: false clears a mark. IDs that are not running come back in unmatched and change nothing.
  • One hold rule. In backgroundWorkHoldsCompletion, marked work, subagents, background tasks, and PR watches hold a thread. Unmarked commands and monitors never do. The same rule drives the Working list on web and mobile, completion alerts, auto-settle, and the restart wake.
  • Claude implements it. The mark lives beside Claude's background-task roster: it ends with the task and resets with the process. Claude Code defers MCP tools behind ToolSearch, so its system prompt says when to use the tool.
  • Other providers return "unsupported" and keep today's behavior. Their background lists only hold subagents, which still hold.
  • Older clients and servers ignore the optional awaited field.

Takeover

Replaces #22055 by @LovelyCodeMonkey. Their three commits are kept as they were, with authorship, and cherry-picked cleanly onto current main. Added two commits: the restart-recovery doc (docs/internals/server-updates.md) and the shellRuntime comment still described the old rule, and the t3_background_wait description now uses shorter, plainer sentences with the same facts.

Evidence

Live runs against an isolated dev server (its own state, no copied data), Claude Opus 5.5, with prompts that never mention T3 tools:

Scenariot3_background_waitRoster after the turnHolds in WorkingThen
sleep 75 && echo 'ALL 42 TESTS PASSED' in the backgroundcalled on its owncommand, awaited: trueyeswoke on exit, reported the result, came back
Monitor on a 3-step deploycalledmonitor, awaited: trueyeswoke on each step, then reported "DEPLOY DONE"
Monitor with a 50 s gap between eventscalledstill awaited: true between wakesyesfinished
python3 -m http.server plus an error-watch Monitor, "leave both running"not calledcommand and monitor, unmarkednoback in the inbox right away; main keeps it in Working

An unplanned server restart during a first attempt also exercised the restart path: the threads with awaited work were woken with the restart note. After the description rewrite, the first and last rows ran again with the same result.

Screenshots from #22055 show the same behavior in the app (other thread titles blurred):

Tests, before (main)Tests, after, while waitingTests, after, with the result
main: back in the inbox while tests runbranch: in Working while tests runbranch: back with the result
Dev server, before (main)Dev server, after
main: stuck in Workingbranch: back in the inbox

Tests: vp test run passes for the shared hold rule and awareness, client-runtime presentation, web Sidebar.logic, mobile threadListV2, and the server's Claude adapter, thread management, settlement, restart note and continuation, projection store, delegated completion, runtime layer, awareness relay, and MCP suites. vp run check:changed passes.

Proved with live runs on an isolated dev server plus focused tests.

Reviewed with sol-loop: 1 round with GPT-6.1 Sol on high, before the copy-only description rewrite. Sol verdict: approved

Written by Claude Opus 5.5 in Claude Code, run from T3 Code. Tool description copy by Muse Wonder Full in Muse Code. Original implementation by @LovelyCodeMonkey with Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code

Checks

23 successful · 13 skipped · 1 neutral
All checks passed
1d989a7
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR adds a new background-wait tool and changes when monitors keep threads in Working or trigger restart recovery. Because it changes product defaults and affects thread lifecycle behavior across server and client layers, the change warrants human review.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

âś… Thread transfer remains within every enforced ceiling.

ℹ️ The exact PR base did not have a successful artifact. Baseline uses the latest successful main measurement shown below.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiBâś…
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiBâś…
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiBâś…
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiBâś…
CodexLive turn messages220 (0.0%)8âś…
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiBâś…
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiBâś…
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiBâś…
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiBâś…
ClaudeLive turn messages220 (0.0%)8âś…

Baseline: 8bcef34 · PR result: 1d989a7 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between d2bc1f9e1d8804771d3713cd1937ad7166f17d3f and 1d989a7862b342ee294f039be6b8c25dd6816d85.

External image Files selected for processing: 1
  • apps/server/src/mcp/toolkits/orchestrator/tools.ts

Limit details: You’ve used all 10 included reviews currently available.

Walkthrough

The change adds an MCP tool to mark background tasks as awaited. Provider task rosters carry the awaited marker, and completion, restart-continuation, and thread-status behavior distinguish awaited work from other running commands and monitors.

Changes: Background wait behavior

Layer / File(s)Summary
Track awaited tasks on provider threads
packages/contracts/src/orchestrationV2.ts, packages/provider-core/src/server/ProviderAdapter.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
The contracts add an optional awaited: true marker. The provider runtime adds an operation to mark or unmark task IDs. The Claude adapter tracks marks by thread, includes them in rosters, and removes them when tasks leave the roster.
Expose background waits through orchestration
apps/server/src/orchestration-v2/ThreadManagementService.ts, apps/server/src/orchestration-v2/ThreadManagementService.test.ts, apps/server/src/mcp/toolkits/orchestrator/*, packages/shared/src/t3McpToolPresentation.ts, packages/client-runtime/src/t3ToolSummary.ts, packages/client-runtime/src/work-log/presentation.ts
The thread-management service calls the provider runtime and returns matched and unmatched IDs. The t3_background_wait MCP tool accepts task IDs and an optional waiting flag. Tool presentation and summaries include the new action.
Apply awaited state to completion and thread status
packages/shared/src/orchestrationV2PendingBackgroundWork.ts, apps/server/src/orchestration-v2/RestartBackgroundNote.ts, apps/server/src/orchestration-v2/runtimeLayer.test.ts, apps/server/src/orchestration-v2/RestartBackgroundNote.test.ts, apps/server/src/orchestration-v2/RestartContinuation.test.ts, apps/server/src/orchestration-v2/DelegatedCompletionDelivery.test.ts, apps/server/src/orchestration-v2/ProjectionStore.test.ts, packages/shared/src/*test.ts, packages/client-runtime/src/state/*, apps/server/src/relay/AgentAwarenessRelay.test.ts, apps/web/src/components/Sidebar.logic.test.ts, apps/mobile/src/features/threads/threadListV2.test.ts, docs/internals/server-updates.md, docs/user/thread-sidebar.md, docs/user/updating.md
Commands and monitors hold completion when marked awaited; unmarked commands and monitors do not. Restart handling carries the awaited marker into cancelled-work checks. Tests and documentation reflect completion and thread-status behavior.

Priority: External image Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant OrchestratorToolkit
3 participant ThreadManagementService
4 participant ProviderAdapterV2SessionRuntime
5 participant ClaudeAdapterV2
6 OrchestratorToolkit->>ThreadManagementService: Submit task IDs and waiting flag
7 ThreadManagementService->>ProviderAdapterV2SessionRuntime: Mark tasks on provider thread
8 ProviderAdapterV2SessionRuntime->>ClaudeAdapterV2: Match IDs and update awaited marks
9 ClaudeAdapterV2-->>ProviderAdapterV2SessionRuntime: Return matched IDs and updated roster
10 ProviderAdapterV2SessionRuntime-->>ThreadManagementService: Return matched IDs
11 ThreadManagementService-->>OrchestratorToolkit: Return matched and unmatched IDs

Possibly related issues

Possibly related PRs

  • pingdotgg/t3code#17885: Both changes affect Claude background-task wake behavior, at separate gates in the wake flow.
  • pingdotgg/t3code#22458: Both changes affect Working placement and completion notifications.
  • pingdotgg/t3code#24391: Both changes affect Claude provider-thread rosters around background-task completion and wake delivery.

Suggested labels: bugfix, takeover

Suggested reviewers: juliusmarminge, macroscopeapp

Merge Risk: External image Minimal · up to 1d989

No actionable merge-blocking risk is established for this change.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title "fix(threads): Working holds only background work the agent waits on" matches the main change. The changeset adds an agent-driven t3_background_wait mark and changes `backgroundWorkHoldsCo…
Description checkPassedThe description follows the template's main sections: Problem, Change, Scope and approval, and Verification. It explains the problem and the fix, and it lists the live runs and test suites that were r…
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "fix(threads): Working holds only background work the agent waits on" matches the main change. The changeset adds an agent-driven t3_background_wait mark and changes backgroundWorkHoldsCompletion so unmarked commands and monitors no longer hold a thread in Working. The title is concise, uses a conventional commit prefix, and names the primary behavior change.

Full details: Description check

Explanation

The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. It explains the problem and the fix, and it lists the live runs and test suites that were run. It links the replaced PR #22055 and the screenshots. The Scope and approval section does not link a triaged issue or maintainer approval, and it does not explain why the change qualifies without one. The description also has no explicit Problem heading for the bug reproduction steps beyond the live runs. The description is mostly complete, so the check passes, but the missing approval link should be added.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
đź§Ş Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Usage-based review receipt

Note

This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.

Comment @coderabbitai help to get the list of available commands.

Added 5 commits

  • docs: monitors the agent waits on also keep a thread in Working0bc5b96
  • docs: restart recovery only wakes for work the agent marked35072e1
  • fix(threads): Working holds only background work the agent waits on6421ae4
  • fix(threads): the work log no longer says a cleared background wait was markedf2c66b3
  • chore(server): simpler t3_background_wait description1d989a7