diff --git a/plans/abstractions.md b/plans/abstractions.md index 7a9a6c1b..4349e41f 100644 --- a/plans/abstractions.md +++ b/plans/abstractions.md @@ -12,7 +12,13 @@ Anything short → _Watching_ (what's missing) or _Rejected_ (why). ## Last scan -- **Date:** 2026-06-07 (radar loop, pass 22) +- **Date:** 2026-06-07 (radar loop, pass 23) +- **Pass 23 — trigger fired (empty streak ends at 19–22).** commerce recorded a Phase 3 + **flow-integration design** (order saga as a flow-on-sx flow, payment suspended until + webhook resume) → 2nd durable-flow consumer; **W8 broadened** from "delivery" to + "externally-resumed orchestration on lib/flow." events made its federation transport + **fed-sx-ready** (injected) → reinforces W1's 5/5 inject-fed-sx seam. acl left tmux + (now fully quiescent). host-persist adapter still not landed (W4 migration still gated). - **Empty-discovery streak: passes 19–22** (last verified pass 22). Fleet at steady state — active loops (content CvRDT, events recurrence/reschedule, identity grant-mgmt, fed-sx outbox internals) are building *inside* their domains, not cross-cutting infra. Census @@ -370,20 +376,25 @@ one merged file copied N times. Correct one-liner: --- -### W8 · Durable outbound delivery (at-least-once + idempotency + retry) -- **Live exemplar on `lib/flow`:** `events/lib/events/notify.sx` — reminders/digests are - durable `flow`s: a flow `request`s delivery (suspend point), the **host** performs the - send via an injected `dispatch` transport, then resumes with the outcome; flow's - deterministic replay means a completed delivery never re-runs on recovery. At-least-once - with an idempotency key per message. This is "reliable delivery" done right on the flow - substrate. -- **Others roll their own:** `fed-sx` built its own outbox + `delivery_worker` + retry - bookkeeping (Steps 8a–d); `mod/fed.sx` has an in-memory outbox seam; `acl/federation` - propagates facts. Same *goal* (reliable outbound delivery, retry/idempotency) on - different machinery. -- **Disposition:** durable delivery is exactly what `lib/flow` is *for* (events proves - it). Watch whether fed-sx / mod converge their outbox onto flow, or stay bespoke for - perf/substrate reasons. 1 clean flow-based consumer today → Watching, not a proposal. +### W8 · Durable externally-resumed orchestration on `lib/flow` (suspend→host-IO→resume) +- **The shared shape:** a durable `flow` that `request`s an external action (a suspend + point), the **host** performs the IO, then `flow/resume`s the flow with the outcome; + flow's deterministic replay means a completed step never re-runs on recovery. +- **Consumers (pass 23): 1 live + 1 designed.** + - `events/lib/events/notify.sx` (**live**) — reminders/digests as durable flows; + suspend on delivery `dispatch`, resume with send outcome. At-least-once + idempotency key. + - `commerce` Phase 3 (**designed**, `commerce/plans/commerce-on-sx.md`) — order saga + `(defflow ordf … (request 'reserve oid) … )`: reserve→pay→fulfil as a flow, **payment + stays suspended until the payment webhook calls `flow/resume`**. Carries only the + order-id; pure orchestration over `ledger.sx`. + - Both are the *same* pattern: long-running process, external resume (delivery dispatch + vs payment webhook). fed-sx/mod still roll their own outbox (watch for convergence). +- **Disposition:** `lib/flow` IS the abstraction (events proves it, commerce adopts it) → + this is an **adoption** observation like W4, NOT an extraction. Home = `lib/flow`. +- **Flow-onboarding friction (light signal):** commerce's note logs real gotchas adopting + flow — `flow-make-env` returns a large likely-cyclic env (don't print it), env build is + slow (budget ~540s like flow's own suite). If ≥3 subsystems hit the same onboarding + gotchas, that's a signal to smooth `lib/flow`'s adopter API — flow's concern, flagged here. - **Name-collision caveat:** `notify.sx` means two unrelated things — `feed/notify.sx` is a *read-side digest* (group inbox by verb+object), NOT delivery. Do not pair them.