The duplicate-refund failure mode
The provider may commit the refund before the response reaches the agent. The caller sees a timeout and retries. Without stable logical identity or reconciliation, the second attempt can look like a brand-new refund.
Recovery sequence
- Reuse the same logical operation identity.
- Read durable operation state.
- Reconcile authoritative provider truth where supported.
- Replay stored results when already confirmed.
- Block another external execution if the outcome remains unsafe to determine.
Run the failure yourself
Minimal failure: send one refund; the provider commits; lose the response; retry after restart. A new request without effective deduplication can create another refund.
// Unsafe when the first refund may already have committed:
try { await refundCustomer(intent); }
catch { await refundCustomer(intent); }
Use the runnable local refund proof: a separate HTTP provider records two unprotected effects versus one with Once, followed by UNKNOWN blocking, authoritative reconciliation and changed-amount CONFLICT. No financial account is required.
When an idempotency key solves it
If the provider key binds the complete intended operation for your full retry horizon, use it. Once does not replace that guarantee. A local result table cannot make an arbitrary external write atomic with a database commit; preserve uncertainty when no trustworthy result exists.
Limits and next action
The controlled proof is not a real payment integration. Your developer must explicitly choose a stable, tenant-scoped refund-intent ID and complete effect/account fields. Use distinct IDs for genuine new partial refunds. UNKNOWN stays blocked when truth is unavailable; absence alone does not authorize local redispatch. Local SQLite is limited to one machine.