Skip to content

fix(server): a Claude fork no longer reads as finished the moment it starts - #26405

Closed
Batuhan1999 wants to merge 1 commit into
pingdotgg:mainfrom
Batuhan1999:fix/claude-fork-ack-settles-subagent
Closed

Batuhan1999 wants to merge 1 commit into
pingdotgg:mainfrom
Batuhan1999:fix/claude-fork-ack-settles-subagent

Conversation

@Batuhan1999

Copy link
Copy Markdown
Contributor

Problem

A Claude fork (Agent with subagent_type: "fork") is marked finished a few milliseconds after it starts. A running fork shows as completed, with the result "Fork started — that fork is you." A foreground fork that the user's steer interrupts later shows as Failed 0s, even though it worked for minutes.

The cause: a fork inherits the parent's history, so its transcript opens with its own copy of the parent's Agent call. That copy is a tool_result for the parent's tool_use_id, reading "Fork started — that fork is you.", and arrives with parent_tool_use_id set to that same id. ClaudeAdapterV2 took it for the launch result and settled the subagent as completed, with completedAt set at launch.

Seen in a real session (times from the Claude session log and the T3 projection):

  • 10:04:08.215: parent calls Agent (fork, foreground).
  • 10:04:08.234: fork transcript opens with tool_result "Fork started — that fork is you."
  • 10:04:08.253: T3 marks the subagent completed, completedAt 10:04:08.253.
  • 10:05:54.183: user steers. The real result [Request interrupted by user for tool use] arrives, and the status becomes failed while completedAt stays at launch. The UI shows "Failed 0s".
  • The fork's child thread has 20 items of work between those two points.

Change

When a tool_result for a subagent's launch call arrives in a frame whose parent_tool_use_id is that same call, it comes from inside the subagent's own transcript, so the adapter skips it. Only the parent's own result for the call settles the subagent. Background launch acks and task notifications are handled as before.

Scope and approval

This is a very small, focused fix for an obvious bug: a 5-line guard in one adapter branch, plus one test. The subagent's own copy of its launch call is never the parent's result for it, and settling on it leaves the subagent's status and elapsed time wrong.

Verification

  • New test does not settle a fork on the launch result its own transcript opens with in ClaudeAdapterV2.test.ts replays the frames from the session above: task_started, then the fork's "Fork started" frame, then the parent's interrupted result.
    • Before the fix it fails with expected [ 'running', 'completed' ] to deeply equal [ 'running', 'failed' ].
    • After the fix the fork stays running until the parent's result settles it.
  • ClaudeAdapterV2.test.ts: 245/245 pass.
  • ClaudeReplayFixtures.integration.test.ts: 38/38 pass.
  • apps/server typecheck, lint and format are clean.
  • I did not record a new live fork replay fixture. The test uses the frame shapes from the real session log.

Separately, a steer-interrupted subagent is still reported as failed, not interrupted. This PR leaves that as is.

Model and harness: Claude Opus 5.5 in Claude Code (T3 Code).

🤖 Generated with Claude Code

…starts

A fork's transcript opens with its own view of the parent's Agent call, a
tool result reading "Fork started — that fork is you." The adapter took it
for the launch result and settled the fork as completed within
milliseconds, so a running fork showed as done, and a fork later
interrupted by a steer showed as failed after 0s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 28, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 47843c4

Macroscope's review found this PR approvable — The change prevents a Claude fork's launch acknowledgment from prematurely marking it finished. Parent results and task notifications continue to control completion, keeping the change narrowly scoped.

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

@coderabbitai

coderabbitai Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 2a73827 and 47843c4.

Files selected for processing: 2
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The Claude adapter now ignores a subagent result when its tool-use ID matches the enclosing message’s parent tool-use ID. A regression test checks that the fork launch acknowledgement does not settle the subagent, while a later interrupted tool result marks it failed.

Changes: Claude fork result handling

Layer / File(s) Summary
Ignore fork launch acknowledgement
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
The adapter skips a result whose tool-use ID matches the enclosing message’s parent tool-use ID. The test verifies that the launch acknowledgement is not recorded as the result and that a later interrupted tool result settles the subagent as failed.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested labels: bugfix, size:S

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to 47843

No actionable merge-blocking risk remains from the reviewed change.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title follows conventional commit format and names the change: a Claude fork no longer reads as finished when it starts. The raw summary and PR objectives both describe a guard in ClaudeAdapterV2 …
Description check Passed The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section explains the bug, the cause, and reproduction timing from a real sessio…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title follows conventional commit format and names the change: a Claude fork no longer reads as finished when it starts. The raw summary and PR objectives both describe a guard in ClaudeAdapterV2 that skips a launch-call tool_result from the fork's own transcript, so the title matches the main change. It is specific enough for a teammate scanning history to understand the primary fix.

Full details: Description check

Explanation

The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section explains the bug, the cause, and reproduction timing from a real session. The Change section explains the guard and why only the parent's result should settle the subagent. The Scope section argues the fix is small and obvious. The Verification section lists a new focused test with before and after results and the suites run. It also notes what was not checked, which the template asks for. The description does not include a model and harness line in the required form, but it does include one at the end.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Copy link
Copy Markdown
Member

Closing in favour of #26459, which makes the same change. Thanks for the work here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants