YeonGyu-Kim
|
11f9e8a5a2
|
feat: #164 Stage B CLOSURE — turn-loop JSON + cancel_observed coverage + CLAWABLE promotion
Closes all three gaebal-gajae-identified closure criteria for #164 Stage B:
1. turn-loop runtime surface exposes cancel_observed consistently
2. cancellation path tests validate safe-to-reuse semantics
3. turn-loop promoted from OPT_OUT to CLAWABLE surface
Changes:
src/main.py:
- turn-loop accepts --output-format {text,json}
- JSON envelope includes per-turn cancel_observed + final_cancel_observed
- All turn fields exposed: prompt, output, stop_reason, cancel_observed,
matched_commands, matched_tools
- Exit code 2 on final timeout preserved
tests/test_cli_parity_audit.py:
- CLAWABLE_SURFACES now contains 14 commands (was 13)
- Removed 'turn-loop' from OPT_OUT_SURFACES
- Parametrized --output-format test auto-validates turn-loop JSON
tests/test_cancel_observed_field.py (new, 9 tests):
- TestCancelObservedField (5 tests): field contract
- default False
- explicit True preserved
- normal completion → False
- bootstrap JSON exposes field
- turn-loop JSON exposes per-turn field
- TestCancelObservedSafeReuseSemantics (2 tests): reuse contract
- timeout result has cancel_observed=True when signaled
- engine.mutable_messages not corrupted after cancelled turn
- engine accepts fresh message after cancellation
- TestCancelObservedSchemaCompliance (2 tests): SCHEMAS.md contract
- cancel_observed is always bool
- final_cancel_observed convenience field present
Closure criteria validated:
- ✅ Field exposed in bootstrap JSON
- ✅ Field exposed per-turn in turn-loop JSON
- ✅ Field is always bool, never null
- ✅ Safe-to-reuse: engine can accept fresh messages after cancellation
- ✅ mutable_messages not corrupted by cancelled turn
- ✅ turn-loop promoted from OPT_OUT (14 clawable commands now)
Protocol now distinguishes at runtime:
timeout + cancel_observed=false → infra/wedge (escalate)
timeout + cancel_observed=true → cooperative cancellation (safe to retry)
Test results: 182 → 192 passing, +10 tests, zero regression, 3 skipped unchanged.
Closes #164 Stage B. Stage C (async-native preemption) remains future work.
|
2026-04-22 19:49:20 +09:00 |
|