When A succeeds and B fails, decide—don’t improvise.
Payment captures and inventory doesn't. The carrier said yes, but your call timed out. By morning the ledgers disagree, and whoever was awake decided what to retry. Half-done writes are ordinary, so decide in daylight what happens next.

For every critical multi-step write, draw the TWIMCO partial-failure decision tree: when step A succeeds and step B fails, choose compensate, retry, park, or notify—with a named owner and audit fields. Leaving the choice to the on-call engineer’s memory is how duplicate charges and silent divergence are born.
Half-done is an ordinary case
Payment captures. Inventory does not. The order is saved. The shipment call times out after the carrier already said yes. The CRM updates. Billing does not.
Someone retries both, or neither, or the wrong one. By morning the ledgers disagree.
If you only designed the happy path, the choice belongs to whoever is awake. Give them a branch before that night.
Four branches
For each pair of steps, pick a default.
Compensate. Undo the step that succeeded. Use this when leaving it in place is a lie or a double charge.
Retry. Try the failed step again, with a key that will not duplicate the side effect. Use this when the second step is safe to repeat and the first step should stand.
Park. Stop, with an owner and a clock. Use this when a person has to look before anyone touches it again.
Notify and stop. Tell a named role and do not continue. Use this when continuing would be worse than waiting, and you have written down what "waiting" means.
"Someone will notice" is not a branch. Always-retry creates duplicates. Always-undo makes the happy path fragile. Park-forever is a parking lot. Notify-only, with no state, is noise.
How the work moves
Four branches after A ok / B fail
- Compensate
Undo or offset A; idempotent compensation.
- Retry B
Only if idempotent; capped; then escalate.
- Park
A stands; human owns; timeboxed.
- Notify
Alert without pretending B succeeded.
Partial success is not a rare bug—it is a design case you either name or inherit.
Draw three real pairs
Do not start from a framework diagram. Start from three writes you already fear.
For each, write the owner and what gets logged: what succeeded, what failed, which branch you took, and the state a stranger would see in the morning.
Share the tree with whoever owns the other side of the edge. If their retry fights your undo, fix that agreement before the next incident chooses for you.
Decide in daylight
Tabletop the compensate branch and the park branch once. The point is to find the blank owner while everyone is calm.
Put the tree next to the boundary for that edge. A retry policy in one document and an undo in another, with no one reconciling them, is two instructions that will meet at 2 a.m.
Put this into practice
Pick three critical pairs this week. Choose the branch. Name the owner. Link it to the boundary for that edge.
This is business process automation when the design is the handoff, not the happy path.
Related work: Paddle8.
Decision guide
Improvised vs decided
| Consideration | On-call invents | Tree filled |
|---|---|---|
| Duplicate risk | Blind retry both sides. | Retry only idempotent B with caps. |
| Undo | Manual guess. | Named compensate path. |
| Waiting | Silent half-state. | Park with owner and SLA. |
| Comms | Ad-hoc messages. | Notify templates tied to state. |
We build alongside the people doing the work.
Bring us the problem you’re thinking about.