Compensation and Cleanup
A saga records which forward steps definitely succeeded. If later work fails or the run is cancelled, WOML runs their explicit compensations in reverse completion order, then runs cleanup. This is not an automatic rollback or a distributed transaction: each corrective action must be designed for the external system it changes.
Define a saga
Place this fragment inside <steps>:
<saga id="checkout">
<step id="capturePayment">
<script>return { paymentId: "payment-42" };</script>
<compensate timeout="30s" retry="5">
<script>
return {
refundedPayment: context.steps.capturePayment.paymentId,
idempotencyKey: attempt.idempotencyKey
};
</script>
</compensate>
</step>
<step id="commitOrder">
<script>return { orderId: "order-42" };</script>
</step>
<cleanup>
<step id="closeSession">
<script>return { closed: true };</script>
</step>
</cleanup>
</saga>This example illustrates placement and bindings; replace the placeholder scripts with supervised calls to your payment and order systems. A compensation is registered only after its forward step definitely succeeds. Cleanup runs on success as well as failure. A saga that has committed is not reopened by a later failure outside it.
Handle uncertain effects
Use the original forward result to identify the exact resource being corrected. Use attempt.idempotencyKey if the external API supports it. When an external effect may have happened but cannot be proven, WOML stops for explicit operator resolution rather than guessing or retrying blindly.
woml get <run-id> --jsonCorrective scripts cannot contain their own waits or approvals. Put the authorization and evidence before the effect, and review the external system's state during an ambiguous recovery.