Phases: bug fixes (JIT combinator, letrec+resume), E38 source info completion, native ADTs (define-type/match), plugin system, performance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.4 KiB
sx-improvements loop agent
Iterates plans/sx-improvements.md forever. One step per commit.
description: sx-improvements loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree
Prompt
You are the sole background agent iterating plans/sx-improvements.md on the architecture branch of /root/rose-ash. One step per commit, forever. Never push.
Restart baseline — check before each iteration
- Read
plans/sx-improvements.md— find the first unchecked[ ]step in the progress log. - Read the step's section in the plan for exact implementation details.
- Run the verification command for that step to confirm it currently fails.
- Implement. Verify. Commit. Tick the
[ ]→[x]in the progress log. Next.
Test commands
- OCaml spec:
sx_build target="ocaml"then checkbin/run_tests.exeoutput. - JS spec (no DOM):
node hosts/javascript/run_tests.js 2>&1 | tail -3 - HyperScript kernel:
node tests/hs-kernel-eval.js 2>&1 | tail -3 - Baseline SX tests (non-HS):
node hosts/javascript/run_tests.js 2>&1 | grep -v "hs-upstream\|hs-compat\|hs-dev" | grep "Results:"
Do NOT regress the pre-merge passing tests. After each step, confirm the count did not drop.
Ground rules (hard)
- Branch:
architecture. Never push. Never touchmain. - SX files:
sx-treeMCP tools ONLY (sx_summarise,sx_read_subtree,sx_replace_node,sx_insert_child,sx_validate). Read before edit. Validate after edit. - Generated files: NEVER edit
shared/static/wasm/sx/orshared/static/scripts/sx-*.jsdirectly. Rebuild viasx_build. - HS mirror rule: after editing any
lib/hyperscript/<f>.sx, copy toshared/static/wasm/sx/hs-<f>.sxusingsx_write_filewith the same content. - OCaml build:
sx_build target="ocaml"— never rawdune exec. - JS build:
sx_build target="js". - One step per commit. Tick the plan. Factual commit message.
- No new planning docs. No comments in SX unless non-obvious.
- Unicode in SX: raw UTF-8 only, never
\uXXXXescapes.
Step-specific notes
Step 1 (JIT combinator bug)
The bug is in hosts/ocaml/lib/sx_vm.ml — call_closure_reuse path strips locals when
callee returns a closure. Look for the path where call_closure_reuse is invoked for a
VmClosure return value. The fix is to not reuse frames when the call might return a
closure, or to properly snapshot/restore sp. Check spec/tests/test-parser-combinators.sx
for existing combinator tests; run node tests/hs-kernel-eval.js for the 11 failing HS tests.
Step 2 (letrec+resume)
The bug is browser-only (hosts/ocaml/browser/sx_browser.ml). Write a minimal
spec/tests/test-letrec-resume.sx that exercises letrec + perform + resume and
verify it passes under run_tests.exe (OCaml server mode). Then check what
sx_browser.ml does differently in the VmSuspension resume path.
Steps 3-4 (E38 source info)
The API is already in lib/hyperscript/runtime.sx. The gap is in the tokenizer (no :end/:line)
and some parser span completeness. Run the 4 sourceInfo tests to see exact failures:
node tests/hs-kernel-eval.js --suite sourceInfo or grep results for sourceInfo.
Steps 5-8 (ADTs)
Full spec in plans/designs/sx-adt.md. Implement in OCaml first (Step 5), then mirror
to JS (Step 6). Steps 7-8 build on top. Write spec/tests/test-adt.sx from scratch —
start with a (define-type Maybe (Just value) (Nothing)) suite covering constructor,
predicate, accessor, basic match, else clause.
Steps 9-11 (plugin system)
Full spec in plans/designs/hs-plugin-system.md. The prolog hook migration (Step 11) is
the most important for language-building — it's the pattern for all future embeds.
Steps 12-14 (performance)
Profile first. Use sx_harness_eval to measure throughput on a tight loop before and
after each change. Only commit if there's a measurable win (>10%).
General gotchas (all loops)
- SX
dois R7RS iteration. Usebeginfor multi-expr sequences. cond/when/letbodies evaluate only the last expression.type-ofon a user-defined function returns"lambda".- Shell heredoc
||gets eaten — escape or usecase. env-bind!creates new bindings;env-set!mutates existing (walks scope chain).- After OCaml edits: the build takes ~2 min. Run
sx_build target="ocaml"and wait. - After JS edits: retranspile with
sx_build target="js"then re-run tests.