Files
rose-ash/plans/agent-briefings/lib-guest-loop.md
giles d39ef786ba GUEST-plan: claim step 0 — baseline snapshot
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 21:04:19 +00:00

6.6 KiB

lib/guest extraction loop (single agent, queue-driven)

Role: iterates plans/lib-guest.md forever. Each iteration picks the top pending step, extracts/ports/validates, commits, logs, moves on. North star: every guest's scoreboard.json ≥ baseline at all times, while lib/guest/ accumulates shared infrastructure.

description: lib/guest extraction loop
subagent_type: general-purpose
run_in_background: true

Prompt

You are the sole background agent working /root/rose-ash/plans/lib-guest.md. You work a prioritised queue, one step per code commit, indefinitely. The plan file is the source of truth for what's pending, in-progress, done, and blocked. Update it after every iteration.

Iteration protocol (follow exactly)

1. Read state

  • Read plans/lib-guest.md in full.
  • Pick the first step with status [ ]. If all remaining are [blocked] or [done], stop and report loop complete.
  • Set that step's status to [in-progress] and commit the plan change alone: GUEST-plan: claim step <N> — <name>.

2. Baseline (every iteration that touches a guest)

Before any code edit, snapshot the current scoreboard for every guest this step will touch (extraction consumers + canaries):

bash lib/<guest>/conformance.sh    # or test.sh
cp lib/<guest>/scoreboard.json /tmp/baseline-<guest>-step<N>.json

If the step is Step 0, the snapshot itself is the work — copy each guest's scoreboard.json (or harvest pass/fail counts from test.sh for guests without a scoreboard) into lib/guest/baseline/<lang>.json, populate the table in plans/lib-guest.md, commit, done.

3. Do the work

For each step the protocol is:

  1. Read the relevant existing guest file(s) via sx_read_subtree to see exactly what shape needs extracting.
  2. Draft lib/guest/<file>.sx via sx_write_file (validates by parsing).
  3. Port the first consumer to use it. Run that guest's conformance. Must equal baseline.
  4. Port the second consumer (the two-language rule). Run that guest's conformance. Must equal baseline.
  5. If the second consumer needs escape hatches that the first didn't, the abstraction is wrong — redesign before continuing, don't paper over with alias chains or per-language flags.

For Step 0 only: just snapshot, no extraction.

4. Verify

For every guest the step touched:

bash lib/<guest>/conformance.sh   # or test.sh
diff lib/<guest>/scoreboard.json /tmp/baseline-<guest>-step<N>.json

Abort rule: if any touched guest's scoreboard regresses by ≥1 test, do NOT commit code. Revert with git checkout -- lib/guest/ lib/<consumers>/, mark the step [blocked (<specific reason>)] in the plan, commit the plan, move to the next step.

5. Commit code

One commit for the code:

GUEST: step <N> — <name>

<2-4 lines on what was extracted, which two consumers were ported, baseline-equal verification.>

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

6. Update plan + commit

In plans/lib-guest.md:

  • Change this step's status from [in-progress] to [done] (or [partial — pending <consumer>]).
  • Fill in the Commit and Delta columns of the progress log.
  • If you re-snapshotted any baseline, update the Baseline column.

Commit: GUEST-plan: log step <N> done.

7. Move on

Go back to step 1. Continue until:

  • All steps are [done] or [blocked], OR
  • You hit your iteration budget, OR
  • You encounter a substrate-level failure (build broken, sx_server.exe missing) — stop and report.

Ground rules

  • Branch: architecture. Commit locally. Never push. Never touch main.
  • Scope: ONLY lib/guest/**, lib/{lua,prolog,haskell,common-lisp,tcl,erlang,smalltalk,forth,ruby,apl,js}/**, plans/lib-guest.md, plans/agent-briefings/lib-guest-loop.md. NO spec/, hosts/, web/, shared/.
  • SX files: sx-tree MCP tools ONLY. Never Edit/Read/Write on .sx. sx_validate after every edit.
  • OCaml build: sx_build target="ocaml" MCP tool. Never raw dune.
  • Two-language rule: never merge an extraction until two guests consume it. Step 8 (HM) is the only exception, marked explicitly.
  • No alias chains to bridge naming drift between extraction and consumer — rename consumer-side or extraction-side, don't add a translation layer.
  • No new planning docs beyond updating the plan file.
  • No comments in SX unless non-obvious.
  • Unicode in SX: raw UTF-8, never \uXXXX.
  • Hard timeout: >45 min on a step → mark blocked, move on.
  • Partial fixes are OK. If you extract something and only the first consumer ports cleanly, mark [partial — pending <second consumer>], commit, move on. The next iteration that lands the second consumer flips it to [done].

Gotchas from past sessions

  • env-bind! creates a binding; env-set! mutates an existing one (walks scope chain). Macros that want to introduce names use env-bind!.
  • SX do is R7RS iteration, not a sequence form. Use begin for multi-expr bodies.
  • cond / when / let clause bodies eval only the last expr — wrap in begin for side-effects.
  • list? returns false on raw JS Arrays — host-side data must be SX-converted.
  • make-symbol builds an identifier symbol; string->symbol exists too — use whichever the surrounding code uses.
  • sx_validate after every edit. The hook will block raw Edit/Write on .sx anyway, but the validator catches subtree mistakes that parse-but-don't-mean-what-you-think.
  • Guest conformance.sh scripts use the epoch protocol against sx_server.exe. If the server isn't built, run sx_build target="ocaml" first.
  • Each guest's scoreboard.json schema differs slightly — normalise to {:totals {:pass N :fail M} :suites [...]} when writing lib/guest/baseline/<lang>.json.
  • lib/parser-combinators.sx exists and is unused by any guest. The new lex/Pratt kit may want to coexist with it, or supersede it — investigate before duplicating its functionality.
  • Prolog operator parsing is the stress test for Pratt — Prolog ops have variable precedence, xfx/xfy/yfx associativity classes, and user-definable ops at runtime. The Pratt kit must accommodate runtime registration, not just static tables.
  • Haskell layout is the stress test for whitespace-sensitive lexing — off-side rule, do/let/where/of opening blocks, semicolon insertion, brace insertion. Don't ship lib/guest/layout.sx unless the haskell scoreboard equals baseline.

Starting state

  • Branch: architecture. HEAD at or near 40f0e733.
  • Canaries: Lua + Prolog.
  • Plan file at plans/lib-guest.md. Step 0 (baseline snapshot) is the first iteration.
  • lib/guest/ does not yet exist — create it on the Step 0 commit.