mergedhumanPR #250Identity
Make message acceptance atomic and bind the complete envelope
Make current Town's durable message acceptance atomic and bind replay to the complete message envelope.
Description
The pitch.
## Summary Make current Town's durable message acceptance atomic and bind replay to the complete message envelope. This carries forward the concurrent-retry and request-identity requirement identified while reviewing [#211 by ChiJian28](https://github.com/projnanda/nandatown/pull/211), at `a39b0f0adff59ea9bfebcdf7010ec317a1ac27f1`. It is a fresh fix for the current coordinator, not a port of the legacy Prava payment adapter. ## Behavior - Begin one SQLite write transaction before looking up a message ID. Lookup, insertion, notification and event writes use that connection. - Exact retries match sender, recipient, kind and body fingerprint and return the original acceptance time. Completed work and consumed or suppressed notifications are not reset. - Reusing the ID with a changed envelope commits rejection evidence and returns the existing HTTP 409 response. - Initial acceptance rolls back completely if notification or event insertion fails. - Preserve schemas, body-only fingerprint meaning, canonical payloads, permissions and claim/ack behavior. ## Verification - TDD: 14 failures / 34 passes before the fix; 48 focused tests pass afterward. - Full suite independently rerun by the controller: **461 passed**, 8 existing warnings. - Real independent SQLite connections exercise identical and conflicting simultaneous acceptance with deterministic race setup, without sleeps or barriers behind a write lock. - Coverage includes each envelope field, reordered body keys, separate runs, fresh-process retries, state preservation, transaction rollback and HTTP 202/409 behavior. - Independent expert review passed spec compliance and code quality with no actionable findings. Concurrency tests use threads with separate connections; fresh-process coverage checks sequential retry, not a load test. ## Scope and credit This fixes exactly-once **local acceptance**, not exactly-once external effects. Existing SQLite busy-timeout behavior and claim/ack concurrency are unchanged. The broader provider integration from #211 remains separate: durable outbound-effect journals, uncertain-response reconciliation, provider authorization, currency/principal binding, refunds and independently observed merchant completion need their own profile and tests. No live payments or contributor code were executed. The source PR remains open until this replacement is merged and its selected/deferred scope is documented.
Try it
Open PR on GitHubView diffCheckout locally
git fetch origin pull/250/head:pr-250
git checkout pr-250