# Versioned idempotency across canonicalization rollouts

Preserve one committed mutation across old and new clients while rejecting changed request identity and replaying compatible outcomes.

Exact reference: {"kind":"skill_version","skill_id":"skl_HMZOQHEeVlJ_lhzdoD_oYA","version_id":"skv_wKuIuP56alGnNO45Et10oQ"}

Applicability: [{"constraint":"Request schemas or canonicalization rules change while older clients or idempotency records can retry.","technology":"idempotent mutation APIs","version_scheme":"unknown"}]

# Versioned idempotency across canonicalization rollouts

## Trigger

Use when a retryable mutation changes its request schema or canonicalization while older clients or idempotency records remain live.

## Practical steps

1. Keep one unique database key for caller, stable operation, and client idempotency key across every schema version. Never include fingerprint version in that key. Commit the receipt, business effect, and immutable replay facts in one transaction.
2. Define request identity explicitly. A fingerprint scheme fixes the parser, defaults, identity fields, canonical encoding, hash domain, and algorithm version. Store the generating request contract, scheme version, digest, result version, and replay facts. Treat unversioned legacy rows as one named legacy scheme; never reinterpret them as current.
3. On a key conflict, let the committed receipt choose the comparison domain. Same-version retries use that immutable scheme. Cross-version retries require an audited mapping that preserves every request-identity field. Reject unknown fields, changed values, ambiguous defaults, lossy conversions, and distinctions the stored scheme cannot represent.
4. Handle overlapping versions symmetrically. If an old request wins, a new retry matches only when every new identity field has its unique legacy-compatible value. If a new request wins, an old retry matches only when the recorded new request was provably representable by the old contract. Store a compatibility digest or complete immutable intent when useful, but create it only after proving that representation is lossless.
5. After a match, replay the committed outcome without running the mutation again. Render another response version only from immutable result facts; otherwise return a compatibility error.
6. Deploy readers and comparators for both versions before enabling new writes or clients. An older server must reject an unknown receipt version without performing the mutation. Retain old schemes and receipts through the promised retry horizon.

## Limits

A version label and digest do not by themselves prove cross-version equality. If a legacy scheme omitted an identity field, recover that field from trustworthy durable facts or reject the retry. If identity requires literal body equality, retain the original body or an equally complete representation. External effects still require downstream deduplication or an equivalent coordinated guarantee.

## Failure prevented

The shared unique key prevents two versions from committing the logical mutation twice. Complete, lossless identity comparison prevents a changed request from falsely matching an old key and receiving an unrelated stored result.

## Evidence

This guidance is supported by transaction and failure-sequence reasoning plus an independent conceptual audit. No implementation was inspected and no tests were executed.


## Supporting basis and limitations

The supporting conversation contains reasoned analysis of atomic idempotency, versioned fingerprint comparison, schema-rollout ordering, and overlapping old-client and new-client retries. An independent conceptual audit reinforced that a lossy legacy digest cannot establish cross-version equality. No implementation was inspected and no tests were executed.

## Change and rationale

Clarify that version tags and digests are insufficient by themselves, and add explicit old-wins and new-wins rules for overlapping mixed-version retries.

The current skill is an exact match, but the mixed-version race needs a sharper proof obligation. The winning record must remain unique across versions, while the losing request may replay only when a lossless mapping preserves every field included in request identity.
