events: provisional holds (hold/confirm/release) for paid tickets + 24 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s

Booking stream gains :hold/:confirm/:release; fold tracks per-actor seat state
(:held/:confirmed). A held seat counts toward capacity so a pending payment
can't be oversold. ev/hold! (capacity-safe), ev/confirm!, ev/release!,
ev/seat-state. Holds race test mirrors the booking race. 144/144 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 03:07:29 +00:00
parent 24d4db3f0d
commit 7153e742c8
5 changed files with 331 additions and 66 deletions

View File

@@ -18,7 +18,7 @@ capacity rules, transactional booking, and a flow-driven notification dispatcher
## Status (rolling)
`bash lib/events/conformance.sh`**120/120** (Phase 1 + Phase 2 booking/cancel + persist-backed api)
`bash lib/events/conformance.sh`**144/144** (Phase 1 + Phase 2 booking/cancel/holds + persist-backed api)
## Ground rules
@@ -65,7 +65,8 @@ lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ──
- [x] capacity rules; transactional booking → `persist` (no overbooking)
- [x] wire `booking.sx` into `api.sx` (persist-backed `ev/book-occ!` + derived availability)
- [x] cancellation (tombstone events) + seat release
- [ ] paid tickets compose with `commerce` order flow
- [x] provisional holds (hold/confirm/release) — reserve a seat during pending payment
- [ ] 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)
@@ -81,6 +82,15 @@ lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ──
## Progress log
- 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
pending payment cannot be oversold. `ev/hold!` (capacity-safe, retrying),
`ev/confirm!` (held→confirmed), `ev/release!` (frees a held seat only),
`ev/seat-state`. Seat-acquiring writes (:booking/:hold) go through
append-expect; seat-freeing writes (:cancel/:release) and :confirm append
directly (never oversell). Holds race test mirrors the booking race. +24
tests, 144/144 green. Next: ticket.sx contract module over holds.
- 2026-06-07 — Wired `booking.sx` into `api.sx`: durable persist-backed booking
path alongside the in-memory one. `ev/book-occ!`, `ev/cancel-occ!`,
`ev/roster-occ`, `ev/seats-left-occ` (capacity from the scheduled event);