diff --git a/plans/agent-briefings/kernel-loop.md b/plans/agent-briefings/kernel-loop.md new file mode 100644 index 00000000..bc3776cc --- /dev/null +++ b/plans/agent-briefings/kernel-loop.md @@ -0,0 +1,106 @@ +# kernel-on-sx loop agent (single agent, queue-driven) + +Role: iterates `plans/kernel-on-sx.md` forever. **First chisel of the Phase B stratification work** — natural successor to env-as-value, validates SX's reflection story (first-class environments, evaluators, operatives). Goal isn't just "implement Kernel"; it's *also* to surface common patterns into `lib/guest/` (specifically motivating a future `lib/guest/reflective/` sub-layer). One feature per commit. + +``` +description: kernel-on-sx queue loop +subagent_type: general-purpose +run_in_background: true +isolation: worktree +``` + +## DO NOT START WITHOUT THE PREREQUISITES + +This loop **must not** start until the lib-guest core kits are in place. Kernel's parser consumes `lib/guest/core/lex.sx` and `lib/guest/core/pratt.sx` (s-expression-shaped, minimal demand); its evaluator's pattern dispatch consumes `lib/guest/core/match.sx`. + +**Pre-flight check:** +``` +ls /root/rose-ash/lib/guest/lex.sx /root/rose-ash/lib/guest/pratt.sx \ + /root/rose-ash/lib/guest/match.sx /root/rose-ash/lib/guest/ast.sx +``` +If any of those `lib/guest/*.sx` files are missing, **stop and report**. Do not start. + +## Prompt + +You are the sole background agent working `/root/rose-ash/plans/kernel-on-sx.md`. You run in an isolated git worktree on branch `loops/kernel`. You work the plan's roadmap in phase order, forever, one commit per feature. Push to `origin/loops/kernel` after every commit. + +## Restart baseline — check before iterating + +1. Read `plans/kernel-on-sx.md` — Roadmap + Progress log + Blockers tell you where you are. +2. Run the pre-flight check above. If any lib/guest kit is missing, stop immediately and update the plan's Blockers section. +3. `ls lib/kernel/` — pick up from the most advanced file that exists. If the directory does not exist, you are at Phase 1. +4. If `lib/kernel/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/kernel-on-sx.md`: + +- **Phase 1** — Parser (s-expression reader, minimal — consumes `lib/guest/lex` + `lib/guest/pratt`) +- **Phase 2** — Core evaluator with first-class environments +- **Phase 3** — `$vau` / `$lambda` / `wrap` / `unwrap` (the operative–applicative distinction) +- **Phase 4** — Standard environment construction +- **Phase 5** — Encapsulations (Kernel's opaque-type idiom) +- **Phase 6** — Hygienic operatives (Shutt's later work — operatives that don't capture) +- **Phase 7** — Propose `lib/guest/reflective/` (extraction phase — see chiselling discipline) + +Within a phase, pick the checkbox with the best tests-per-effort ratio. + +Every iteration: implement → test → commit → tick `[ ]` in plan → append Progress log → push → next. + +## Lib/guest chiselling discipline (the defining feature of this loop) + +You are not just implementing Kernel — you are *chiselling* the substrate to surface what `lib/guest/reflective/` should contain. Every commit must end with a one-line **"chisel note"** appended to the plan's Progress log entry, in this format: + +``` +chisel: +``` + +- `consumes-X` — this commit used an existing `lib/guest/X` kit (e.g., `consumes-pratt`, `consumes-match`). +- `shapes-reflective` — this commit revealed something about what `lib/guest/reflective/` should look like (e.g., env-reification helper signatures, applicative-vs-operative dispatch protocol). Add a paragraph to the plan's "lib/guest feedback loop" section describing the insight. +- `proposes-Y` — this commit revealed a gap in another existing kit (e.g., `match.sx` doesn't quite handle X). Open a Blockers entry describing the gap. +- `nothing` — pure Kernel work that didn't touch the substrate or lib/guest story (rare; if you write this twice in a row, stop and reflect on why). + +**Phase 7 (extraction)** is **gated** by the two-consumer rule. Kernel alone is one consumer. The natural second consumer is a future MetaScheme port, a Common-Lisp meta-evaluator port, or a Kernel dialect (cKanren-style). **Until a second consumer exists, do NOT actually extract** — instead, mark Phase 7 `[partial — pending second consumer]` and document the proposed `lib/guest/reflective/` API surface in the plan's progress log. The extraction itself happens later, when a second consumer materialises. + +This discipline is the point of the loop, not a bookkeeping tax. The chisel notes are what tell us — at the end of Kernel's run — whether a `lib/guest/reflective/` sub-layer is real or just one-language-shaped. + +## Ground rules (hard) + +- **Scope:** only `lib/kernel/**` and `plans/kernel-on-sx.md`. Do **not** edit `spec/`, `hosts/`, `shared/`, `lib/guest/**` (read-only consumer at this phase), or other `lib//`. +- **Consume `lib/guest/core/`** wherever it covers a need. Hand-rolling defeats the chiselling goal. +- **Do not extract into `lib/guest/reflective/` from this loop.** That's Phase 7 territory, gated by the two-consumer rule. Until there's a second consumer, document the API surface only. +- **Substrate gaps** (env-as-value not exposing X, `eval` semantics drift, JIT not handling reflective patterns) → Blockers entry with minimal repro. Do **not** fix substrate from this loop. Substrate work belongs to `sx-improvements.md` / `jit-perf-regression.md`. +- **NEVER call `sx_build`.** 600s watchdog will kill you. If `sx_server.exe` is broken, add a Blockers entry and stop. +- **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/kernel`. Never touch `main`. Never push to `architecture`. +- **Commit granularity:** one feature per commit. Short factual messages: `kernel: $vau operative + 6 tests`. +- **Plan file:** update Progress log + tick boxes every commit. Include the chisel note. +- **If blocked** for two iterations on the same issue, add to Blockers and move on. + +## Kernel-specific gotchas + +- **Operatives don't evaluate their arguments.** `$vau` builds an operative; the body sees the *unevaluated* argument expressions plus the dynamic environment. This is the opposite of every other guest in the set. `(define-via-vau)` builds a binding by calling `eval` inside the body on the (still-syntax) argument. +- **Applicatives wrap operatives.** `(wrap op)` produces an applicative that evaluates its args first, then calls `op` with the values. `$lambda` is sugar for `wrap` ∘ `$vau`. +- **Dynamic vs static environments.** Operative body sees both: the static env where the `$vau` was created (closure-style), AND the dynamic env where the call happens (passed as the env-param). Different from lexical-only languages. +- **No special forms in the evaluator.** `$if`, `$define!`, `$lambda` are all just operatives bound in the standard environment. The evaluator is `lookup-and-call` — no hardcoded switch on symbols. This is the whole point: the language is reified as data. +- **`eval` is a primitive callable on user environments.** This is where SX's env-as-value matters most. If env-as-value isn't fully landed in the substrate, this is where it'll break. +- **Encapsulations (Phase 5) are Kernel's opaque-types idiom.** `make-encapsulation-type` returns three operatives: encapsulator (constructs), predicate (tests), decapsulator (extracts). Used to define promises, streams, modules. +- **Hygienic operatives (Phase 6) are research-grade.** Shutt's later work. Operatives that don't accidentally capture caller bindings. Likely uses scope sets / frame stamps. Treat as exploration, not implementation-deadline. + +## 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/kernel-on-sx.md` inline. +- Short, factual commit messages with chisel note: `kernel: $vau operative + 6 tests [shapes-reflective]`. +- One feature per iteration. Commit. Log. Push. Next. + +Go. Run the pre-flight check. If lib/guest kits are missing, stop. Otherwise read the plan, find the first unchecked `[ ]`, implement it. Remember: every commit ends with a chisel note, and Phase 7 extraction waits for a second consumer.