ADR-0049 Sales approval and combined Prisma admission proof
Sales acknowledges ADR-0049's payment-based ownership design and the existing Revenue scoped-read authorization position. This memo completes the requested combined Sales persistence proof. It does not clear paid-invoice-handoff-ready, authorize deployment or establish Revenue/Delivery semantic behavior. The root local implementation commitment remains completed; activation and existing-client reconciliation remain conditional.
Source and verification boundary
The isolated Sales checkout is C:/Users/jallr/Documents/Sguild/repos/sales/.cache/payment-handoff-race, branch codex/payment-handoff-race-proof, local commit 4c1a950c1934ad6c49e168e6a2ce231a197b04c6. It includes owner ADR-0048 commit a171613 via cherry-pick 718de67, with e54a69c admission locking as an ancestor. The handoff core and organization metadata are combined with the actual closure code while preserving its guards and DTO fields. This proof branch is local and not pushed or deployed. The complete Sales runtime integration remains in the original dirty workspace; this checkpoint is not a complete rollout branch.
Command from Sales root:
npx tsx scripts/local-dev/prove-payment-handoff-races.ts --checkout .cache/payment-handoff-race
The runner checks both DATABASE_URL and DIRECT_URL for loopback, verifies source and generated Prisma models explicitly use the sales schema, creates a new database, installs that schema with Prisma db push, and applies the closure partial-unique indexes. It does not seed, reset, or reuse the shared mesh. The test verifies both rewritten URLs, the generated schema and actual current_database again before enabling the feature only inside its child process. All outbound fetch calls fail, consumer URLs point to an unreachable loopback target, and dispatcher/external-action fanout remains false.
The final run exited 0, with 11 of 11 tests passed. Dedicated database: sales_handoff_race_a108c7eea0764d20935589f2b5591a46. Retained manifest: sales/.cache/sales_handoff_race_a108c7eea0764d20935589f2b5591a46.json. Generated Prisma delegates, row locks, transactions, stage transitions, audit writes and dispatcher outbox are real. Only Revenue's assessment read is synthetic. No Delivery consumer runs here. This proves Sales serialization and persistence only.
Earlier failed-run databases and manifests remain preserved. In particular, sales_handoff_race_4ebb67de51e148c6b24283d2ac9ea5f0.json exited 1 because a new teardown assertion incorrectly required existing-journal lease claims to use Serializable. That run is not the final pass. The final harness records lease isolation separately and asserts every critical Lead write uses Serializable; it retains all semantic scenarios and verifies the actual PostgreSQL conflict code.
Results
When cancellation or producer admission wins, its transaction updates the common Lead version before committing the journal. A waiting Serializable payment snapshot aborts; a fresh service call sees the unresolved journal and defers. A row lock without changing the common Lead was insufficient for this snapshot guarantee and is not the implemented protocol.
When payment wins, cancellation and producer admission abort and fresh retries reject the terminal Lead. The producer callback is never called in this ordering. Unknown or blocked producer outcomes preserve their open admission rows and cannot be bypassed. Concurrent duplicate payment commits one handoff and returns the same receipt on retry. Existing unresolved rebooking and immutable historical Locked/Lost decisions are unchanged.
Six real serialization aborts are recorded: Prisma P2010, meta.driverAdapterError.cause.kind = TransactionWriteConflict, PostgreSQL originalCode = 40001. Every critical Lead write recorded Serializable. Existing-journal worker lease bookkeeping may use Read Committed and cannot admit a new operation or change terminal ownership.
| Case | Persisted Lead | Final substage |
|---|---|---|
| closure_first | lead_01a0e0b5-e4f5-7162-960d-8debb5439d65 |
awaiting_payment |
| handoff_before_closure | lead_01a0e0b5-e9db-73cb-a028-a3ad03fe70d5 |
handed_off |
| admission_blocked | lead_01a0e0b5-ecbe-70e8-be70-133909faf7d7 |
awaiting_payment |
| admission_unknown | lead_01a0e0b5-ed78-74bc-8da1-482546f34912 |
awaiting_payment |
| handoff_before_admission | lead_01a0e0b5-ee62-7377-ab99-141af324a3f0 |
handed_off |
| duplicate_payment | lead_01a0e0b5-efbc-744a-a6f9-506164fb674b |
handed_off |
| rebooking_in_progress | lead_01a0e0b5-f0a2-75d3-995b-6ed2671bc27e |
awaiting_payment |
| rebooking_failed_needs_review | lead_01a0e0b5-f15c-7119-a118-337a0bb9ecc5 |
awaiting_payment |
| rebooking_blocked | lead_01a0e0b5-f1a0-7680-b0c9-b25c1d19ac19 |
awaiting_payment |
| terminal_locked | lead_01a0e0b5-f1df-7204-82fe-4914a6278b18 |
locked |
| terminal_lost | lead_01a0e0b5-f260-7688-b0b8-e8a1f65d7ea7 |
lost |
The cancellation-first case retains closure journal ocl_09c72906-d0be-430b-ac1f-7fb92c67141f. Blocked and unknown producer cases retain their onboarding_operation rows. These three cases emit zero handoff events.
Each successful payment case has exactly one handoff history row, one stage event, and one specialized event:
lead_01a0e0b5-e9db-73cb-a028-a3ad03fe70d5: historylsh_01a0e0b5-ebac-74c3-9ee2-5ca87068c970; stageevt_01a0e0b5-eaae-79b5-881b-b91b11212101; handoffevt_01a0e0b5-ec2f-728c-905b-8703e85f2433.lead_01a0e0b5-ee62-7377-ab99-141af324a3f0: historylsh_01a0e0b5-ef20-70b6-ba82-2dccdfdfcd72; stageevt_01a0e0b5-ef13-7743-b687-fbff9c670eab; handoffevt_01a0e0b5-ef89-716b-a233-69b36942bb50.lead_01a0e0b5-efbc-744a-a6f9-506164fb674b: historylsh_01a0e0b5-f042-713a-99ed-6f691ee8d4a5; stageevt_01a0e0b5-f03b-73af-991c-9bd4fe006ac5; handoffevt_01a0e0b5-f071-7d34-a8b5-855bd064941d.
The manifest includes exact order, Person, nondefault organization, market, task and event payloads for all cases. The three successful cases have no lesson/reservation, proving the Sales producer does not require lock or booking. They do not establish Delivery customer/preparation behavior.
Organization provenance and reporting
Onboarding flow metadata now supports optional explicit organizationId. Sales saves it only after selecting a Revenue invoice fetched under the authenticated organization or explicit existing booking scope, with exact Person/Lead correlation validation and a transaction-time scope recheck. Saved and booking organization conflicts defer; no-booking nondefault organizations work. Missing legacy provenance defers as organization_missing. The legacy display default is not persisted as payment ownership evidence. Existing communication history and copy are unchanged.
For the successful fixture rows above, lead.stage.changed@1 carries actual from_stage=onboarded, to_stage=terminal, transition_reason=inbound_event. It contains no substage or evidence classification. The immutable source row has to_substage=handed_off, handoff_evidence=invoice_paid. The exact same decision timestamp is persisted as history changed_at and stage payload transition_at, verified in all three cases. Warehouse should count the earliest immutable successful handoff per tenant/Lead, not add a second conversion from the specialized event or infer success from terminal alone. Historic evidence remains unchanged.
Validation and remaining gates
The current main workspace passes 435 focused Sales tests and typecheck. Its 11 opt-in race tests are skipped unless the dedicated runner preflights a fresh database. The combined checkout additionally passes 275 focused handoff/closure unit tests and typecheck; the four separate adapter-level Postgres tests are skipped in that unit run. The final real generated-Prisma suite passes all 11 scenarios. Diff and event-registry checks pass. Prior local cadence drift/readiness evidence remains one unrelated missing enrollment on lead_01900000-0000-7000-8000-000000001011; no repair was made.
Remaining activation evidence includes Revenue's real coherent full/partial/offline/refund/cancellation assessment and auth, Delivery's durable consumer with exact customer/OrgMarket/context/preparation records, no-booking and repeat/inactive-customer handling, later lock dedup, disabled-first Platform routing, real cross-domain producer races, accepted contracts, consumer deployment, and review of exact existing-client preview before normal-service apply. A dispatcher acknowledgment alone cannot satisfy these gates. No production flag, deployment, financial mutation, outbound message or existing-client transfer occurred.
Final source hashes
SHA-256 values from the final exit-0 manifest:
| Path relative to combined checkout | SHA-256 |
|---|---|
modules/payment-handoff/repo.ts |
2d6a6d8f334b020eee0b9aae47cd2129c1911059b9255cd81b79ac252b96e6f2 |
modules/payment-handoff/service.ts |
9ca6ebf5a90e7b1ea7ef33e88a79d89e4c269eb2c1432d946a907697f7630aa9 |
modules/payment-handoff/races.postgres.test.ts |
1613d98353a71f6739e566ca384710cee9826223a476f4b85b6a4585d885f28d |
modules/onboarding-closure/admission.repo.ts |
4d68936ddcad88b78a04dd4c948069ec1f44456c4d5c3c7be280384da2997c78 |
modules/onboarding-closure/repo.ts |
b5a7abb96b382b4d41da79ac416b57fdfbda0ce7e9c4d81bc8157586e6679d77 |
modules/leads/leads.service.ts |
05b4ca90aa89259fbb71b5b56376f1167f6de13e387d256c77f709181a702efe |
modules/lead-onboarding/repo.ts |
a60bcef52230f74e2a3b5353c031ad7acaea82dc40ddfec7ecb464756cff7726 |
prisma/schema.prisma |
ecd2b23be2e410dd931b156a2b0bac3c4699e05acad0b0bbe76e03c658c3478f |
node_modules/.prisma/client/schema.prisma |
819712fe0be5b51a38c65666bc03cbd7810abffc3c75c38c030c7a013acd9c76 |