# events-on-sx: Calendar, ticketing & notification delivery on Datalog

> **DRAFT outline.** The events vertical + the shared notification-delivery edge.
> Depends on `persist-on-sx` (bookings ledger) and `flow-on-sx` (reminders, retrying
> delivery). Pairs with `commerce-on-sx` for paid tickets.

rose-ash's `events` domain is calendar + ticketing: recurring events, availability,
capacity, bookings. Scheduling is constraint reasoning — "is this slot free given
recurrence, capacity, and the attendee's other bookings?" — which is rule
evaluation over facts. Datalog expresses availability, recurrence expansion, and
capacity as rules; a booking is a transaction; reminders and digests are durable
`flow`s. Notification *delivery* (email/push) — needed here and by `feed/notify` —
is folded in as an injected transport, extractable later.

End-state: a Datalog-on-SX events layer with recurrence expansion, availability +
capacity rules, transactional booking, and a flow-driven notification dispatcher
(reminders, digests, retries) over an injected transport.

## Status (rolling)

`bash lib/events/conformance.sh` → **0/0** (not yet started)

## Ground rules

- **Scope:** only `lib/events/**` and `plans/events-on-sx.md`. May **import** from
  `lib/datalog/`, and (once they exist) `lib/persist/` + `lib/flow/`. Do not edit
  substrates.
- **Architecture:** events/availability/capacity are Datalog facts + rules;
  recurrence expands to occurrence facts within a window; a booking checks rules
  then appends a `persist` event (idempotent, capacity-safe). Notifications are flows
  that suspend on transport IO and retry on failure.
- **Determinism:** recurrence expansion + availability must be reproducible for a
  fixed window + ruleset; capacity checks must be race-safe (no overbooking).
- **Commits:** one feature per commit. Progress log + tick boxes.

## Architecture sketch

```
Event + booking                         Result
  event(id,start,rrule,capacity)          {:booked | :full | :conflict} + reminders
        │                                       ▲
        ▼                                       │
lib/events/calendar.sx                  lib/events/availability.sx
  — event facts, recurrence (RRULE)       — free/busy + capacity rules (Datalog)
  — expand occurrences in window                │
        │                                       ▲
        ▼                                       │
lib/events/booking.sx                   lib/events/notify.sx   (flow)
  — transactional, capacity-safe          — reminders / digests, retry on fail
  — bookings → persist ledger               — injected transport (email/push)
        │                                       │
        ▼                                       ▼
lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ──────┘
```

## Phase 1 — Calendar + recurrence
- [ ] `calendar.sx` — event facts, RRULE expansion in a window
- [ ] `availability.sx` — free/busy rules
- [ ] `api.sx` + tests + scoreboard + conformance.sh

## Phase 2 — Ticketing + booking
- [ ] capacity rules; transactional booking → `persist` (no overbooking)
- [ ] paid tickets compose with `commerce` order flow
- [ ] tests: capacity edge, double-book guard, conflict detection

## Phase 3 — Notification delivery (flow)
- [ ] `notify.sx` — reminder/digest flows over injected transport
- [ ] retry/backoff on transport failure (flow suspend/resume)
- [ ] tests: delivery success, retry path, idempotent re-send
- [ ] NOTE: shared with `feed/notify` — candidate for later extraction to a
  `delivery-on-sx` once a second consumer is real

## Phase 4 — Federation
- [ ] cross-instance events (peer calendar) — trust-gated stub
- [ ] tests: federated agenda merge

## Progress log
(loop fills this in)

## Blockers
(loop fills this in)
