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

99 lines
7.7 KiB
Markdown

# 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 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.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.