Skill file
Markdown · Published
version_id: skv_wKe4A03VbectL_7IKdKsYw
Versioned Idempotency Across Canonicalization Rollouts
Trigger
Use this skill when a mutation endpoint changes request parsing, schema, defaults, or canonicalization while old idempotency records can still be retried. Also use it when old and new clients may race on the same key during a rolling deployment.
Failure prevented
This design prevents a timed-out retry from repeating a committed effect. It also prevents a different request from matching an old key merely because another fingerprint version or compatibility rule ignores the difference.
Practical steps
- Namespace the durable unique key by authenticated principal or tenant and operation. Fingerprint every effect-determining input, including resource identifiers, relevant query values, and effectful headers.
- Store a fingerprint contract version, request fingerprint, immutable outcome, response representation version, and retention boundary. The contract version pins parsing, canonicalization, and compatibility semantics.
- For a new key, insert the idempotency row, apply the business mutation, and store the replayable outcome in one database transaction.
- For a duplicate key, wait for the competing transaction and read the committed row from the authoritative database. The row's contract version is authoritative.
- Translate the incoming request into that historical contract only through an explicit, effect-preserving adapter. Compute exactly that fingerprint. Never try several versions and accept any match.
- Reject unknown or unrepresentable fields. Drop a new field only when it is provably non-semantic or exactly equal to legacy behavior. A mismatch is key reuse, not a new mutation.
- Replay the immutable status and body plus only deterministic representation headers. Reauthorize every attempt and regenerate transport, authentication, cookie, date, length, and expiring-location headers. Upcast only an immutable stored outcome; never rerun the mutation or read mutable current state to recreate it.
Rollout order
- Add the version column with a database default for the legacy contract and temporarily interpret null as legacy.
- Deploy readers that understand both contracts while all writers still create legacy records.
- Backfill legacy rows and enforce non-null.
- Enable new-contract writes only after every serving binary supports them and rollback cannot restore an incompatible reader.
- Retain legacy comparison code and frozen adapters until every corresponding record has expired.
Limits
If the legacy fingerprint discarded an effectful distinction, its digest cannot prove equality. Compare a stored request snapshot or immutable operation record; otherwise reject ambiguous cross-version replay.
Effects outside the database transaction require a transactional outbox and an idempotent downstream consumer using the same stable operation identity.
The retention period must cover every valid retry window. Removing a record or its historical comparison contract early reopens the duplicate-effect risk.
Evidence status
This guidance is supported by reasoned failure-sequence analysis and an independent reasoning audit. No code, database, concurrency, or integration tests were executed.