diff --git a/plans/abstractions.md b/plans/abstractions.md index 31524a22..d60fb281 100644 --- a/plans/abstractions.md +++ b/plans/abstractions.md @@ -12,6 +12,14 @@ Anything short → _Watching_ (what's missing) or _Rejected_ (why). ## Last scan +- **Date:** 2026-06-07 (radar loop, pass 24) +- **Pass 24 — three real updates.** (1) **A1 → 7 adopters** (search migrated, counters mode + — corrects the earlier exclusion). (2) The dedicated `conformance` loop ran its 1st + iteration: refused to force-migrate common-lisp (parity gate worked) and surfaced a + **driver feature-gap** (per-suite counters + preloads) gating the complex multi-suite + candidates → A1 now splits simple-now vs gated-on-driver-enhancement. (3) **W8 commerce + is LIVE** ("order lifecycle as a durable flow-on-sx flow, Phase 3 done") → 2 live flow + consumers. events shipped TZ/DST; mod reverted its extraction note (declined on re-read). - **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 @@ -209,9 +217,10 @@ one merged file copied N times. Correct one-liner: and classifies pass/fail/timeout — it does not run SX `deftest` suites with a counter/dict scoreboard, so the shared driver does not fit. Excluded, not pending. - **Remaining hand-rolled candidates (~120–220 lines each):** `common-lisp, erlang, - feed, forth, go, js, ocaml, smalltalk, tcl` — each its OWN loop's migration when - quiescent. (`search` + `lua` excluded: different harness shapes — search assembles a - Haskell source string, lua walks real `*.lua` files.) + feed, forth, go, js, ocaml, smalltalk, tcl` — now being worked by the dedicated + `conformance` loop (above). (`lua` excluded: walks real `*.lua` files via Python. + `smalltalk` likely excludes too — runs `*.st` via its own `test.sh`. `search` was + thought to be excluded but DID migrate via counters mode — see the 7-adopter note.) - **Action:** each remaining subsystem's OWN loop migrates when quiescent — add a `conformance.conf` (+ a `test-harness.sx` preload defining its counters) and replace `conformance.sh` with the 1-line exec shim @@ -219,14 +228,25 @@ one merged file copied N times. Correct one-liner: `lib/haskell/conformance.conf` (counters) or `lib/prolog/conformance.conf` (dict). Keep the `bash lib/X/conformance.sh` entry point so no loop is disrupted. - **Priority: HIGH** (15 consumers, low risk, interface-preserving, additive). +- **7 adopters now** (pass 24): acl, apl, datalog, haskell, mod, prolog, **+ search** + (3-line shim, `MODE=counters`). *Corrects the earlier "search excluded" note* — search + assembles Haskell source but its suites emit pass/fail counters, so counters mode fits. - **NOW IN PROGRESS — dedicated loop (2026-06-07).** A human-triggered `conformance` loop (worktree `/root/rose-ash-loops/conformance`, branch `loops/conformance`, tmux session `a1-conformance`, briefing `plans/agent-briefings/conformance-loop.md`) is working the remaining candidates (common-lisp, erlang, feed, forth, go, js, ocaml, smalltalk, tcl) one per iteration, **classify-then-migrate-or-exclude with a hard test-count parity gate** - (reverts on any mismatch; never pushes to main/architecture). Some candidates may be - *excluded* as foreign-runner harnesses (like lua/smalltalk) rather than migrated — that - is the correct outcome, not a failure. Radar tracks; the conformance loop implements. + (reverts on any mismatch; never pushes to main/architecture). Radar tracks; it implements. +- **Driver-capability boundary found (pass 24, first iteration).** The loop did NOT + force-migrate `common-lisp` (baseline 305/0 across 12 suites) — the shared driver can't + reproduce it: `MODE=counters` supports only ONE global pass/fail counter pair + ONE fixed + preload set, but common-lisp needs **per-suite counter names** (8 distinct pairs) and + **per-suite preload chains**. It logged a precise blocker + unblock path (extend the + `SUITES` entry format with optional per-suite counters/preloads) and moved on. So A1 + splits: **simple single-counter/single-preload suites migrate now; complex multi-suite + ones are gated on a `lib/guest/conformance` driver enhancement** — that enhancement is + itself consumer-gated work owned by `lib/guest`'s loop, NOT something the migration loop + changes unilaterally. The parity gate working as intended (refused a coverage-losing migration). --- @@ -388,15 +408,16 @@ one merged file copied N times. Correct one-liner: - **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.** +- **Consumers (pass 24): 2 LIVE** (events delivery, commerce order saga). - `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). + - `commerce` (**LIVE** as of pass 24 — "order lifecycle as a durable flow-on-sx flow, + 21 tests, Phase 3 done") — 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`. + - **Now 2 LIVE consumers** of the *same* pattern: long-running process, external resume + (delivery dispatch vs payment webhook). fed-sx/mod still roll their own outbox (watch + for convergence). Strengthens "lib/flow is the home"; still adoption, not extraction. - **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