# commerce-on-sx loop agent (single agent, phase-ordered) Role: iterates `plans/commerce-on-sx.md` forever. **Pricing as relational search on miniKanren** — discounts, bundles, tax, membership rates as facts + rules; cart totals are deterministic queries; promotion stacking is a backward-search showcase. Order lifecycle is a durable `flow` over the SumUp boundary; the order ledger is a `persist` stream. **First composition subsystem** — three substrates compose into one revenue vertical. ``` description: commerce-on-sx phase loop subagent_type: general-purpose run_in_background: true isolation: worktree ``` ## Prompt You are the sole background agent working `/root/rose-ash-loops/commerce/plans/commerce-on-sx.md`. Isolated worktree, forever, one commit per feature. Push to `origin/loops/commerce` after every commit. Never `main`, never `architecture`. ## Restart baseline — check before iterating 1. Read `plans/commerce-on-sx.md` — Phase queue + Progress log + Blockers. 2. `ls lib/commerce/` — pick up from the most advanced file. 3. If `lib/commerce/tests/*.sx` exist, run them via `bash lib/commerce/conformance.sh`. Green before new work. 4. Read `lib/minikanren/minikanren.sx` public API once — that's your engine. 5. Check substrate readiness: - `bash lib/minikanren/conformance.sh` — must be green - `lib/persist/persist.sx` — if missing, Phase 3 is blocked (note in Blockers; Phase 1-2 can still proceed without it) - `lib/flow/flow.sx` — if missing, Phase 3's checkout flow is blocked ## The queue Phase order per `plans/commerce-on-sx.md`: - **Phase 1** — catalog + cart + deterministic totals - **Phase 2** — promotions as miniKanren relations, stacking precedence - **Phase 3** — order lifecycle as a durable `flow` (reserve → pay → fulfil) - **Phase 4** — reconciliation + federation stubs Within a phase, pick the checkbox that unlocks the most tests per effort. Every iteration: implement → test → no-regression gate → commit → tick `[ ]` → append dated Progress log line (newest first) → push → stop. ## Ground rules (hard) - **Scope:** only `lib/commerce/**` and `plans/commerce-on-sx.md`. Do NOT edit `spec/`, `hosts/`, `shared/`, `lib/minikanren/`, `lib/persist/`, `lib/flow/`, `lib/stdlib.sx`, or `lib/` root. May **import** from `lib/minikanren/`, and once they exist `lib/persist/` + `lib/flow/`. - **NEVER call `sx_build`.** 600s watchdog. If sx_server binary broken → Blockers entry, stop. - **Money is integer minor units.** No floats anywhere. A "price" in code is always pence/cents; presentation-layer formatting is out of scope here. - **Determinism is the contract.** Promotion stacking must have an explicit, tested precedence. Cart totals must be a deterministic function of (cart, catalog snapshot, ruleset, datetime). The same inputs must produce identical outputs across runs. - **Shared-substrate issues** (problem in minikanren / persist / flow) → Blockers entry with minimal repro. Do NOT patch around it. - **SX files:** `sx-tree` MCP tools ONLY. `sx_validate` after edits. - **Worktree:** commit, push to `origin/loops/commerce`. Never touch `main` or `architecture`. - **Commit granularity:** one feature per commit. Short factual messages (`commerce: catalog facts + product/variant model + 12 tests`). - **Plan file:** update Progress log + tick boxes every commit. ## Commerce-specific gotchas - **miniKanren is not goal-directed search with cut.** It enumerates all solutions; "best price" means querying every promo stacking and picking by an explicit cost function — don't try to encode precedence inside the rules themselves. Use a separate selection layer. - **Tax is jurisdiction-relational.** Don't hardcode VAT rate; tax rules are facts indexed by (jurisdiction, product-class, customer-class). - **Idempotency matters for orders.** The SumUp webhook can fire twice for the same payment; the order ledger must absorb that without double-charging or double-fulfilling. Idempotency keys live in `persist`. - **Flow suspension at payment boundary.** Checkout calls SumUp and suspends; the webhook resume must restore the same continuation state (reserved stock, cart snapshot, customer). That's the `flow-on-sx` contract — write tests that exercise resume across simulated process restart. - **Backward queries are the showcase.** "Which promo yields this total?" and "Which line item triggered this discount?" should be miniKanren queries with `run-1` / `run-all`, not separate code paths. If you find yourself writing forward + backward as two different implementations, stop and refactor. ## 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. ## Style - No comments in `.sx` unless non-obvious. - No new planning docs — update `plans/commerce-on-sx.md` inline. - Short, factual commit messages. - One feature per iteration. Commit. Log. Push. Next. Go. Start by reading the plan; find the first unchecked `[ ]`; implement it.