Repository navigation
fix(server): Claude subagents that end between turns no longer stay Running - #301
Merged
Merged
Conversation
…s Running A background subagent's task_notification that arrives while the root turn is idle only went to the wake buffer, so its card completed when a continuation run drained it. A nested subagent's end never offers a continuation, and a held queue can keep the continuation from ever starting; on stage a reviewer subagent showed Running for a day after it finished. Between turns, a running registered subagent's end now completes its card at once through the turn that settled last, as its progress already does. The frame still waits in the wake buffer, so the wake label and continuation offer are unchanged; the drain skips the card update it already made, and the undrained end keeps pinning the session until then. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stop holds every queued run, and each later queued run copied that hold. A continuation that ProviderContinuationService queues for output the Claude CLI already produced (it started a turn by itself) was held with them, so it never ran: the adapter kept that output, and every later wake on the thread, in its buffer. On stage this lost three agent replies and a subagent's completion. An adapter continuation (createdBy agent, creationSource provider) no longer copies the hold, and the queue starts the first queued run that is not held. Held user runs keep waiting for the user, in their order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inuations A second end that arrives behind a buffered resume must wait for the drain that re-opens the card, or the card stays Running. The queue helper's comment now says that a Codex continuation is a real prompt and also starts past a held queue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Fresh-context review: no blockers. These are the answers to the three minor points.
|
…end-between-turns
…end-between-turns
This was referenced Oct 11, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A Claude subagent can finish while T3 still shows it as Working for hours. On stage, the reviewer subagent "Review swap undo diff" on "CI/CD Improvement" finished at 2026-10-10 09:08:11 UTC. One day later, T3 still showed it as running.
The cause has two parts:
task_notificationonly in its wake buffer. The card completes only when a continuation run drains that buffer. The end of a nested subagent never offers a continuation.Evidence: the Claude stream log has
task_notificationa4439e85fa530c9abcompletedat 09:08:11.564. The stage database has that subagent asrunning, and run 173 asqueued+queueHeldsince 09:07:58. The journal has no wake-turn log at 09:08:11. The latest upstreammain(8d199b4f7, 2026-10-11) still has the same code.Fix
task_notificationnow completes its card through the last settled turn, as subagent progress already does. The frame stays in the wake buffer, so the wake label and the continuation offer do not change. The drain does not apply the card update a second time. The undrained end keeps the session pinned, as the running subagent did before.createdBy: "agent",creationSource: "provider") no longer copies the hold. The queue starts the first queued run that is not held. Held user runs keep waiting for the user, in their order. Stop still holds every queued run, including a continuation that is already queued.All edits in upstream files have
T3-CUSTOM(expbkt3)markers. The queue helper is in the fork-ownedQueueHeldContinuation.expbkt3.ts.Tests
ClaudeAdapterV2.subagentEndBetweenTurns.expbkt3.test.ts: a nested subagent ends between turns. A root background subagent ends between turns and the continuation is still offered. A drain replay does not change the card.QueueHeldContinuation.expbkt3.test.ts: a continuation starts past a held queue. A user message still copies the hold. A queue with only held runs starts nothing.canStartQueuedRungives the same result for SQLite and in memory.I ran no tests locally (shared-host rule). CI verifies.
Risks
Model and harness: Claude Opus 5.5 in Claude Code (T3 Code session).
🤖 Generated with Claude Code