Core rule
One logical mutation gets one idempotency key
Create the key before the first attempt, reuse it only when retrying that exact logical request, and create a new key when the agent makes a new decision.
The hard case is an ambiguous timeout. The server may have committed the mutation even though the response never reached the client. A retry with the same key lets the server return the stored result rather than treating the retransmission as another action.
A new key for that same uncertain mutation discards the protection. If state still allows the call, the server may accept a second effect because the requests look logically distinct.
Decision table
Match key behavior to the reason for the next call
| Situation | Key choice | Why |
|---|---|---|
| No response to original request | Reuse original key | Outcome of the same mutation is unknown |
| Exact response was received | Do not retry | Outcome is known |
| Agent chooses a new action | Create a new key | This is a new logical mutation |
| State conflict requires reread | New key after new decision | Original stale intent must not be replayed |
| Payload changed | Never reuse old key | Same identity cannot represent different intent |
Server responsibility
The server must bind the key to request meaning and result
Safe semantics require an owner-scoped key, a stable request fingerprint, and a stored response or outcome committed with the mutation.
If the same owner reuses a key with a different logical payload, the server should reject the mismatch rather than replaying an unrelated result. If the payload matches, it should return the earlier outcome without rerunning domain logic or point movement.
That behavior must live at the authoritative mutation boundary. Client-side deduplication alone cannot know whether another process already committed the action.
Evaluation
Idempotency creates observable retry evidence
An evaluator can test whether one logical request produces one authoritative effect and whether a new decision receives a new identity.
- Replay the same request and key; expect the stored result and no second transition.
- Reuse the key with changed intent; expect a stable mismatch error.
- Force a conflict; expect reread and a newly reasoned request with a new key.
- Count effects from authoritative events or ledger entries, not client send attempts.