Repository navigation
fix(ws-13): verify cancellation from turn state - #3684
Conversation
There was a problem hiding this comment.
Code Review
This pull request integrates TurnStateStore into the LoopExitApplier logic to dynamically verify if a cancellation has been requested for a specific run. It replaces the previous static return in is_cancellation_observed with a lookup to the state store and updates associated tests and instantiation sites. Feedback suggests expanding the cancellation check to include the Cancelled state as well as CancelRequested to ensure idempotency and better handle retries after a worker crash.
| run_id, | ||
| }) | ||
| .await?; | ||
| Ok(state.status == TurnStatus::CancelRequested) |
There was a problem hiding this comment.
To support idempotent retries and robust recovery, the check should also accept runs that are already in the Cancelled state. If a worker crashes after successfully applying a cancellation but before completing its task, a subsequent retry should still consider the cancellation as 'observed' rather than failing with a protocol violation.
| Ok(state.status == TurnStatus::CancelRequested) | |
| Ok(state.status == TurnStatus::CancelRequested || state.status == TurnStatus::Cancelled) |
References
- When managing job or task states, distinguish between active and terminal states (like Cancelled) to ensure robust recovery and idempotency during retries.
684d837 to
e17c627
Compare
There was a problem hiding this comment.
Pull request overview
This PR tightens WS-13 cancellation correctness by requiring durable turn-run state (CancelRequested) before accepting LoopExit::Cancelled evidence, and introduces a host-facing cancellation observation port that the canonical executor consults at cooperative boundaries.
Changes:
- Update
ThreadCheckpointLoopExitEvidencePortto read durable run state and only accept cancellation when the run isCancelRequested. - Add a
LoopCancellationPort+LoopCancellationSignalto the host contract and wire it through loop-support + Reborn host adapter plumbing. - Add/enable regression tests verifying cancellation short-circuits execution and that cancellation exits are backed by durable state.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ironclaw_turns/tests/agent_loop_host_contract.rs | Updates host contract test host to implement the new cancellation port. |
| crates/ironclaw_turns/src/run_profile/mod.rs | Re-exports the new cancellation port/signal types from the run-profile API. |
| crates/ironclaw_turns/src/run_profile/host.rs | Introduces LoopCancellationPort and LoopCancellationSignal, and adds the port to AgentLoopDriverHost. |
| crates/ironclaw_reborn/tests/planned_driver_e2e.rs | Adds an end-to-end test asserting planned driver short-circuits on host cancellation. |
| crates/ironclaw_reborn/tests/loop_driver_host.rs | Updates evidence port construction to pass the new TurnStateStore dependency. |
| crates/ironclaw_reborn/src/turn_runner/tests/mod.rs | Updates the stub host to implement the cancellation port. |
| crates/ironclaw_reborn/src/loop_exit_applier/tests/mod.rs | Adds a regression test for accepting cancellation evidence only with durable CancelRequested state; adds a static TurnStateStore test double. |
| crates/ironclaw_reborn/src/loop_exit_applier.rs | Makes cancellation evidence verification consult durable run state via TurnStateStore. |
| crates/ironclaw_reborn/src/loop_driver_host.rs | Wires per-run cancellation observation into the Reborn host via a RunCancellationFactory and RunStateLoopCancellationPort. |
| crates/ironclaw_loop_support/src/lib.rs | Exposes the new cancellation port/factory utilities from loop-support. |
| crates/ironclaw_loop_support/src/cancellation_port.rs | Adds run-scoped cancellation handle/port and a factory abstraction (with tests). |
| crates/ironclaw_loop_support/Cargo.toml | Adds chrono + parking_lot dependencies needed for cancellation signal storage/locking. |
| crates/ironclaw_agent_loop/tests/deferred_followups.rs | Enables/implements the prior placeholder integration test for executor-level cancellation short-circuiting. |
| crates/ironclaw_agent_loop/src/test_support/mod.rs | Extends the mock host builder to supply a cancellation signal and implements LoopCancellationPort. |
| crates/ironclaw_agent_loop/src/executor.rs | Adds cooperative cancellation checks at boundary points and produces cancellation exits with a final checkpoint when possible. |
| crates/ironclaw_agent_loop/Cargo.toml | Adds dev-dependencies used by new/updated tests (chrono, futures). |
| Cargo.lock | Records new dependency resolutions from the added crates/features. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
henrypark133
left a comment
There was a problem hiding this comment.
Review — fix(ws-13): verify cancellation from turn state
No blockers. Approve.
Evidence gate — is_cancellation_observed correctly reads get_run_state and returns true only on CancelRequested. Logic is sound.
TOCTOU — read-then-accept window is inherent in cooperative check design. State machine prevents double-transition. Acceptable.
CancelCheck enum — private module-local sentinel, not a duplicate of any exported type.
Test coverage — regression test covers the gate path. Executor-level and e2e integration tests cover cooperative boundary detection.
Caveman review findings1🔴 2🟡 1❓
|
c3ec966 to
d13f6d2
Compare
d13f6d2 to
2af72f4
Compare
Code Review —
|
Context
Split out from the follow-up fixes for #3648 so the original WS13 cancellation accessor PR can stay focused.
What changed
ThreadCheckpointLoopExitEvidencePortnow reads durable turn state for the claimed run.LoopExit::Cancelledevidence is accepted only when the run is durablyCancelRequested.CancelRequestedstate.Validation
cargo test -p ironclaw_reborn loop_exit_applierStack
Base: #3648 /
arch/ws-13Next:
codex/ws13-live-cancel-wiring