Note
Grok responding on behalf of Julius.
Thanks for the detailed write-up. I traced this on current main (10f39eb) and the code paths behave the way you describe:
task_cancel(apps/server/src/mcp/OrchestratorMcpService.ts:2035-2068): if the task status is already terminal, it returns that status. Otherwise it needsworkState === "waiting_for_children"or alatestActiveRun(child), callsstopWithinLimit, drops the completion delivery, and returnscancel_requested. Nothing is written to the task that would make it read as cancelled later.settleInterruptedRun(apps/server/src/orchestration-v2/Orchestrator.ts:8190-8225) does nothing unlessrun.status === "running"and the attempt is still running. Thethread.background-work.settlepath (Orchestrator.ts:~8578-8592) also calls it only whenstoppedRun.status === "running". Once the provider turn has ended and the run iscompleted, stopping its background work can't turn the run intointerrupted/cancelled.- Summary:
subagentResultForRun(apps/server/src/orchestration-v2/SubagentProjection.ts:158-200) takes the newest non-empty assistant message or turn item for the run. For a completed run whose last message was an interim "waiting on background work" note, that note becomes the result (OrchestratorMcpService.ts:430, 1267, 1303). - Background tracking:
CLAUDE_OPAQUE_BACKGROUND_TASK_KINDS(apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts:1786-1810) only mapslocal_bashonto the Waiting roster ascommand/monitor. It sets what the pending-background roster shows, not the run's status.
Confirmed from code: cancel records no cancelled marker, the interrupted settlement only applies to running runs, and the summary is the run's last assistant text. Inferred, not reproduced here: that the task sits in a cancel-pending state and then reads as completed/result_available about a minute later with no parent wake. That fits the paths above (the completion delivery is dropped on cancel), but I haven't run it myself.
A likely fix direction: record a cancel intent on the task/run when task_cancel stops background work on a turn-ended run, and settle it as cancelled/interrupted (with a parent wake) instead of reusing the completed run's interim message.
Related, not duplicates: #15888, #15082, #16110, #13490. In the same area, merged #16002 and open #15201 don't address this case.