claw-code/src
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
..
assistant chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
bootstrap chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
bridge chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
buddy chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
cli chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
components chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
constants chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
coordinator chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
entrypoints chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
hooks chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
keybindings chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
memdir chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
migrations chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
moreright chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
native_ts chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
outputStyles chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
plugins chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
reference_data Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
remote chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
schemas chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
screens chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
server chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
services chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
skills chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
state chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
types chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
upstreamproxy chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
utils chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
vim chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
voice chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
QueryEngine.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
Tool.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
__init__.py feat(#160): wire claw list-sessions and delete-session CLI commands 2026-04-22 17:16:53 +09:00
_archive_helper.py chore: additional AI slop cleanup and enforcer wiring from sessions 1/5 2026-04-03 18:35:27 +09:00
bootstrap_graph.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
command_graph.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
commands.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
context.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
costHook.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
cost_tracker.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
deferred_init.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
dialogLaunchers.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
direct_modes.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
execution_registry.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
history.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
ink.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
interactiveHelpers.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
main.py feat: #164 Stage B CLOSURE — turn-loop JSON + cancel_observed coverage + CLAWABLE promotion 2026-04-22 19:49:20 +09:00
models.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
parity_audit.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
permissions.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
port_manifest.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
prefetch.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
projectOnboardingState.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
query.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
query_engine.py feat: #164 Stage B prep — add cancel_observed field to TurnResult 2026-04-22 19:44:47 +09:00
remote_runtime.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
replLauncher.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
runtime.py feat: #164 Stage B prep — add cancel_observed field to TurnResult 2026-04-22 19:44:47 +09:00
session_store.py fix(#160): harden delete_session contract — idempotency, race-safety, typed partial-failure 2026-04-22 17:11:26 +09:00
setup.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
system_init.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
task.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
tasks.py Make the repository's primary source tree genuinely Python 2026-03-31 07:17:34 -07:00
tool_pool.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
tools.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00
transcript.py Rewriting Project Claw Code - Python port with Rust on the way 2026-03-31 08:16:20 -07:00