- mission schema: optional capabilities.tools (same validation as task)
- merge semantics in runTask: neither -> none; mission only -> mission;
task only -> task; both -> intersection (task narrows, never widens);
empty intersection -> tool-free run with an explicit stderr note
- result.json records EFFECTIVE tools; task/mission snapshots remain the
immutable declaration of intent
- adapters unchanged; host-side only (no image change, 0.0.6 still active)
- task suite +5 cases (41 total): all four merge cases asserted from run
evidence + invalid mission capabilities rejected
Policy decision recorded: missions govern; tasks cannot escalate.
Closes#30
- retryRun rewrites a snapshot's relative mission path to the run's own
recorded mission.json (absolute) before execution — retries stay
faithful to what originally ran
- runTask accepts options.retriedFrom; retry records lineage in
result.json (additive optional field, no schema break)
- task suite +4 cases: retry succeeds, lineage recorded, mission section
present after retry (36 total), missing-run retry exits 4
Closes#28
- live hello failure dumps latest run result.json + stderr tail before
sandbox cleanup destroys them
- wrong-expectExact case asserts reason == expect-mismatch (was: any
exit 1, which masked compose-level failures)
- repair dangling if/else from the docker-guard refactor
Closes#15