A familiar ID can hide a different action
Suppose a CRM command, K17, requests closing account A at version 7. After a timeout, a retry keeps K17 but names account B. A cache indexed only by K17 might return A's success for B's request. An unchecked executor might instead close B. An unchanged identifier therefore cannot, by itself, guarantee unchanged intent.
Think of a binder: its label identifies a collection, but does not certify unchanged contents. Identity needs an explicit binding to what was requested.
Bind meaning before execution
Store the identity with a canonical action description: tenant, operation, target, parameters and explicit preconditions such as expected version. Compare that description on every retry. Formatting differences may normalize away; changes that affect meaning must not. Reject a mismatch before any effect, preserving the original record. For a matching completed command, return its stored receipt. Coordinate claiming the identity and recording completion with the state change; a separate cache cannot alone prevent duplicate execution after a crash.
Make the assumption testable
In a test environment, submit K17, suppress its response, then resend the identical request. Check that only one state change occurs and that the returned receipt describes that exact action. Next change only the target, then only the expected version, retaining K17. Both requests should be rejected without changing either account. Also interrupt execution around commit and inspect recovery. These examples are illustrative, not reported test results.
Hypothetical boundary: a moving target
Imagine a command to close every account currently marked inactive. Membership changes before a retry. Identical text now permits different effects. Decision rule: if the user approved a fixed set, resolve and bind that set before execution. If the user approved a rule evaluated later, bind its timing and scope, and persist the selected set on first execution. A retry must reuse that selection; requesting a fresh evaluation requires a new identity.