events: paid-ticket contract (commerce) over holds + 31 tests (Phase 2 done)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 42s

ticket.sx: checkout-request (events->commerce) + payment-result
(commerce->events) wire shapes — commerce imports the contract. ev/request-
ticket! holds a seat + emits a checkout request; ev/settle-payment! confirms
on :paid, releases on failure/expiry. Idempotent; late paid for a vanished
hold -> :paid-but-no-hold (refund signal). 175/175 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 03:34:15 +00:00
parent 7153e742c8
commit 05d5c46730
6 changed files with 374 additions and 7 deletions

View File

@@ -18,7 +18,7 @@ capacity rules, transactional booking, and a flow-driven notification dispatcher
## Status (rolling)
`bash lib/events/conformance.sh`**144/144** (Phase 1 + Phase 2 booking/cancel/holds + persist-backed api)
`bash lib/events/conformance.sh`**175/175** (Phase 1 + Phase 2 complete: booking/holds/paid-ticket contract)
## Ground rules
@@ -66,7 +66,7 @@ lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ──
- [x] wire `booking.sx` into `api.sx` (persist-backed `ev/book-occ!` + derived availability)
- [x] cancellation (tombstone events) + seat release
- [x] provisional holds (hold/confirm/release) — reserve a seat during pending payment
- [ ] paid tickets compose with `commerce` order flow (contract module over holds)
- [x] paid tickets compose with `commerce` order flow (contract module over holds)
- [x] tests: capacity edge, double-book guard, conflict detection
## Phase 3 — Notification delivery (flow)
@@ -82,6 +82,16 @@ lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ──
## Progress log
- 2026-06-07 — **Phase 2 complete: paid-ticket contract.** `ticket.sx` defines
the two wire messages between events and commerce — `checkout-request`
(events→commerce) and `payment-result` (commerce→events, :paid/:failed/
:expired) — so commerce imports the contract, not vice versa. Orchestration
over holds: `ev/request-ticket!` places a capacity-safe hold + emits a
checkout-request; `ev/settle-payment!` confirms on :paid, releases on
failure/expiry. Idempotent (redelivered :paid stays confirmed, redelivered
release is :noop); a late :paid for a vanished hold → :paid-but-no-hold
(refund signal), no phantom seat. occ-key+actor locate the hold so no side
table. +31 tests, 175/175 green. Phase 3 (notification flows) is next.
- 2026-06-07 — Provisional holds (paid-ticket foundation). Booking stream now
carries :booking/:hold/:confirm/:release/:cancel; the fold tracks per-actor
seat STATE (:held / :confirmed). A held seat counts toward capacity, so a