Darkmind / Issue 017

Design the Undo Before the Action

For a multi-step AI workflow, define the compensating action beside every consequential forward step—before the model is allowed to run it.

Oct 24, 20264 min readAgent reliability

An AI workflow that completes one action at a time can still leave a mess. It might reserve inventory, create a customer record, and then fail to collect payment. It might publish a draft, update a tracker, and then discover that a required approval was missing. A retry key prevents duplicate calls; an approval gate prevents an unreviewed start. Neither answers the next operational question: what should happen to the steps that already succeeded?

The practical move is to design the compensation plan before an agent can begin a multi-step, consequential workflow. For every forward step, name its business-safe undo or repair action, the data needed to perform it, whether the action is reversible, and the person or rule that may authorize it. Store that plan as each step succeeds. If a later step cannot recover, the workflow can unwind what it actually completed instead of asking a model to improvise a rollback from a transcript.

Microsoft’s Compensating Transaction guidance describes recording how to undo each completed step in an eventually consistent workflow, then applying compensating actions if a later step fails.[1] The original Sagas paper frames long-lived work as a sequence of smaller transactions, each with a compensating transaction that can semantically undo its effect.[2] The word semantically matters: canceling a reservation or issuing a credit is not always the same thing as restoring old database bytes.

Start with the business effect, not the API call

Do not write DELETE /reservation/123 as an undo plan and call it finished. Ask what the forward step changed in the world and what a safe repair means after time has passed.

A successful reserve_inventory call may be compensated by release_unshipped_reservation, but only while the item has not shipped. send_welcome_email may have no true undo; the right response could be notify_support and record a correction. create_invoice_draft might be safely deleted, while submit_tax_filing is a point of no return that must wait until all earlier validation is complete.

That distinction gives an agent a useful boundary. It can choose among pre-approved forward steps, but it does not get to invent a refund amount, cancel a shipment, or erase a record simply because a later tool returned an error. The workflow owns the compensation map; the model receives only the status and allowed next move.

Copy this compensation card

Create one card for every consequential step before enabling the workflow. Keep it with the proposal or workflow definition, not only in a prompt.

WORKFLOW: [named business outcome]
OPERATION_ID: [one durable ID for this attempt]

STEP: [1, 2, 3...]
FORWARD ACTION: [allowlisted command]
SUCCESS RECEIPT: [provider ID, version, amount, or other evidence]

COMPENSATION
- action: [allowlisted undo or repair command | none]
- allowed when: [preconditions, time window, state]
- required data: [IDs and immutable values captured on success]
- idempotency key: [derived, stable compensation ID]
- authorization: automatic | named policy | human approval
- outcome: compensated | alternative path | manual review | irreversible

STOP RULE
- retry forward step: [only for named transient conditions]
- begin compensation when: [exhausted retries / business failure / cancellation]
- never compensate automatically when: [high-impact or ambiguous condition]

AUDIT
- forward result: [timestamp + provider receipt]
- compensation result: [timestamp + provider receipt]
- owner if blocked: [team or queue]

The required data line is where many recovery plans fail. Capture the reservation ID, original quantity, account, version, and any deadline at the moment the forward action succeeds. Do not expect an agent to reconstruct those values later from a natural-language summary. The original record may have changed, and the current state may reflect somebody else’s valid work.

Reverse completion, not the intended checklist

When a workflow fails, compensate only the steps that actually completed. If steps 1 and 2 succeeded but step 3 failed, inspect their receipts and start from the appropriate repair order. That order is often reverse completion order, but it is not a law. Microsoft notes that some compensation actions can run in parallel or need business-specific ordering; the most consistency-sensitive system might need repair first.[1]

Keep forward retries separate from compensation. A brief timeout while creating a draft may justify a bounded retry using the original operation ID. An invalid approval or a permanent business rule failure should stop the forward path. Only then choose among a defined alternative, compensation, or human review. This avoids the destructive pattern of “undo everything whenever any tool looks unhappy.”

Failure mode: pretending every effect is reversible

A compensation plan does not erase a message a customer read, an external shipment that left the warehouse, or a legal filing that has been accepted. It can also fail on its own. Microsoft recommends making compensating commands idempotent, recording their progress, and alerting for manual intervention when recovery cannot finish automatically.[1]

Mark irreversible steps explicitly and place them late, after validation, approvals, and the highest-risk dependencies have passed. For an ambiguous, expensive, or customer-visible situation, pause with the completed-step receipts and a proposed repair. A human can decide whether to continue through an alternative, compensate selected steps, or accept a partial outcome.

The habit to keep

before an AI workflow makes its first consequential change, make every step answer one question—if a later step fails, what exact, authorized repair will preserve a valid business state?

Sources

  1. Microsoft Learn, “Compensating Transaction pattern”
  2. Garcia-Molina and Salem, “Sagas”