# maude-on-sx loop agent (single agent, queue-driven) Role: iterates `plans/maude-on-sx.md` forever. **Rewriting as the only primitive** — equational logic + term rewriting modulo theories (assoc/comm/id). The chisel is *the reduction step*: Maude asks "what is one step of computation?" and answers with rewrite-modulo-equations, more general than the CEK transition. One feature per commit. ``` description: maude-on-sx queue loop subagent_type: general-purpose run_in_background: true isolation: worktree ``` ## Prerequisites — check before starting 1. **lib-guest lex + pratt present** — the `fmod`/`endfm` parser consumes `lib/guest/lex.sx` + `lib/guest/pratt.sx`. **Pre-flight:** ``` ls /root/rose-ash/lib/guest/lex.sx /root/rose-ash/lib/guest/pratt.sx ``` If missing, stop and record a Blockers entry. (Maude needs no special core primitive — it builds its own term/rewrite machinery in SX.) ## Prompt You are the sole background agent working `/root/rose-ash/plans/maude-on-sx.md`, in an isolated git worktree on branch `loops/maude`, forever, one commit per feature. Push to `origin/loops/maude` after every commit. Never touch `main` or `architecture`. ## Restart baseline — check before iterating 1. Read `plans/maude-on-sx.md` — Roadmap + Progress log + Blockers. 2. Run the pre-flight; record gaps in Blockers. 3. `ls lib/maude/` — pick up from the most advanced file. No dir → Phase 1. 4. If `lib/maude/tests/*.sx` exist, run them via the epoch protocol against `sx_server.exe`. Green before new work. ## The queue Phase order per `plans/maude-on-sx.md`: - **Phase 1** — parser + signatures (`fmod`/`endfm`, sorts + subsorts, op decls, equations; overloading by arity+sort) - **Phase 2** — syntactic equational reduction (apply eqs left-to-right to a fixpoint; strict pattern match) - **Phase 3** — **equational matching modulo assoc/comm/id** (the chisel: flatten AC operators, match across permutations/multisets; return *all* matches) - **Phase 4** — conditional equations (`ceq L = R if Cond`) - **Phase 5** — system modules + rewrite rules (`rl … => …`, asymmetric, fairness) - **Phase 6** — strategy language (`;`, `|`, `*`, fixed-point; named strategies) - **Phase 7** — reflection (META-LEVEL: terms-as-data, meta-interpretation) - **Phase 8** — propose `lib/guest/rewriting/` extraction (wait for a 2nd consumer) Within a phase, pick the checkbox with the best tests-per-effort ratio. Every iteration: implement → test → commit → tick `[ ]` → Progress log → push → next. ## Chisel discipline — the reduction step The payoff is **Phase 3's AC matching**: matching modulo associativity/commutativity/ identity is genuinely harder than the substitution the CEK does, and it's where Maude's "reduction step" diverges from SX's. Implement it as a term-rewriting engine *in SX* (terms are SX data; matching returns substitution sets). Do NOT try to bend the CEK into a rewriter — Maude runs *on* the CEK as an interpreter, it does not replace it. Note for the integrator: the AC-matching + normal-form engine is the prime candidate to feed an eventual `artdag-on-sx` effect-pipeline optimizer (`plans/artdag-on-sx.md`) — keep it cleanly separable (Phase 8). ## Ground rules (hard) - **Scope:** only `lib/maude/**` and `plans/maude-on-sx.md`. Do **not** edit `spec/`, `hosts/`, `shared/`, `lib/guest/**` (read-only), or other `lib//`. - **Consume `lib/guest/`** (lex, pratt). The rewrite engine itself is yours. - **Don't patch the substrate.** Maude is an interpreter over SX terms; substrate gaps → failing test + Blockers entry, never a `spec/` patch. - **NEVER call `sx_build`** (600s watchdog). Broken binary → Blockers, stop. - **SX files:** `sx-tree` MCP tools ONLY; `sx_validate` after every edit; `file:` not `path:`. Never `Edit`/`Read`/`Write` on `.sx`. - **Worktree:** commit, then push `origin/loops/maude`. Never `main`/`architecture`. - **Commits:** one feature per commit (`maude: AC matching for assoc-comm ops + 6 tests`). - **Plan file:** Progress log + tick boxes every commit. - **Blocked 2 iterations → Blockers, move on.** ## Maude-specific gotchas - **Equations vs rules.** `eq`/`ceq` are *equational* (`=`, applied to a fixpoint to normalise, confluent-by-intent); `rl` are *transitions* (`=>`, asymmetric, possibly nondeterministic). Don't apply rules during equational reduction. - **AC operators flatten.** `_+_` assoc means `a + (b + c)` and `(a + b) + c` are the same term — normalise to a flat sequence/multiset before matching, and match across orderings for `comm`. - **Matching returns a set of substitutions, not one.** AC matching is multi-valued; Phase 3 must yield all matches and let the caller drive (rule application picks). - **Identity is a rewrite, not a special case.** `id: e` for `_*_` means `X * e ≡ X` in both directions — handle as an equation in the AC matcher, carefully (avoid infinite insertion of identities). - **Strategies make the same rules mean different things** — Phase 6 evaluation result depends on strategy; keep rule set and strategy orthogonal. ## 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`. - `let` is parallel — nest `let`s when one binding references an earlier one. - `env-bind!` creates a binding; `env-set!` mutates an existing one. - Namespace-prefix guest helpers (`mau/…`). - Shell heredoc `||` gets eaten — escape or use `case`. ## Style - No comments in `.sx` unless non-obvious. No new planning docs — update the plan. - Short, factual commit messages. One feature per iteration. Commit. Log. Push. Next. Go. Run the pre-flight. If lib-guest is missing, stop and report. Otherwise read the plan, find the first unchecked `[ ]`, implement it.