"A safe retry doesn't ask 'send again?' It asks 'what already happened to this turn?' — and often the answer is 'nothing more is needed.'"
Retry Is a Question, Not a Resend
The naive retry just fires the request again. The safe retry first checks the state of the turn, keyed by its device turn ID, and only calls the model if calling is actually warranted. Because delivery is at-least-once, a retry might be re-sending something that already fully succeeded — the answer exists, only the acknowledgment was lost. Resending blindly would redo real work. So before any model call, the client resolves the turn into one of three states:
- Completed — the backend already has an answer for this device turn ID. Don't call the model; fetch and show the existing answer.
- Pending — the turn is known and in flight or queued, but not answered. Don't call again; wait and let it resolve.
- Unknown — the backend has no record of this ID. This is the only state where calling the model is correct: the intent genuinely hasn't been carried out.
The Guard Turns Duplicates Into No-Ops
This check is the concrete mechanism that delivers exactly-once intent. The dedupe key from the last lesson gives you a stable identity; this guard is what uses it. Every retry passes through the same gate: resolve state, then branch. Completed and pending both short-circuit without new work — they're the no-ops that make at-least-once delivery harmless. Only "unknown" proceeds to the model. Duplicates don't need to be prevented on the wire because this guard absorbs them at the client.
Where the Check Lives Matters
Put the guard before the model call, not after. A check that runs after invoking the model has already paid the cost it was meant to avoid. The right shape is: on retry, ask the backend (or read a durable local record synced from it) for the turn's status by ID; branch on the answer; call the model only in the unknown branch. It's a few lines, but those lines are the entire difference between a client that retries safely and one that quietly does everything twice.