Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 KiB
Abstraction Radar — backlog
Maintained by the read-only radar loop (see plans/agent-briefings/radar-loop.md).
Detection only — implementation is a separate, coordinated step owned by the
relevant subsystem loop, never by radar.
AHA gate to reach Proposed: ≥3 real consumers · all past Phase 2 & API-stable · structurally identical (file:line evidence) · a natural home (usually NOT lib/guest). Anything short → Watching (what's missing) or Rejected (why).
Last scan
- Date: 2026-06-07 (radar loop, pass 32)
- Pass 32 — A1 DONE.
loops/conformancemerged to architecture (db76cc8c); 13 adopters now on the shared driver; radar spot-checked common-lisp = 487/487 green post-merge → coordination flag CLEARED. A1 moved to a new Done section. New nascent subsystemsdream+maude(0 files),fed-primsresumed (mutex-deadlock fix). The idlea1-conformanceloop can be retired (worklist complete). - Date: 2026-06-07 (radar loop, pass 31)
- Pass 31 — A1 conformance loop WORKLIST COMPLETE. tcl excluded (foreign
*.tcl); final: 4 migrated (common-lisp/erlang/feed/go) + 5 excluded (forth/js/ocaml/smalltalk/tcl). A1 = 12 on shared driver + 6 excluded; only the parity-gated merge to architecture remains. commerce shipped a refund saga on flow (2nd flow use) + finished Phase 5 → going quiescent. relations building graph algos (all-paths) — still unconsumed (W9 unchanged). - Date: 2026-06-07 (radar loop, pass 30)
- Pass 30: conformance loop near done —
ocaml+smalltalkexcluded (both foreigntest.sh/corpus runners, as predicted). Tally: 4 migrated, 4 excluded, tcl only left. Next A1 milestone = theloops/conformance→architecture merge under adopter-parity. No new candidate; relations/artdag steady (no new W9 delegation). - Date: 2026-06-07 (radar loop, pass 29)
- Pass 29: conformance loop excluded
js(test262 fixtures) → 4 migrated + 2 excluded, 3 remain (ocaml/smalltalk/tcl). New subsystems advancing fast:relations→ Phase 4 federation,artdag→ Phase 6 federation → both fold into W1 (now 7 federation modules, theme-not-shape holds) and W9 (relations past Phase 2 but not yet consumed by anyone). - Date: 2026-06-07 (radar loop, pass 28)
- Pass 28 — fleet expanding again. Conformance loop:
gomigrated 609/609;forthexcluded (foreign Forth corpus — classify-then-exclude working). 4 migrated +1 excluded on the branch; js/ocaml/smalltalk/tcl remain. 2 new subsystems:relations(Phase 1, parent/child rel facts → new W9 nascent watch) andartdag(nascent, 0 files).eventsMERGED to architecture (its persist+flow adoption now integrated — W4/W8 landed). Briefing commit hints more incoming:dream,host, +5 language chisels. - Date: 2026-06-07 (radar loop, passes 26–27)
- Passes 26–27 (routine tracking): conformance loop steady at ~1 migration/iteration — erlang 761/761, then feed 189/189. A1 = 8 on architecture + 3 on the branch; 6 remain. W4 still gated (host-persist adapter not landed); no new subsystem; app loops on incremental domain work (commerce Phase 5 payment envelope, content/events/identity/fed-sx). Nothing new to discover; merge-time adopter-parity flag still open.
- Date: 2026-06-07 (radar loop, pass 25)
- Pass 25: A1 → 8 adopters (events via its own loop) + common-lisp 487/487 on the
conformance branch. The conformance loop extended the shared
lib/guestdriver (per-suite counters/preloads) to do it → raised a coordination flag in A1: verify the branch is non-regressive against all 8 adopters before merging to architecture. commerce drafting Phase 5 provider-neutral payment envelope. No new candidate; A1 advancing fast. - 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
conformanceloop 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 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 exhausted (p17); all gates re-tested (W1 p18, W2 p19). No new candidate clears any gate.
- Radar is now trigger-driven. The next substantive pass needs one of: (a) a new subsystem worktree spawning (auto-joins scan), or (b) host-persist's durable adapter landing → unblocks the W4 acl/mod→persist/log migration, or (c) a quiescent subsystem (acl/mod/search/commerce, static ~9–16 passes) resuming. Polling ~hourly until one fires; will tighten cadence then.
- Date: 2026-06-07 (radar loop, pass 20)
- Pass 20 — honest empty pass. 3 new census recurrences since p17 (normalize/index ×2, query ×3) — all name collisions (same noun, domain-specific op), added to the table. Recorded the meta-pattern: the fleet shares vocabulary, not structure. Most subsystems quiescent (acl/mod/search/commerce static ~9-15 passes = API-stable); only events/ identity/content/fed-sx still committing domain features. No new gate-clearer.
- Date: 2026-06-07 (radar loop, pass 19)
- Pass 19 — honest empty pass. Scanned 10 active subsystems. content/index.sx is a
blog index/tag-cloud listing (presentation, not full-text search — no search reinvention)
and content/multi-doc indexing adds no per-viewer filter. W2 re-tested: still 2
(feed, search) — acl's
permit?-like matches are its own authZ engine (the home), not a downstream read filter. No new candidate cleared any gate. - Date: 2026-06-07 (radar loop, pass 18)
- Pass 18 — W1 gate re-test. events shipped Phase 4 federation (5th consumer): a 5th
divergent merge (sorted agenda +
:originprovenance), trust-gate = runtime list membership (shares mod's mechanism, not acl's). Reinforces W1's "theme not shape" — but the inject-fed-sx-transport seam is now 5/5, strengthening "all are fed-sx consumers-in-waiting." Trust sub-pattern refined: mod+events (runtime set) vs acl (rule). - Date: 2026-06-07 (radar loop, pass 17)
- Pass 17 — filename census declared EXHAUSTED (see the Census-status table above). Examined the last unswept ≥2 recurrences (schema/engine = acl⇄mod substrate twins; catalog/batch = name collisions; store = divergent). No new candidate. Incremental churn elsewhere (content 621/621, identity PAR, events reminders). Future passes pivot from censusing to re-testing gates as consumers mature.
- Date: 2026-06-07 (radar loop, pass 16)
- Pass 16: events started Phase 3 — durable notification delivery on
lib/flow(new W8: at-least-once + idempotency exemplar; fed-sx/mod roll their own outbox). The twonotify.sx(feed vs events) are a name collision (read-side digest vs delivery), noted in W8. Substrate-adoption story deepening: app domains now consume persist (content/ commerce/events), flow (events), commerce (events), acl-authZ (identity). - Date: 2026-06-07 (radar loop, pass 15)
- Pass 15: added the scanning-method note above after
query.sxagain proved to be merged-lib copies (lib/prolog + lib/persist in every worktree). Corrected census surfacedwire×2 (content+mod) → Rejected (shared role, divergent structure: generic SX serializer vs bespoke pipe-format under a Prolog-env string-prim constraint). events↔ commerce integration appeared (paid tickets); acl/mod/search quiescent ~7 passes (now API-stable). No new gate-clearer. - Date: 2026-06-07 (radar loop, pass 14)
- Pass 14: filename census flagged
snapshot×?? — but the*/lib/persist/snapshot.sxcopies are just the mergedlib/persistin each worktree, NOT consumers (same artifact aslib/feed/rank.sxeverywhere). The one distinct file,content/snapshot.sx, reimplements persist's projection-checkpoint on raw KV instead of usingpersist/snapshot→ new W7 (persist-adoption nudge).audit×3 = the W4 fakes (acl/mod/identity), known. - Date: 2026-06-07 (radar loop, pass 13)
- Pass 13 — honest re-test, no gate-clearer. Re-tested the two longest-waiting gates
against the maturing app-domain loops: W2 (per-viewer visibility) still 2 consumers
(feed, search) — commerce/content/events/identity add no per-viewer read filter; W3
(pagination) still 2 (feed, search) —
content/page.sxis an HTML wrapper, not pagination (filename collision, noted in W3). Incremental churn only elsewhere. - Date: 2026-06-07 (radar loop, pass 12)
- Pass 12:
eventsshipped transactional booking on persist (3rd live persist consumer) usingpersist/append-expect(optimistic-concurrency CAS, lock-free capacity safety). W4 ledger now shows a persist feature-ladder append → append-once → append-expect that the hand-rolled fakes can't match. No new candidate; W4 reinforced. - Date: 2026-06-07 (radar loop, pass 11)
- Pass 11 — W4 sharpened with a consumer ledger. commerce built an order ledger on
persist (2nd live exemplar; uses
persist/append-oncefor webhook idempotency) and identity a grant audit ledger (in-memory Erlang fake, gated on an Erlang↔persist bridge). The append-only monotonic-seq event-log pattern is now validated across 4 domains, 2 live on persist + 3 fakes flagged for adoption. See W4 table. - Date: 2026-06-07 (radar loop, pass 10)
- Pass 10: commerce/content/events/identity advancing (content 238/238). Probed a shape outside the routing table — guarded lifecycle state machines (mod/lifecycle + identity/membership) → new W6: shared design principle, divergent structure (SX transition-table vs Erlang gen_server), NOT an extraction target. No gate-clearer.
- Date: 2026-06-07 (radar loop, pass 9)
- Pass 9:
commerce+contentreached Phase 2 (content162/162). Key find:contentbuilt its op log directly onpersist/log(backend-injected, append+replay- to-seq) — the live reference exemplar for W4 (see W4).eventsMONTHLY RRULE,identityOAuth2 auth-code + PKCE, search boolean-filtered ranked. A1 still 6 adopters. - Date: 2026-06-06 (radar loop, pass 8)
- Pass 8 — fleet expanded by 4 app-domain loops (the briefing's anticipated
commerce/identityarrivals, auto-picked up by dynamic discovery). All early-stage, pre-Phase-2 → moving targets, none count toward any gate yet:commerce(Phase 1:api/cart/catalog/price). Its "per-line audit" is a cost breakdown view (api.sx:44), not an append-only decision log → NOT a W4 consumer.events(Phase 1:calendar.sx, RRULE expansion).identity(early:session/token). Defers authZ to acl (token.sx:15) — reinforces W2's "delegatepermit?to acl-on-sx" routing; identity = authN, acl = authZ.content(just-started:block.sx). These are the future consumers W2/W3 are waiting on — re-check their per-viewer filters / pagination once each clears Phase 2. No new gate-clearer this pass.
- Pass 7: A1 jumped 4→6 adopters —
acl+modmigrated to the shared conformance driver (first app-domain adopters; proves it generalizes past substrates).host-persistclosed its blob-adapter blocker (durable storage adapter now landing → W4 migration path opening). search shipped proximity/NEAR; flow + persist quiescent. - Pass 6: new worktree
host-persist(active — building persist's durable host adapter);feedwent quiescent (left tmux). acl shipped hardening (+25), fed-sx-m1 at Step 6c. mod loop independently wrote a shared-plumbing note (mod-on-sx.md,538b8a53) corroborating W4/W5 — folded its claims + home disagreements into W1/W4/W5. No new gate-clearer (audit log still 2 consumers), but consumers are now API-stable. - Pass 5: search (+highlight/snippet) and fed-sx-m1 (+follower_graph) moved; rest
unchanged. Filename census:
api×6,fed×3, thenschema/rank/query/page/explain/ engine/batch/audit×2. Examined the ×6api.sx→ Rejected (shared name, divergent structure incl. implicit-vs-explicit-state contract). rank/batch/engine all ≤2 + substrate/domain-divergent → no new gate-clearer. - Pass 4: no churn vs pass 3 (same worktrees/tmux/HEADs/adopters). Swept audit+explain surfaces: acl/mod share an append-only-log shape (→ sharpened W4 with persist/log API evidence) and a proof-explain shape (→ new W5, substrate-bound). No new gate-clearer.
- Pass 3 (earlier today): subsystem set + tmux + A1 adopters (4) all unchanged vs pass 2. Loops advanced: acl shipped Phase 4 federation; search shipped Phase 4 + pagination; feed shipped pagination/threading; mod at Ext 19 (capstone); persist did a worked acl-grants migration (W4). New shape found: offset/limit pagination → folded into W3.
- Subsystem set discovered: loop worktrees
acl, erlang, fed-prims, fed-sx-m1, feed, flow, go, kernel, mod, ocaml, persist, radar, ruby, search, sx-vm-extensions; main-repolib/*incl. mergedfeed+ substrates (apl, common-lisp, datalog, erlang, forth, go, haskell, hyperscript, js, lua, minikanren, ocaml, prolog, scheme, smalltalk, tcl) +lib/guest. Actively looping (tmux):acl, fed-sx-m1, feed, flow, mod, persist, search(+ radar). - New since pass 1: worktrees
kernel(empty/unset — not yet a repo) andocaml(lib/ocaml/baselineonly). Both early-stage, pre–Phase 2 → out of proposal scope. - Re-enumerate every pass; new loops (e.g. a future
commerce/identity) auto-join.
Census status (pass 17): EXHAUSTED. Every own-namespace filename recurring ≥2× has been examined and dispositioned — further filename-censusing is low-yield until new subsystems/modules appear. Map:
| filename | owners | verdict |
|---|---|---|
api ×10 |
all | Rejected — shared role, divergent state contract |
fed/federation |
feed/search/mod/acl(+content) | W1 — theme not shape |
audit ×3 |
acl/mod/identity | W4 — append-only log → persist/log |
page ×3 |
feed/search (pagination) + content (HTML wrapper) | W3 + collision noted |
explain ×2 |
acl/mod | W5 — proof tree, substrate-bound |
snapshot ×2 |
persist(facet) + content(reinvents) | W7 |
wire ×2 |
content(SX serializer) / mod(pipe-format) | Rejected — divergent |
schema,engine ×2 |
acl/mod | substrate-twin parallels (Datalog vs Prolog); only audit (W4) is liftable |
catalog,batch ×2 |
commerce/persist, mod/persist | name collisions, unrelated |
normalize ×2 |
content(tree-prune)/feed(record-coerce) | name collision (pass 20) |
index ×2 |
content(listing)/search(inverted index) | name collision (pass 20) |
query ×3 |
content(doc-block)/search(bool AST)/persist(stream-read) | 3-way name collision (pass 20) |
store ×2 |
content(on persist) / flow(workflow records) | related concept, divergent |
rank ×2 |
feed/search | different domains (activities vs docs), ≤2 |
| acl⇄mod are structural twins (decision engine over a logic substrate, Datalog vs | ||
| Prolog) — they parallel across engine/schema/explain/audit/fed, but only the audit log | ||
| is substrate-agnostic and liftable (→ W4); the rest are substrate-idiomatic. Next passes: | ||
| re-test gates (W2/W3/W8) as consumers mature, watch new modules — not re-census. |
Meta-pattern (pass 20): new module names keep recurring but the operations keep colliding — same noun, domain-specific op (normalize, index, query, catalog, batch, notify, page, store all proved to be collisions). This is why genuine extraction candidates are rare: the fleet shares vocabulary, not structure. The real shared assets are the substrate subsystems (persist, flow, acl, fed-sx) that app domains adopt (W1/W2/W4/W7/W8), not hand-rolled libs to extract.
Scanning-method note (learned the hard way, passes 5/12/14/15): a filename census
for cross-subsystem recurrence MUST restrict to each subsystem's OWN namespace —
X/lib/X/*.sx — never X/lib/*/. The merged substrate libs (lib/prolog, lib/persist,
lib/feed, lib/datalog, …) are checked out inside every worktree, so a naive census
reports e.g. query.sx/snapshot.sx/rank.sx ×N as phantom recurrences that are really
one merged file copied N times. Correct one-liner:
for w in <subsystems>; do for f in $w/lib/$w/*.sx; do basename $f .sx; done; done | sort | uniq -c | sort -rn.
Done
A1 · Shared conformance driver — ✅ COMPLETE (merged db76cc8c, pass 32)
Full closed loop: radar detected it → dedicated conformance loop implemented it
(classify-then-migrate-or-exclude, hard parity gate) → merged to architecture
(db76cc8c Merge loops/conformance into architecture: A1 conformance-driver migration)
→ radar spot-verified post-merge (common-lisp 487/487 green on architecture — exercises
the new per-suite-counters/preloads driver feature, the riskiest change). Final state:
- 13 on the shared driver: acl, apl, common-lisp, datalog, erlang, events, feed, go, haskell, mod, prolog, relations, search.
- 6 correctly excluded (foreign-program runners — a legitimately different harness): forth, js, ocaml, smalltalk, tcl, lua.
- The shared driver gained per-suite counters + per-suite preloads (backward-compatible); spot-check confirms existing adopters unaffected. Coordination flag CLEARED. Detail of the migration arc retained under the original entry below.
Proposed (cleared the gate)
(empty — A1 graduated to Done, pass 32.)
A1 · Adopt the shared conformance driver across subsystems
- Pattern: every subsystem hand-rolls a near-identical
conformance.sh(epoch-load → eval → scoreboard emit) and an inline<x>-test name got expectedpass/fail counter. - Consumers (≥3, overwhelming): 15
lib/*/conformance.sh—apl, feed, datalog, flow, mod, lua, erlang, forth, go, common-lisp, haskell, js, ocaml, prolog, smalltalk, tcl. - Home:
lib/guest— the one legitimate exception (the shared driverlib/guest/conformance.sh+lib/guest/conformance.sxalready exist; modesdictandcounters). - Status: IN PROGRESS — 6 adopters (pass 7).
prolog(dict),haskell(counters),apl(dict),datalog(dict), andacl(dict) +mod(dict), newly migrated this pass — all 3-line exec shims intolib/guest/conformance.shwith aconformance.conf. acl + mod are the first app-domain adopters (not language substrates) — strong evidence the driver generalizes beyond the substrate layer, which was the open question. Theaplmigration earlier surfaced a latent bug: the old awk extractor under-countedpipeline(40 vs the real 152 assertions); true apl total is 562, not 450 — evidence that adopting the driver also improves correctness. - Not a target (different harness shape):
lua/conformance.shis a Python runner (lib/lua/conformance.py) that walks real*.luasource files vialua-eval-astand classifies pass/fail/timeout — it does not run SXdeftestsuites 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— now being worked by the dedicatedconformanceloop (above). (luaexcluded: walks real*.luafiles via Python.smalltalklikely excludes too — runs*.stvia its owntest.sh.searchwas 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(+ atest-harness.sxpreload defining its counters) and replaceconformance.shwith the 1-line exec shim (exec bash …/guest/conformance.sh …/conformance.conf "$@"). Recipe template:lib/haskell/conformance.conf(counters) orlib/prolog/conformance.conf(dict). Keep thebash lib/X/conformance.shentry point so no loop is disrupted. - Priority: HIGH (15 consumers, low risk, interface-preserving, additive).
- 8 adopters on architecture (pass 25): acl, apl, datalog, events, haskell, mod,
prolog, search —
eventsmigrated via its OWN loop;searchvia counters mode (which corrects the earlier "search excluded" note). +4 on theloops/conformancebranch:common-lisp487/487,erlang761/761,feed189/189,go609/609 — pending merge. 5 EXCLUDED — all foreign-runner harnesses (correctly, not force-migrated):forth(Hayes core.fr via awk+python),js(test262.js/.expected),ocaml(scrapestest.sh+.mlbaseline),smalltalk(scrapestest.sh+*.stcorpus),tcl(foreign*.tclvs# expected:annotations). - ✅ CONFORMANCE LOOP WORKLIST COMPLETE (pass 31). Final A1 picture:
- 12 on the shared driver: acl, apl, datalog, events, haskell, mod, prolog, search
(on architecture) + common-lisp, erlang, feed, go (on
loops/conformance, pending merge). - 6 correctly excluded (foreign-program runners — testing a language impl against an external corpus is legitimately a different harness): forth, js, ocaml, smalltalk, tcl, lua.
- Honest finding: the driver's reach is narrower than the raw "15 conformance.sh"
count implied — language substrates that run real
.lua/.st/.ml/.tcl/.js/.frprograms should keep their foreign runners. ~half migrate, ~half don't, and that's correct. - One step left: merge
loops/conformance→ architecture under the adopter-parity check (the coordination flag above — the sharedlib/guestdriver change must be proven non-regressive against all existing adopters first). The loop is now idle.
- 12 on the shared driver: acl, apl, datalog, events, haskell, mod, prolog, search
(on architecture) + common-lisp, erlang, feed, go (on
- NOW IN PROGRESS — dedicated loop (2026-06-07). A human-triggered
conformanceloop (worktree/root/rose-ash-loops/conformance, branchloops/conformance, tmux sessiona1-conformance, briefingplans/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). 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=counterssupports 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 theSUITESentry format with optional per-suite counters/preloads) and moved on. - Driver gap RESOLVED next iteration (pass 25) — but it touched the shared driver. The
loop extended
lib/guest/conformance.sh(+38 lines: optional per-suite counters + per-suite preloads in theSUITESformat, backward-compatible) and then migrated common-lisp at 487/487 (above the 305 baseline — likely another extractor under-count correction, à la apl'spipeline). The parity gate held throughout. - ⚠ COORDINATION FLAG (radar): the
loops/conformancebranch now carries a change to the SHAREDlib/guestdriver used by all 8 adopters. It's additive by design, but before this branch merges toarchitecture, re-run the existing adopters' suites under the new driver to confirm zero regression (acl/apl/datalog/events/haskell/mod/prolog/search). This is the one cross-cutting risk in an otherwise per-subsystem-isolated effort — surfaced here so the merge is gated on adopter-parity, not assumed.
Watching (real but not yet through the gate)
W1 · Federation scaffold (merge / ingest / backfill / trust-gate)
-
FAILS the structural-identity gate (deep-dived 2026-06-06, all 4 read). Consumer count is met (4) but they are superficially similar, not structurally identical — the federated unit and merge op differ fundamentally:
Subsystem (file) Federated unit Merge op Trust gate Injected transport feed ( fed.sx:14,18,40)activity streams dedupe by (actor verb object)none (visibility via permit?separately)send-fn,fetch-fnsearch ( fed.sx:8)inverted indices relabel DocId peer*1000+local+ union posting listsnone none (pure merge fn) mod ( fed.sx:11-14,99)moderation decisions advisory-list vs applied-list; bind iff mod/trusted?yes — runtime list mod/trusted? peer scopemock outbox / fed-send!acl ( federation.sx:43,56)Datalog delegate facts pull facts, gate by trust/level_coversrule, re-saturateyes — Datalog rule at query time transportdictevents ( federation.sx)calendar agendas fold trusted peers' agendas into one sorted agenda + :originprovenanceyes — runtime list ev/trusts?(peer-id ∈ trust-set)injected behind ev/peer-agenda -
The ONLY real commonality is the injection seam (now 5/5, pass 18), not extractable code: every one says "the real transport is
fed-sx's job; injectsend-fn/fetch-fn/transport/peer-agendaand mock it in tests." That is an architectural convention the fleet already follows. The merge op diverges 5 ways (dedupe / index-union / advisory / fact-saturation / agenda-sort). The trust gate, where present, splits: mod + events use a runtime trust-set membership check; acl uses a declarative Datalog rule — so even the trust sub-pattern is 2-of-3, and the membership check is a trivial one-liner (below the extraction threshold). No shared merge, no single shared trust mechanism. -
Disposition: do NOT extract a shared "federation lib." When
fed-sxships its real transport, these 4 become its consumers (wiringsend-fn/fetch-fn/transportto it) — that work belongs to each subsystem's loop + thefed-sxloop, not a cross-cutting extraction. Stop re-proposing on the shared name. Home:fed-sx. -
Now 7 federation modules (pass 29): +
relations(Phase 4: erel trust-gating, peer_rel/trust, fed-sx mock transport — Datalog-rule trust like acl) andartdag(Phase 6: content-addressed cache + trust + invalidation — a merge shape unlike any other). Each new one reinforces "theme not shape": 7 divergent merges, all sharing only the inject-fed-sx-transport seam. Verdict unchanged — they're fed-sx consumers-in-waiting. -
Narrower sub-claim (mod note, pass 6; refined pass 18): mod asserts the fed trust/outbox shape shares between mod+acl. Radar evidence refines this: the trust gate splits by mechanism, not by subsystem pair — mod + events both use a runtime trust-set membership check (
mod/trusted?,ev/trusts?), while acl uses a Datalog rule. So a "trust-set membership" helper has 2 consumers (mod, events) — but it's a one-linemember?and the merge it gates diverges, so still not worth extracting. Resolve at the architecture-merge point if a heavier shared trust-set surface emerges.
W2 · Per-viewer visibility / permission filter
- 2 shipped consumers, same shape —
filter <injected-permit> <ranked/candidate stream>:feed/lib/feed/acl.sx:27feed/visible = (feed/filter stream (fn (a) (permit? viewer a))), capstone at:34(stream → ACL → rank → top-N).permit?injected, sig(viewer activity)→bool.search/lib/search/fed.sx:16aclFilter permit docs = filter permit docs;topNTfIdfAcl n permit ts idx = take n (aclFilter permit (rankTfIdf ts idx)).permitinjected, sigDocId→Bool(viewer baked in by caller).
- NOT a consumer:
mod/lib/mod/policy.sxis moderation policy (reviewer actions), no per-viewer read filter. So mod won't be the 3rd. - Missing: (a) only 2 consumers, need ≥3; (b) the two interfaces diverge —
feed passes
(viewer, item), search bakes the viewer in — so any shared form must pick a convention; (c) both already inject the predicate, and the filter body is literally one line (filter permit xs). Leaning toward: the predicate's home isacl-on-sx(permit?), and the one-line filter is too thin to extract. - Home when ripe: delegate
permit?toacl-on-sx; do NOT extract the filter. Re-check if a 3rd genuine per-viewer read filter ships (e.g. events/commerce).
W3 · Collection helpers (group-by, dedupe-by-key, stable top-N, distinct-order, offset/limit page)
- feed built all of these on APL primitives. search/commerce/events will want group-by / top-N.
- NEW (2026-06-06): offset/limit pagination shipped in 2 subsystems, identical shape
take limit (drop offset xs):feed/lib/feed/page.sx:9feed/page(offset/limit window over a stream).search/lib/search/page.sx:9paginate off lim docs = take lim (drop off docs).- NOT a 3rd:
persist/lib/persist/query.sx:5has a since-cursor for incremental log consumption — resumable-stream semantics, not result windowing. Different shape. - feed also has cursor-by-
:atrecency pagination (page.sx:21-44); search has no cursor. So only the plain offset/limit window is shared, and it is a literal 1-liner.
- Missing: ≥3 stable consumers; AND every item here is collection math that belongs
in the substrate (APL/Haskell already expose grade/sort/unique/take/drop), not a
shared lib. A 1-line
take/dropwindow is far below the extraction threshold. Watch; revisit only if a non-substrate subsystem needs the same windowing without take/drop. - Filename-collision caution (pass 13):
content/lib/content/page.sxis an HTML page wrapper (full HTML5 doc), NOT pagination — do not count it as a 3rd pagination consumer.page.sxnow means two unrelated things across the fleet. Re-tested pass 13: pagination still only feed + search (2).
W4 · In-memory store fakes → persist-on-sx
-
Not an abstraction to extract — a migration target. Every subsystem fakes its store with a mutable list (
feed/-log, flow store, mod audit, …). -
Owner:
persist-on-sx(in progress). Tracked there, listed here for visibility. -
Concrete instance (file:line, found pass 4): the append-only decision/audit log.
acl/lib/acl/audit.sxandmod/lib/mod/audit.sxare the SAME hand-rolled shape, andpersist/lib/persist/log.sx(the persist log facet) already implements it durably:role acl/audit.sx mod/audit.sx persist/log.sx (target) log var acl-audit-log:9mod/*audit-log*:10backend stream monotonic seq acl-audit-seq:10mod/*audit-seq*:11per-stream high-water :1 append (auto-seq) acl-audit-decide!commit :32 persist/append:17count acl-audit-count:51mod/audit-count:44persist/count:12read-all oldest-first snapshot/tail :73 mod/audit-all:43persist/read:29read seq≥from — by-seq persist/read-from:31Both deliberately use a monotonic seq with no wall-clock (deterministic/testable) — identical to persist/log's design. Action when persist's host adapter lands: acl + mod loops swap their in-memory log for
persist/log. 2 consumers today; not a new lib — the home already exists. Belongs to acl/mod loops × persist loop, not an extraction. -
Cross-loop corroboration (pass 6): the mod loop independently reached the same conclusion —
mod/plans/mod-on-sx.md(commit538b8a53): "mod-sx (Prolog) and acl-sx (Datalog) converged on the same module shape … only the audit log + fed trust/outbox shapes truly share; extract at the architecture-merge point, refactoring both consumers atomically, not unilaterally from a loop branch." Confirms the shape AND the do-not-extract-unilaterally stance. -
Home disagreement to resolve at merge: mod's note proposes lifting the audit-log primitives into
lib/guest/. Radar routing disagrees: a durable append-only log is apersist-on-sxconcern (the log facet already exists), not language-impl plumbing. Hold the line —lib/guestis lexer/parser/AST/HM/test-runner, not an event log. -
Migration is becoming concrete: new
host-persistloop (worktree + tmux, pass 6) is building the durable-storage host adapter persist was blocked on — once it lands, acl/mod can actually swap topersist/log. -
LIVE REFERENCE EXEMPLAR (pass 9):
contentalready does it right.content(Phase 2 complete, 162/162) built its op log directly onpersist/loginstead of faking it —content/lib/content/store.sx: backend injected via(persist/open)("content knows nothing about which backend", :10); append op as eventpersist/append b (content/-stream doc-id) …(:20); readpersist/read(:36);persist/last-seq(:47); version = replay op stream up to a seq (filterpersist/event-seq ev <= seq, :61). "The op log is the source of truth … the materialised doc is a cache, never primary state." This proves the W4 target is real, not hypothetical: acl + mod's hand-rolled monotonic-seq logs should adopt exactly content'spersist/logpattern. -
Consumer ledger of the append-only monotonic-seq event log (pass 11):
consumer what backing note content ( store.sx)doc op log persist/log ✓ live plain append + replay-to-seq commerce ( ledger.sx)order ledger persist/log ✓ live persist/append-once— idempotent, webhook-replay-safe :40,58events ( booking.sx)booking roster persist/log ✓ live persist/append-expect— optimistic-concurrency CAS, capacity-safe, lock-freeacl ( audit.sx)decision log in-memory fake (SX) migrate directly when host adapter lands mod ( audit.sx)decision log in-memory fake (SX) migrate directly identity ( audit.sx)grant ledger in-memory fake (Erlang) {Seq,Subject,Action}; needs an Erlang↔persist bridge first — author scoped it out until persist lands ("queryable semantics identical") -
Two takeaways: (1) the pattern is validated across domains — CRDT doc ops, financial orders, event bookings, rule decisions, OAuth grants all reduce to the same append-only monotonic-seq stream; (2) migrating to
persist/logis strictly better than the fakes — persist exposes a feature ladder the fakes don't have:append(content) →append-once/idempotency (commerce) →append-expect/optimistic- concurrency (events). Every fake would have to reinvent a weaker version of these. This is an adoption item (the home already exists), NOT a new extraction — owned by persist/host-persist × each consumer loop. The SX fakes (acl, mod) migrate directly; the Erlang fake (identity) is gated on an Erlang↔persist bridge.
W5 · Proof-tree explanation over a logic-program derivation
acl/lib/acl/explain.sx(reconstructs a canonical proof by goal-directed search over a saturated Datalog db) andmod/lib/mod/explain.sx(renders a Prolog-style proof tree goal-by-goal with proved/unproved marks + unification bindings) are the same idea.- Missing / disposition: only 2 consumers, and they sit on different substrates
(acl→
lib/datalog, mod→lib/prolog). Proof reconstruction/rendering is logic-engine machinery → it belongs in each substrate (datalog/prolog), not a shared app lib. Watch; revisit only if a 3rd logic-backed subsystem reimplements proof explanation. - Cross-loop note (pass 6): mod's note calls
mod/proof-goals(re-query-each-goal) generic and proposes lifting it intolib/guest/. Radar caveat: proof-tree reconstruction is engine-agnostic logic machinery, butlib/guestis for lexer/parser/AST/HM/match/test-runner — a logic-engine proof helper is a poor fit there. If genuinely shared by ≥3 engines, alib/logic-style substrate helper is the better home thanlib/guest. Still 2 consumers → stays Watching either way.
W9 · Parent/child relationship tracking → the new relations subsystem (nascent)
- New subsystem (pass 28):
relations(loops/relations, Phase 1 —schema.sx+api.sx, rel facts +relate/unrelate/children/parents/related, 22 tests). Per CLAUDE.md it's the canonical "cross-domain parent/child relationship tracking." - Why watch: several subsystems already track parent/child locally — feed reply-to
threading (
thread/replies), content nested block trees, events occurrence/RECURRENCE-ID links. Ifrelationsbecomes the shared home, those are candidate delegators (like acl=authZ, persist=log). But it's Phase 1, pre-Phase-2, moving target — and each local impl is currently domain-specific (different keys/semantics). Do NOT propose yet. Re-check when relations is past Phase 2 AND ≥3 subsystems' relationship logic could genuinely delegate to it.artdagalso just spawned (nascent, 0 files) — tracking only. (pass 32:dream+maudealso spawned, nascent 0-files;fed-primsresumed.) - Update pass 29: relations rocketed to Phase 4 (one gate — past Phase 2 — now met), but it's building ITSELF out (schema/federation), not yet being consumed by anyone. The blocker is the other gate: 0 subsystems currently delegate their parent/child logic to it (feed/content/events still track locally). Watch for the first real delegation. (artdag also raced to Phase 6 — these ports advance fast; treat committed state as truth.)
W8 · Durable externally-resumed orchestration on lib/flow (suspend→host-IO→resume)
- The shared shape: a durable
flowthatrequests an external action (a suspend point), the host performs the IO, thenflow/resumes the flow with the outcome; flow's deterministic replay means a completed step never re-runs on recovery. - Consumers (pass 24): 2 LIVE (events delivery, commerce order saga).
events/lib/events/notify.sx(live) — reminders/digests as durable flows; suspend on deliverydispatch, resume with send outcome. At-least-once + idempotency key.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 callsflow/resume. Carries only the order-id; pure orchestration overledger.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/flowIS 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-envreturns 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 smoothlib/flow's adopter API — flow's concern, flagged here. - Name-collision caveat:
notify.sxmeans two unrelated things —feed/notify.sxis a read-side digest (group inbox by verb+object), NOT delivery. Do not pair them.
W7 · Snapshot/projection-checkpoint reimplemented vs persist/snapshot (delegate)
persist/lib/persist/snapshot.sxalready provides a generic projection checkpoint: store{:value :seq}in the kv facet under a namespaced key; the headline property is snapshot + tail == full replay (pure, clock-free).content/lib/content/snapshot.sxreimplements that same pattern on raw persist KV rather than delegating:persist/kv-put b (content/-snap-key doc-id) {:doc … :seq seq}(:20),persist/kv-has?/kv-get(:27-28), and its own tail-replay (:53-59). It never callspersist/snapshot-*. content's doc-materialisation is a projection fold over its op stream — exactly whatpersist/snapshotcheckpoints generically.- Disposition: persist-adoption nudge (like W4): content could delegate to
persist/snapshot(its projection = "fold ops → doc"), dropping the duplicated KV+replay code. Home already exists → NOT an extraction; owned by content × persist loops. Only 1 reinventor today; watch whether commerce/events/identity also hand-roll a snapshot on raw KV instead of using the facet (would strengthen the nudge). NB timeline: unclear ifpersist/snapshotpredated content's — flag, don't blame.
W6 · Guarded lifecycle state machine (illegal transition = explicit error)
- Recurs as a design principle, NOT a shared structure (found pass 10):
mod/lib/mod/lifecycle.sx— pure SX: immutable case{:state :error :history …}, explicit transition tablemod/lc-transitions(:31), illegal transition returns the case unchanged with:errorset. States open→triaged→decided→appealed→final.identity/lib/identity/membership.sx— an Erlanggen_serverfragment (identity runs on erlang-on-sx): areceiveloop withcase find(...) of … {error, St}guards. States none→pending→active→lapsed→revoked.
- Both share the guideline ("invalid transitions are explicit errors, never silent
no-ops") but implement it substrate-idiomatically — SX transition-table over
immutable values vs an Erlang process loop with per-message case guards. Same W1/
api.sxtrap: shared idea, divergent structure. - Disposition: not an extraction target — the FSM mechanism is ~10 substrate-specific lines; the value is in each domain's state graph, not the plumbing. At most a design guideline ("model lifecycle as a guarded FSM with explicit-error transitions"). Watch whether commerce-checkout / events-booking add their own — if so it confirms the guideline, still not a lib. Do not propose extracting a shared state-machine lib.
Rejected (considered, declined — do not re-propose)
- "Continuous auto-implementing abstractor loop." Rejected at design time: an
agent writing across
lib/<x>/**breaks the worktree isolation that makes the fleet safe, and is rewarded for manufacturing premature/wrong abstractions. The radar is read-only by design. (This file is the alternative.) - Shared
api.sx"public boundary" module (×6). Rejected pass 4-5: every subsystem has anapi.sx(acl, feed, flow, mod, persist, search — a 100% filename match), but it is a naming convention for the public entry point, not a shared structure. They disagree on the most basic contract: acl/feed use implicit module state (acl/api.sx"implicit current db",feed/api.sx"single mutable log") whilepersist/api.sxthreads an explicit backend as every call's first arg; flow's api builds a Scheme env, search's api concatenates a Haskell source string, mod's is a lifecycle state-machine façade (17 defs vs persist's 1). Same role, no common shape — the W1 coincidental-resemblance trap. Do not re-propose on the filename. - Shared
wire.sx"serialization" module (×2). Rejected pass 15: content + mod both have awire.sx, butcontent/wire.sxuses the generic SX serializer (serialize/parse, full-fidelity round-trip) whilemod/wire.sxis a bespoke versioned pipe-delimited line (subset of fields,splithand-built over slice/len because mod's Prolog-loaded env strips string prims). Shared role (wire format), divergent structure + substrate constraint → not a candidate; the SX serializer is already the shared tool for SX-substrate subsystems, and mod can't use it. (Same family as theapi.sxrejection above.) - Dumping app-domain plumbing into
lib/guest. Rejected:lib/guestis for language-implementation plumbing. App patterns route to acl/fed-sx/persist/ substrate/host instead (see the routing rule in the briefing).