Durable workflows should make interruption a state transition
Durable workflows should make interruption a state transition. I do not want a pause, cancellation, or model-driven change of plan to exist only as control flow inside a running process. In production, that process can disappear at the exact moment control changes. I want the workflow to record interruption as durable state—an event with a known position in history, a current step status, and an explicit path to whatever may happen next.
Event sourcing gives that state a durable narrative. The workflow history records what was scheduled, what completed, and which control signal arrived. After a crash, another worker can reconstruct the same boundary instead of inferring it from logs or half-finished side effects. This is the practical core of durable agent execution—recovery depends on persisted decisions, not the memory of the worker that made them.
Signals are how I separate control from execution. A pause request, cancellation request, or revised plan should enter the workflow as an ordered signal rather than mutate an in-memory flag. The workflow then handles that signal at a defined transition point. This matters because “stop now” is not a sufficient production instruction: the system must decide whether the active step may finish, whether pending steps remain runnable, and what state callers will observe.
A workflow steps table makes those decisions inspectable. Each step has a status such as pending, running, completed, failed, or cancelled, while the workflow has its own state. That distinction prevents a paused workflow from making every completed step ambiguous. Operators can see the last committed boundary, identify work still in flight, and determine whether resumption means scheduling a new step or waiting for an existing attempt to settle.
Resumption is safe only when replay cannot duplicate effects. I use an idempotency key for each logical step so retries and recovered workers converge on one execution result. A step fingerprint adds protection when replanning emits work equivalent to something already completed—the new plan can recognize the same effective step even if its position changed. Together, these mechanisms turn exactly-once step execution from a timing assumption into a deduplication rule.
This is especially important for pause-replay-resume. When a signal pauses execution, the orchestrator can replay durable history, apply a revised plan, and resume from the resulting state. It does not restart the agent from an informal summary. It preserves completed work, deduplicates equivalent steps by fingerprint, and schedules only genuinely new work. That is the difference between mid-execution replanning and quietly running the workflow twice.
Cancellation needs the same discipline. As I argue in cancellation is a protocol, a cancellation request is not proof that every effect has stopped. The workflow must record the request, define the fate of pending steps, settle any running attempt according to explicit semantics, and publish a terminal state only when those rules have been applied. Otherwise, “cancelled” becomes a misleading label over untracked work.
Non-retryable failures belong in this state model too. A dead-letter queue should capture the failed step and the durable context required for inspection or repair, rather than invite an automatic retry that can never succeed. The workflow remains explainable—its history shows why forward execution stopped, its steps table identifies the terminal failure, and control can be resumed only through a deliberate transition.
I make one precise concession: interruption cannot make an external side effect atomic when the target system offers no idempotency mechanism. In that boundary case, the workflow can record uncertainty and prevent blind replay, but it cannot prove whether the remote effect occurred. This is why I treat outbound callbacks as distributed transactions and expose indeterminate outcomes rather than manufacturing certainty.
The production test is simple: after any interruption, I should be able to answer what happened, what may still happen, and which transition authorizes it. Event history answers the first question, step status and deduplication answer the second, and signal plus cancellation semantics answer the third. A workflow differs from an agent precisely here—the workflow owns continuity when the reasoning process is paused, replaced, or gone.