Skip to content

Drive Claude subagent mirror lifecycle from the Subagent item, not the parent turn - #443

Merged
Tryanks merged 1 commit into
mainfrom
fix/native-subagent-mirror-lifecycle
Sep 16, 2026
Merged

Tryanks merged 1 commit into
mainfrom
fix/native-subagent-mirror-lifecycle

Conversation

@Tryanks

@Tryanks Tryanks commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Problem

Claude Code background Agent tasks outlive the parent turn. tcode closed every native-subagent mirror on the parent's TurnCompleted, and also treated the async_launched tool_result as the subagent's completion. Result: the mirror never showed running, and every later child transcript item became its own zero-length synthetic turn (a wall of 1:42 PM · 0s footers).

Fix

Mirror lifecycle is owned by the Subagent item's own status end to end.

  • runtime/events.rs, subagents.rs: turn opens while the Subagent item is InProgress, closes on its terminal status. Parent TurnCompleted no longer touches mirrors. SessionClosed marks still-running mirrors Interrupted. Per-item open+close hack removed; stragglers fold into the last turn.
  • agent/claude.rs: async_launched tool_result keeps the item InProgress until task_notification (parent row now spins until the agent really finishes and shows the real summary). Terminal Subagent snapshots are held until the transcript tail acks Stop after its final read, so child items always precede the terminal update. PreferPath only seeds a reader when discovery found nothing (no replay from byte 0). Child items from the stdout parent_tool_use_id feed and the tail feed are deduped.
  • New fixture subagent_background_trace.jsonl.

Tests

  • runtime: native_mirror_turn_lifecycle_outlives_parent_turn, ..._session_closed_interrupts, ..._late_item (fail on main, pass here)
  • agent: background_subagent_terminal_waits_for_tail_flush_and_dedupes_feeds, subagent_tail_prefer_path_does_not_replay_a_discovered_transcript
  • cargo clippy --workspace --all-targets -D warnings clean; cargo test -p agent -p tcode-runtime green.

Not verified: a live GUI run against a real background Agent.

Co-Authored-By: Claude noreply@anthropic.com

…e parent turn

Background Agent tasks outlive the parent turn, so closing every mirror on
the parent's TurnCompleted (and treating the async_launched tool_result as
completion) left mirrors showing not-running and turned every later child
item into a zero-length synthetic turn.

- Runtime: mirror turn opens while the Subagent item is InProgress, closes
  on its terminal status; SessionClosed interrupts still-running mirrors.
- Agent: async_launched keeps the item InProgress until task_notification;
  terminal snapshots wait for the transcript tail's final flush; PreferPath
  no longer replays a discovered transcript; stdout/tail child items are
  deduped.

Co-Authored-By: Claude <noreply@anthropic.com>
@Tryanks
Tryanks merged commit 1af978f into main Sep 16, 2026
6 checks passed
@Tryanks
Tryanks deleted the fix/native-subagent-mirror-lifecycle branch September 16, 2026 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant