Files
rose-ash/plans/agent-briefings/minikanren-loop.md
giles 9dd9fb9c37 plans: layered-stack framing + chisel sequence + loop scaffolding
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>
2026-05-08 22:27:50 +00:00

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

  1. Read plans/minikanren-on-sx.md — Roadmap + Progress log + Blockers tell you where you are.
  2. Run the pre-flight check above. If lib/guest/match.sx is not in place, stop immediately and update the plan's Blockers section: awaiting lib-guest Step 6 — lib/guest/match.sx.
  3. ls lib/minikanren/ — pick up from the most advanced file that exists. If the directory does not exist, you are at Phase 1.
  4. If lib/minikanren/tests/*.sx exist, run them via the epoch protocol against sx_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) — consumes lib/guest/match.sx for the unify core
  • Phase 2 — streams + goals (mzero/unit/mplus/bind, ==, fresh, conde, condu, onceo)
  • Phase 3run + reification (run*, run n, reify)
  • Phase 4 — standard relations (appendo, membero, listo, reverseo, flatteno, permuteo, lengtho)
  • Phase 5project + 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.sx vs 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.sx ends up larger than ~50 lines, the kit is not earning its keep; flag it.

Ground rules (hard)

  • Scope: only lib/minikanren/** and plans/minikanren-on-sx.md. Do not edit spec/, hosts/, shared/, lib/guest/** (read-only consumer), or other lib/<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.sx for unification. Do not reimplement.
  • NEVER call sx_build. 600s watchdog will kill you. If sx_server.exe is 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-tree MCP tools ONLY. sx_validate after every edit. Never Edit/Read/Write on .sx.
  • Worktree: commit, then push to origin/loops/minikanren. Never touch main. Never push to architecture.
  • 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. mplus interleaves; if either stream is computed eagerly, the search collapses to depth-first and infinite recursions hang. Use delay/force (or SX equivalent — check lib/stdlib.sx for thunk helpers).
  • conde interleaves; condu commits. conde explores 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.
  • appendo is 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. If appendo doesn'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. Use begin for multi-expr sequences.
  • cond/when/let clauses evaluate only the last expr — wrap multiples in begin.
  • env-bind! creates a binding; env-set! mutates an existing one (walks scope chain).
  • sx_validate after every structural edit.
  • list? returns false on raw JS Arrays — host data must be SX-converted.
  • Shell heredoc || gets eaten — escape or use case.

Style

  • No comments in .sx unless non-obvious.
  • No new planning docs — update plans/minikanren-on-sx.md inline.
  • 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.