Files
rose-ash/plans/agent-briefings/kernel-loop.md
giles 57184daaee
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 42s
briefings: add kernel-on-sx loop briefing
Sibling to apl-loop / common-lisp-loop / scheme-loop. Captures the
queue-driven kernel loop pattern (Phase B stratification entry-point,
env-as-value successor, motivates lib/guest/reflective/).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 15:28:09 +00:00

8.4 KiB
Raw Blame History

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 operativeapplicative 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: <one of: consumes-X | shapes-reflective | proposes-Y | nothing>
  • 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/<lang>/.
  • 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.