feat(server): Idempotency-Key — response-capture ledger, replay, capability flag (CWD-5) - #325
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ned updateRow body type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Idempotency covered exactly one of ~25 write routes (keyless page-create), so a client retrying any other write — and especially the coming CWD-7 offline outbox replaying after a crash — risks double-applying mutations. Board: CWD-5 (epic OB-76); implements §4 of the merged write contract (#321).
Solution
Idempotency-Keyaccepted on the 17 wave-1 routes (400 elsewhere): SHA-256 request fingerprint (length-delimited method/path/media-type/exact body bytes), actor-scoped, with a response-capture ledger written in the same transaction as the mutation — replay returns the captured response byte-exact and suppresses broadcasts/edit-log; fingerprint mismatch → 409idempotency-key-reused; destroy replays resolve before existence checks; CAS 409s consume no key; 7-day GC.GET /api/instancenow advertiseswriteContract: 1so outboxes never auto-replay against old servers. Composed with CWD-4's persister fence (claim/replay outside, fence inside — replay never re-enters the fence). Restoring correct nested-savepoint semantics on Postgres (native driver scopes) came out of review and hardens the whole store.Key files:
packages/server/src/{app,store,db,dbCore,migrations}.ts. New deps: none.Before / After
No visual change — server write semantics.
idempotency-key-reused, outbox marks INDETERMINATEwriteContractcapability gateTest procedure
Operational notes
Migration 0028 (drop/recreate of the unreleased 0027 ledger as TEXT — the JSONB variant existed on-branch for 44 minutes and is preserved for immutability). GC via the existing purge scheduler; TTL
<=0= forever preserved. Bare-204 destroy bodies stay as-is (CWD-2's remit, recorded on its board acceptance).Verify: green (full
pnpm verifyon the merged tip; 86/86 at the fence×idempotency intersection). Reviews cleared: code (Quinn — full round C1-C8 incl. two blockers fixed, then targeted C5/C2 verification: "downstream CWD-2/6/7 can build on this").🤖 Generated with Claude Code
https://claude.ai/code/session_018RUicirLRuuZvjJN13N6yN