claw-code/tests
YeonGyu-Kim 178c8fac28 fix: #159 — run_turn_loop no longer hardcodes empty denied_tools; permission denials now parity-match bootstrap_session
#159: multi-turn sessions had a silent security asymmetry: denied_tools
were always empty in run_turn_loop, even though bootstrap_session inferred
them from the routed matches. Result: any tool gated as 'destructive'
(bash-family commands, rm, etc) would silently appear unblocked across all
turns in multi-turn mode, giving a false 'clean' permission picture to any
claw consuming TurnResult.permission_denials.

Fix: compute denied_tools once at loop start via _infer_permission_denials,
then pass the same denials to every submit_message call (both timeout and
legacy unbounded paths). This mirrors the existing bootstrap_session pattern.

Acceptance: run_turn_loop('run bash ls').permission_denials now matches
what bootstrap_session returns — both infer the same denials from the
routed matches. Multi-turn security posture is symmetric.

Tests (tests/test_run_turn_loop_permissions.py, 2 tests):
- test_turn_loop_surfaces_permission_denials_like_bootstrap: Symmetry
  check confirming both paths infer identical denials for destructive tools
- test_turn_loop_with_continuation_preserves_denials: Denials inferred at
  loop start are passed consistently to all turns; captured via mock and
  verified non-empty

Full suite: 82/82 passing, zero regression.

Closes ROADMAP #159.
2026-04-22 17:50:21 +09:00
..
test_load_session_cli.py fix: #165 — load-session CLI now parity-matches list/delete (--directory, --output-format, typed JSON errors) 2026-04-22 17:44:48 +09:00
test_porting_workspace.py feat(#160): wire claw list-sessions and delete-session CLI commands 2026-04-22 17:16:53 +09:00
test_run_turn_loop_continuation.py fix: #163 — remove [turn N] suffix pollution from run_turn_loop; file #164 timeout-cancellation followup 2026-04-22 17:37:22 +09:00
test_run_turn_loop_permissions.py fix: #159 — run_turn_loop no longer hardcodes empty denied_tools; permission denials now parity-match bootstrap_session 2026-04-22 17:50:21 +09:00
test_run_turn_loop_timeout.py fix: #163 — remove [turn N] suffix pollution from run_turn_loop; file #164 timeout-cancellation followup 2026-04-22 17:37:22 +09:00
test_session_store.py fix(#160): harden delete_session contract — idempotency, race-safety, typed partial-failure 2026-04-22 17:11:26 +09:00
test_submit_message_budget.py fix: #162 — budget-overflow no longer corrupts session state in submit_message 2026-04-22 17:29:55 +09:00