The short version
- Keep the proposed action, approval and operation identity outside the conversation.
- Distinguish “not sent”, “confirmed” and “outcome unknown”.
- Retry only under the destination’s documented repeatability rules.
- Recheck changed work and preserve a route to human recovery.
The dangerous gap
Consider an illustrative assistant that prepares a work request for an internal application. A person approves the draft. The application creates the record, but the connection drops before the assistant receives its identifier. On screen, the workflow appears to have failed.
If the assistant starts again and submits a new request, there may now be two records. If it confidently announces success, it may be wrong in a different way: perhaps the first request never arrived. The missing reply leaves an uncertain outcome that needs its own state.
Microsoft’s Retry pattern asks designers to consider whether an operation is idempotent: whether repeating it can create an additional effect.1 That question belongs at the tool boundary, before a model is allowed to decide that trying again sounds helpful.
Record the action before sending
Store the intended operation durably: its internal identifier, destination, exact payload, requester, approval reference and status. Separate that record from the model’s conversational memory. A restarted worker should be able to recover the approved proposal without asking the model to reconstruct it from a summary.
Where the destination supports idempotency keys, use a stable key for the same operation and check the documented retention window and payload rules. Microsoft’s asynchronous request guidance describes returning the existing operation status for a repeated key instead of queuing new work.2 The server must enforce this; adding a key to a request does nothing if the receiving system ignores it.
A request identifier in a log is useful for investigation, but is not automatically a duplicate-prevention mechanism. When the destination offers neither safe repeatability nor a dependable status lookup, an uncertain write should stop for reconciliation.
Resume from evidence
- Before sending. Recover the stored proposal and check that permission, approval and relevant preconditions still hold.
- After confirmation. Retain the destination’s record identifier and verified result. Do not replay the write merely because the final screen failed to update.
- After an uncertain result. Look up the operation or reconcile against the destination. Use a documented safe retry only where its guarantees apply; otherwise pause.
- After a changed proposal. Treat a different recipient, record, amount or payload as a new decision requiring the appropriate approval.
A fresh attempt must not inherit a stale permission decision indefinitely. Access may have been removed while the job waited, and the target record may have changed. Recheck the conditions that justify the write. Bind the approval to the reviewed action so that “resume” cannot silently become “do something similar”.
Recovery is not always undo
Some completed actions have an explicit reversal; others require a correction, cancellation or human decision. Microsoft’s compensating transaction guidance explains why recovery is business-specific and may not restore the exact previous state. Compensation can itself fail and needs recorded progress.3
For the work request, cancelling a duplicate may be appropriate before anyone acts on it. Once another person has started work, deletion could hide what happened. The recovery route should preserve the history and involve the responsible owner. Agree that route before release, while the decision is still calm.
Test the stopping points
Interrupt the workflow before submission, after the destination accepts it, and after confirmation but before the user sees the result. Restart the worker twice. Delay the status response. Change access during the pause. Check the number of actual destination records, not just the assistant’s final message.
Also test a dependency that stays unavailable. Bound retry attempts and elapsed time, then move the job to a visible operator queue. OWASP’s agentic risk-assessment guidance recommends injecting component failures and checking isolation and circuit breakers so an error does not spread through the workflow.4
What stopping should mean
An operator needs to stop new actions, identify work already in flight and reconcile uncertain outcomes. A stop button cannot unsend a completed request. The illustrative blueprint makes the ownership and recovery decisions inspectable; the test report shows what the local demonstration actually checks.
Sources and further reading
- Retry patternMicrosoft Azure Architecture Center↩
- Asynchronous Request-Reply patternMicrosoft Azure Architecture Center↩
- Compensating Transaction patternMicrosoft Azure Architecture Center↩
- Agentic AI risk assessment — ASI08: Cascading FailuresOWASP secure-agent-playbook↩