Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
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.

Author

JamesCarnley avatar

@JamesCarnley

github profile →
Status
Merged
Merged on
Sep 4
Branch
fix/atomic-message-acceptance

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 diff

Checkout locally

git fetch origin pull/250/head:pr-250
git checkout pr-250