"The dedupe key has to exist before the first send — which means the client, not the server, has to mint it."
Why the ID Is Born on the Phone
To dedupe retries, every attempt at the same intent must carry the same key. Now ask: when does that key first need to exist? At capture — before the very first send — because the first send might be the one whose acknowledgment gets lost, forcing a retry that needs the matching key. If the server minted the ID, the phone wouldn't have it until a response came back, and a lost response would leave the retry with no key to match. So the device turn ID is minted on the phone, at capture time, and travels with every attempt from the first one onward.
One Key, Written Into the Canonical Log
The device turn ID isn't just a phone-side detail; it's recorded in the canonical log alongside the turn it identifies. That's what makes it a true dedupe key rather than a local guess: the backend persists it, so when a second request arrives bearing an ID it has already seen completed, it can recognize the repeat and return the existing result instead of doing the work again. The key is the shared vocabulary that lets phone and backend agree on "this is the same turn" across an unreliable link.
- Minted: on the device, at capture, as a UUID — globally unique without coordination.
- Persisted: in the local outbox and in the canonical log once the turn lands.
- Carried: on every delivery attempt and every retry of that intent, unchanged.
Stable Identity Is the Whole Trick
The power comes entirely from the ID being stable across attempts. Generate a fresh ID on each retry and you've defeated the purpose — the backend sees three different turns instead of three attempts at one. The discipline is strict: one intent, one ID, for the life of that turn. Mint it once at capture, persist it immediately, and never regenerate it, no matter how many times you resend. Everything the next lessons do — checking before calling, avoiding double-sends — depends on this one identifier staying constant.