119 lines
6.6 KiB
Markdown
119 lines
6.6 KiB
Markdown
# 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.
|