feat(durable): add zeph durable cancel command and Canceled status#6439
Merged
Conversation
Killing the process running a durable execution only delays its resume: the next crash-orphan sweep resumes it, since crash-resume is explicitly designed to survive process death. This adds a durable, intentional Canceled terminal status distinct from the crash-driven Aborted state, and a `zeph durable cancel <id>` command to set it. cancel_execution probes the execution's advisory lock before writing: no live owner cancels immediately via the same race-safe conditional UPDATE finalize already uses; a live owner (or a concurrent maintenance sweep) is refused rather than blind-flipped; a cross-process backend with no lock to probe (Postgres) is refused for the same reason. Canceled executions are never reopened or resumed (refines INV-16 in spec-064, since operator intent now outranks the reopen heuristic it stands in for). Cooperative cancellation of a genuinely live owner is deferred to a follow-up issue: there is no live-owner step loop to observe it yet, since the per-kind resume adapters are unwired in this build.
bug-ops
force-pushed
the
feat/issue-6362/durable-run-cancel
branch
from
July 18, 2026 02:17
afb313e to
b76032b
Compare
bug-ops
enabled auto-merge (squash)
July 18, 2026 02:17
Merged
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Killing the process running a durable execution only delays its resume: the next crash-orphan sweep resumes it, since crash-resume is explicitly designed to survive process death. This adds a durable, intentional
Canceledterminal status distinct from the crash-drivenAbortedstate, and azeph durable cancel <id>command to set it.ExecutionStatus::Canceledvariant, additive (SQLite CHECK constraint extended via migration 112 on both dialects).LocalBackend::cancel_executionprobes the execution's advisory lock (INV-15) before writing: no live owner → immediate cancel via the same race-safeUPDATE ... WHERE status = 'running'patternfinalizealready uses; a live owner (or a concurrent maintenance sweep) → refused (CancelOutcome::LiveOwner), row untouched; a cross-process backend with no lock to probe (Postgres) → refused (CancelOutcome::LivenessUnverifiable) rather than blind-flipping a possibly-live row.open_execution/open_execution_exclusivefail closed withDurableError::ExecutionCanceled(refines INV-16 → INV-16′ inspecs/064-durable-execution/spec.md— operator intent now outranks the active-reopen heuristic it stands in for).zeph durable resumereports "intentionally canceled" distinctly from the generic adapters-not-wired message.zeph durable list --status canceledandprune/prune --dry-run(TTL retention) both recognize the new status.durable_executions' CHECK constraint under-- no-transaction+ explicitBEGIN/COMMIT, required soPRAGMA foreign_keys = OFFactually takes effect for the parent-table rebuild (the PRAGMA is a no-op inside sqlx's default per-migration transaction, which would otherwise FK-violate in production against realdurable_journal/durable_promises/durable_timerschild rows — caught in review, verified by a dedicated FK-survival integration test). The matching Postgres migration is a plain constraint swap.Cooperative cancellation of a genuinely live owner (a durable signal the owning process observes and stops on cooperatively) is explicitly out of scope here: there is no live-owner step loop to observe it yet, since the per-kind resume adapters (agent-turn/subagent) are unwired in this build. Tracked as a follow-up issue.
Closes #6362
Test plan
cargo +nightly fmt --checkcargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warningscargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins— 14304 passed, 0 failedRUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"cargo test --doc --workspace --features "desktop,ide,server,chat,pdf,scheduler"gitleaks protect --staged --no-banner --redact— no leakscrates/zeph-db/tests/durable_canceled_migration.rs) — seeds all three FK-linked child tables, runs the real migration through a file-backedforeign_keys(true)pool, asserts row/FK survivaltokio::spawn+tokio::join!, 20 trials) for cancel-vs-finalize and cancel-vs-sweep_orphanscargo clippy -p zeph-durable -p zeph-db --no-default-features --features postgres— dual-backend model respectedkill-and-cancel walkthrough — not yet performed (playbook scenarios written, flaggedPartialin coverage-status.md, recommended as a follow-up live-tester pass)