Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 44s
BYMONTHDAY (negative = from end), ordinal BYDAY ({:ord :wd}, last-weekday),
default day-of-month skipping short months. Weekly+monthly share ev-emit-occs.
37/37 green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
4.8 KiB
Markdown
96 lines
4.8 KiB
Markdown
# 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` → **37/37** (Phase 1: calendar recurrence)
|
|
|
|
## 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
|
|
- [x] `calendar.sx` — event facts, RRULE expansion in a window (DAILY/WEEKLY)
|
|
- [x] `calendar.sx` — MONTHLY (bymonthday + nth-weekday byday)
|
|
- [ ] `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
|
|
|
|
- 2026-06-06 — MONTHLY recurrence. `ev-days-in-month`, `ev-add-months`,
|
|
BYMONTHDAY (incl. negative = from month end), ordinal BYDAY (`{:ord N :wd W}`,
|
|
ord<0 = nth-from-last), default day-of-month (skips months too short, e.g.
|
|
day-31 monthly skips Feb/Apr). Refactored weekly+monthly onto a shared
|
|
`ev-emit-occs` per-period emitter. 37/37 green (+13).
|
|
- 2026-06-06 — Phase 1 scaffold + calendar recurrence. `calendar.sx`: integer
|
|
epoch-minute datetimes, Hinnant civil<->day-number conversion, DAILY/WEEKLY
|
|
RRULE expansion in a bounded (start,end) window with INTERVAL, COUNT (window-
|
|
independent), UNTIL, BYDAY (weekly). `ev-expand-all` merges + sorts. Wired
|
|
conformance harness (conf + thin wrapper reusing `lib/guest/conformance.sh`),
|
|
scoreboard. 24/24 green. MONTHLY deferred to next commit.
|
|
|
|
## Blockers
|
|
|
|
- None. Substrates present: `lib/datalog` (276/276), `lib/persist`, `lib/flow`
|
|
all exist — Phase 2/3 unblocked when reached.
|