Skip to content

fix: サブエージェント稼働中に result が届いても Completed に倒さない - #46

Merged
takecchi merged 1 commit into
mainfrom
codiva/completed-pr-2
Jul 21, 2026
Merged

takecchi merged 1 commit into
mainfrom
codiva/completed-pr-2

Conversation

@takecchi

Copy link
Copy Markdown
Owner

背景 / 不具合

作業がまだ完了していない(サブエージェントに委譲して継続中の)セッションが、Completed と判定されてしまう不具合の修正。

Task ツールのサブエージェントがバックグラウンド実行されると、その tool_result("running in the background")が即座に返り本体ターンが続行するため、サブエージェント稼働中にトップレベルの result/success が先に届く。従来の sdk-parse.ts はこの result/success を無条件に completed へマッピングしていたため、実際には作業継続中なのにバッジが「Completed」に倒れていた。

原因の裏取り(実データ)

CLAUDE.md の「SDK メッセージの形を想定で書かない」に従い、scripts/spike.tssubagent シナリオを追加して実際の SDK ストリームを採取した。判明した事実:

  • サブエージェントは独自の result を出さない(result/success は最後にトップレベル1件だけ)。
  • サブエージェントのメッセージは parent_tool_use_id(= Task の tool_use id)付きで届く(トップレベルは null)。
  • ライフサイクルは system/task_startedtask_progresstask_notificationstatus: completed|failed|stopped)。
  • バックグラウンド実行時のみ result/successtask_notification より先に届きうる。

修正内容

sdk-parse.ts で稼働中のサブエージェント/Task を追跡し、完了判定をゲートする:

  • system/task_started / system/task_notification で稼働中タスク集合 activeTaskIds を追跡。
  • result/success 受信時にタスクが残っていれば completed にせず、結果を deferredResult に保留して running を維持。
  • 最後のタスクが task_notification で settle し集合が空になった時点で、保留結果を使って completed を確定(completeWith)。
  • skip_transcript の雑務タスクはゲート対象外。failed/aborted 後の遅延 task_notification はセッションを completed に復活させない(status === 'running' ガード)。

activeTaskIds / deferredResult はいずれも transient で永続しない。

テスト計画

  • npm test(738 passed / core・utils カバレッジ 80% 以上、sdk-parse.ts 97.2%)
  • npm run typecheck
  • npm run lint(Biome)
  • 実採取 fixture __fixtures__/session-subagent.jsonl(フォアグラウンド settle → 正常 completed)の回帰テスト
  • 合成テスト: バックグラウンド順序(result 先行 → running 維持 → notification で completed)/複数タスクの全 settle 待ち/skip_transcript 無視/failed を遅延 notification で復活させない/同一 id の重複 task_started を dedup
  • 実機でバックグラウンドサブエージェントを使うセッションを起動し、稼働中は Running、完了後に Completed になることを目視確認

補足

  • SDK メッセージ形状は scripts/spike.ts subagent シナリオで再採取可能。
  • 状態機械・SDK ノートのドキュメント(docs/ARCHITECTURE.md / docs/TECH_NOTES.md)も更新済み。

🤖 Generated with Claude Code

Task ツールがバックグラウンド実行されると tool_result が即返り本体ターンが
続行するため、サブエージェント稼働中にトップレベルの result/success が先に
届く。これをそのまま completed 判定していたため、実際には作業継続中なのに
バッジが「Completed」へ倒れる不具合があった。

- system/task_started / task_notification で稼働中タスク集合(activeTaskIds)を追跡
- result/success 受信時にタスクが残っていれば deferredResult に保留し running を維持
- 最後のタスクが settle した時点で保留結果を使って completed を確定(completeWith)
- skip_transcript の雑務タスクはゲート対象外。late notification は failed を復活させない
- 実データ採取のため spike に subagent シナリオを追加し、fixture でテスト

SDK メッセージ形状は scripts/spike.ts の subagent シナリオで実採取し、
__fixtures__/session-subagent.jsonl として回帰テストに固定した。
@takecchi
takecchi merged commit ef4be9d into main Jul 21, 2026
1 check passed
@takecchi
takecchi deleted the codiva/completed-pr-2 branch July 21, 2026 04:48
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