Description
When running the agent via piped stdin (e.g. `printf '...\n/plan confirm\n' | cargo run ...`), executing a plan with `/plan confirm` immediately aborts: the sub-agent is spawned and canceled within the same millisecond. The `scheduler_loop` detects stdin EOF before the sub-agent has a chance to run, so every plan execution in piped CLI mode silently fails.
This makes `/plan confirm` completely unusable in non-interactive (piped/scripted) CLI mode.
Reproduction Steps
- Run the agent with piped stdin that includes /plan followed by /plan confirm:
```bash
printf "/plan Read Cargo.toml and count workspace members.\n/plan confirm\n" | \
cargo run --features full -- --config .local/config/testing.toml
```
- Observe output: plan is shown, "Confirmed. Executing plan (2 tasks)..." appears, then immediately "Plan canceled. 0/2 tasks completed before cancellation."
Expected Behavior
`/plan confirm` executes the plan and completes all tasks before the agent exits. Sub-agents should run to completion (or until user explicitly cancels) before the scheduler_loop processes stdin EOF.
Actual Behavior
Sub-agent is spawned and immediately cancelled (280 microseconds) because `scheduler_loop` detects channel close (stdin EOF) before sub-agent can run even one turn. Output:
```
Zeph: Confirmed. Executing plan (2 tasks)...
Zeph: Plan canceled. 0/2 tasks completed before cancellation.
```
From logs (`ci-536-plan-confirm.log`):
```
22:23:04.026073Z INFO sub-agent spawned task_id=4a3deca1 def_name=rust-developer
22:23:04.026356Z WARN scheduler channel closed, canceling running sub-agents sub_agents=1 status=Canceled
22:23:04.026386Z INFO sub-agent cancelled task_id=4a3deca1
```
Root Cause
In CLI mode, `scheduler_loop` watches for stdin EOF as the exit signal. When the agent finishes processing `/plan confirm` (which starts the first sub-agent asynchronously), stdin has already been exhausted. The `scheduler_loop` sees channel closed and immediately cancels all running sub-agents before they execute.
Fix direction: `scheduler_loop` should not cancel running sub-agents on stdin EOF until all active plan executions are complete, OR the orchestrator should hold a cancellation guard while tasks are executing.
Environment
- Version: 0.19.1 (commit 7af0182)
- Features: full
- Config: .local/config/testing.toml
- Mode: piped CLI (`printf ... | cargo run`)
Logs / Evidence
Session log: `.local/testing/debug/ci-536-plan-confirm.log` (CI-536, 2026-04-17)
Description
When running the agent via piped stdin (e.g. `printf '...\n/plan confirm\n' | cargo run ...`), executing a plan with `/plan confirm` immediately aborts: the sub-agent is spawned and canceled within the same millisecond. The `scheduler_loop` detects stdin EOF before the sub-agent has a chance to run, so every plan execution in piped CLI mode silently fails.
This makes `/plan confirm` completely unusable in non-interactive (piped/scripted) CLI mode.
Reproduction Steps
```bash
printf "/plan Read Cargo.toml and count workspace members.\n/plan confirm\n" | \
cargo run --features full -- --config .local/config/testing.toml
```
Expected Behavior
`/plan confirm` executes the plan and completes all tasks before the agent exits. Sub-agents should run to completion (or until user explicitly cancels) before the scheduler_loop processes stdin EOF.
Actual Behavior
Sub-agent is spawned and immediately cancelled (280 microseconds) because `scheduler_loop` detects channel close (stdin EOF) before sub-agent can run even one turn. Output:
```
Zeph: Confirmed. Executing plan (2 tasks)...
Zeph: Plan canceled. 0/2 tasks completed before cancellation.
```
From logs (`ci-536-plan-confirm.log`):
```
22:23:04.026073Z INFO sub-agent spawned task_id=4a3deca1 def_name=rust-developer
22:23:04.026356Z WARN scheduler channel closed, canceling running sub-agents sub_agents=1 status=Canceled
22:23:04.026386Z INFO sub-agent cancelled task_id=4a3deca1
```
Root Cause
In CLI mode, `scheduler_loop` watches for stdin EOF as the exit signal. When the agent finishes processing `/plan confirm` (which starts the first sub-agent asynchronously), stdin has already been exhausted. The `scheduler_loop` sees channel closed and immediately cancels all running sub-agents before they execute.
Fix direction: `scheduler_loop` should not cancel running sub-agents on stdin EOF until all active plan executions are complete, OR the orchestrator should hold a cancellation guard while tasks are executing.
Environment
Logs / Evidence
Session log: `.local/testing/debug/ci-536-plan-confirm.log` (CI-536, 2026-04-17)