Two findings addressed in one commit:
**Greptile P1: `loopRound` doc typo** — The JSDoc on `CommandStartInput.loopRound` said the value is surfaced as `AO_LOOP_ROUND` but `buildChildEnv` actually sets `AO_PIPELINE_LOOP_ROUND`. A shell script reading `$AO_LOOP_ROUND` to detect retry-vs-first-run would always get undefined and silently break. Doc-only fix; runtime behaviour was already correct.
**Self-review P1: SIGKILL escalation regression test was unfalsifiable** — The test added in round 4 asserted `outcome.errorMessage` contains "cancelled" and waited 3.5s for SIGKILL. But under the bug, `settle()` is still called synchronously inside `cancel()`, so `done` resolves with the same "cancelled" outcome whether or not SIGKILL ever fires. The trapped-SIGTERM shell process would survive as an orphan and the test would still pass green.
Fix:
- Added `pid?: number` to `RunningCommandStage` (optional — undefined for synthetic-fail handles that never spawned a child).
- The regression test now grabs `handle.pid` and after the SIGKILL grace window calls `process.kill(pid, 0)` (existence probe). Asserts the probe throws `ESRCH` (no such process). Under the round-4 bug this would have returned without throwing, failing the test.
- Also added a sanity check that the child is alive before cancel.
All 1373 core tests pass. Lint clean.