Design + ops scaffolding for the next phase of work, none of it touching
substrate or guest code.
lib-guest.md: rewrites Architectural framing as a 5-layer stack
(substrate → lib/guest → languages → shared/ → applications),
recursive dependency-direction rule, scaled two-consumer rule. Adds
Phase B (long-running stratification) with sub-layer matrix
(core/typed/relational/effects/layout/lazy/oo), language profiles, and
the long-running-discipline section. Preserves existing Phase A
progress log and rules.
ocaml-on-sx.md: scope reduced to substrate validation + HM + reference
oracle. Phases 1-5 + minimal stdlib slice + vendored testsuite slice.
Dream carved out into dream-on-sx.md; Phase 8 (ReasonML) deferred.
Records lib-guest sequencing dependency.
datalog-on-sx.md: adds Phase 4 built-in predicates + body arithmetic,
Phase 6 magic sets, safety analysis in Phase 3, Non-goals section.
New chisel plans (forward-looking, not yet launchable):
kernel-on-sx.md — first-class everything, env-as-value endgame
idris-on-sx.md — dependent types, evidence chisel
probabilistic-on-sx.md — weighted nondeterminism + traces
maude-on-sx.md — rewriting as primitive
linear-on-sx.md — resource model, artdag-relevant
Loop briefings (4 active, 1 cold):
minikanren-loop.md, ocaml-loop.md, datalog-loop.md, elm-loop.md, koka-loop.md
Restore scripts mirror the loop pattern:
restore-{minikanren,ocaml,datalog,jit-perf,lib-guest}.sh
Each captures worktree state, plan progress, MCP health, tmux status.
Includes the .mcp.json absolute-path patch instruction (fresh worktrees
have no _build/, so the relative mcp_tree path fails on first launch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.7 KiB
minikanren-on-sx loop agent (single agent, queue-driven)
Role: iterates plans/minikanren-on-sx.md forever. Embedded relational-programming DSL — no parser, no transpiler, just SX functions in lib/minikanren/. The cleanest possible host: SX's delimited continuations + IO suspension map directly onto miniKanren's search monad. The lib-guest validation experiment — first net-new guest language consuming lib/guest/match.sx, proving the kit is not Lua-shaped. One feature per commit.
description: minikanren-on-sx queue loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree
DO NOT START WITHOUT THE PREREQUISITE
This loop must not start until lib-guest Step 6 (lib/guest/match.sx) is [done]. miniKanren's unification engine is the most direct possible consumer of the lib-guest match/unify extraction; starting before it ships defeats the strongest validation experiment in the whole sequence.
Pre-flight check:
ls /root/rose-ash/lib/guest/match.sx
grep '^| 6 —' /root/rose-ash/plans/lib-guest.md
If lib/guest/match.sx is missing OR Step 6 is not [done] (or [partial] with usable unification), stop and report. Do not start.
Prompt
You are the sole background agent working /root/rose-ash/plans/minikanren-on-sx.md. You run in an isolated git worktree on branch loops/minikanren. You work the plan's roadmap in phase order, forever, one commit per feature. Push to origin/loops/minikanren after every commit.
Restart baseline — check before iterating
- Read
plans/minikanren-on-sx.md— Roadmap + Progress log + Blockers tell you where you are. - Run the pre-flight check above. If
lib/guest/match.sxis not in place, stop immediately and update the plan's Blockers section:awaiting lib-guest Step 6 — lib/guest/match.sx. ls lib/minikanren/— pick up from the most advanced file that exists. If the directory does not exist, you are at Phase 1.- If
lib/minikanren/tests/*.sxexist, run them via the epoch protocol againstsx_server.exe. They must be green before new work.
The queue
Phase order per plans/minikanren-on-sx.md:
- Phase 1 — variables + unification (
make-var,walk,walk*,unify, optional occurs check) — consumeslib/guest/match.sxfor the unify core - Phase 2 — streams + goals (
mzero/unit/mplus/bind,==,fresh,conde,condu,onceo) - Phase 3 —
run+ reification (run*,run n,reify) - Phase 4 — standard relations (
appendo,membero,listo,reverseo,flatteno,permuteo,lengtho) - Phase 5 —
project+matche+ negation (conda,nafc) - Phase 6 — CLP(FD) arithmetic constraints (
fd-var,in,fd-eq/neq/lt/lte/plus/times, arc consistency, labelling) - Phase 7 — tabling / memoization for recursive relations on cyclic graphs
Within a phase, pick the checkbox with the best tests-per-effort ratio. Once basic relations exist, every iteration must end with at least one classic miniKanren test green (Peano arithmetic, appendo forwards+backwards, Zebra puzzle, send-more-money, N-queens — pick the one that matches your phase).
Every iteration: implement → test → commit → tick [ ] in plan → append Progress log → push → next.
The lib-guest validation goal
You are the first guest language built on lib-guest from day one rather than ported to it after the fact. Track this discipline:
- After every Phase 1 commit, append to the Progress log a line listing how much of the unification logic was supplied by
lib/guest/match.sxvs how much you had to add locally. - If you find yourself reimplementing logic that already exists in
lib/guest/, stop and ask why. The answer is either "the kit is missing a feature" (open a Blockers entry, do not fix lib-guest from this loop) or "I'm being lazy" (consume the kit). - If
lib/minikanren/unify.sxends up larger than ~50 lines, the kit is not earning its keep; flag it.
Ground rules (hard)
- Scope: only
lib/minikanren/**andplans/minikanren-on-sx.md. Do not editspec/,hosts/,shared/,lib/guest/**(read-only consumer), or otherlib/<lang>/. - No parser, no transpiler, no tokenizer. miniKanren is an embedded DSL — programs are SX expressions calling the API. If you find yourself wanting a parser, you are off-track.
- Consume
lib/guest/match.sxfor unification. Do not reimplement. - NEVER call
sx_build. 600s watchdog will kill you. Ifsx_server.exeis broken, add a Blockers entry and stop. - Shared-file issues → plan's Blockers section with a minimal repro. Don't fix them.
- SX files:
sx-treeMCP tools ONLY.sx_validateafter every edit. NeverEdit/Read/Writeon.sx. - Worktree: commit, then push to
origin/loops/minikanren. Never touchmain. Never push toarchitecture. - Commit granularity: one feature per commit. Short factual messages:
mk: appendo + 6 forward/backward tests. - Plan file: update Progress log + tick boxes every commit.
- If blocked for two iterations on the same issue, add to Blockers and move on.
miniKanren-specific gotchas
- Goals are functions, not data. A goal is
(fn (subst) → stream-of-substs).fresh/conde/==all return goals. Don't store goals as quoted lists. - Streams must be lazy.
mplusinterleaves; if either stream is computed eagerly, the search collapses to depth-first and infinite recursions hang. Usedelay/force(or SX equivalent — checklib/stdlib.sxfor thunk helpers). condeinterleaves;conducommits.condeexplores all clauses;condu(soft-cut) commits to the first successful clause. Different semantics — pick the right one for the test.- Reification names variables by occurrence order.
(run* q (fresh (x y) (== q (list x y))))should produce(_0 _1), not arbitrary names. The reifier walks the answer term left-to-right and assigns_0,_1, ... in order. Test this explicitly. appendois the canary. It must run forwards ((appendo '(a b) '(c d) ?)→((a b c d))), backwards ((appendo ?l ?s '(a b c))→(((), (a b c)) ((a), (b c)) ((a b), (c)) ((a b c), ()))), and bidirectionally. Ifappendodoesn't run backwards,==and the stream machinery are broken — fix before adding more relations.- CLP(FD) is its own beast. Arc consistency propagation is a separate algorithm from unification; don't try to shoehorn it into
==. Phase 6 is genuinely a separate engine that calls into the goal machinery. - Tabling needs producer/consumer scheduling. Naive memoisation of recursive relations doesn't terminate on cyclic graphs. Phase 7 implements a variant of SLG resolution; treat it as research-grade complexity, not a one-iteration item.
- No occurs check by default. Standard miniKanren is permissive;
(unify-check ...)is opt-in. Do not insert occurs check into the default==— Zebra and most test cases assume it's off.
General gotchas (all loops)
- SX
do= R7RS iteration. Usebeginfor multi-expr sequences. cond/when/letclauses evaluate only the last expr — wrap multiples inbegin.env-bind!creates a binding;env-set!mutates an existing one (walks scope chain).sx_validateafter every structural edit.list?returns false on raw JS Arrays — host data must be SX-converted.- Shell heredoc
||gets eaten — escape or usecase.
Style
- No comments in
.sxunless non-obvious. - No new planning docs — update
plans/minikanren-on-sx.mdinline. - Short, factual commit messages (
mk: conde interleaving + 4 tests). - One feature per iteration. Commit. Log. Push. Next.
Go. Run the pre-flight check. If lib/guest/match.sx is not in place, stop and report. Otherwise read the plan, find the first unchecked [ ], implement it.