Files
rose-ash/plans/agent-briefings/commerce-loop.md
giles d446562ed1 briefings: commerce / content / events / identity loop briefings
Authored from plans/{commerce,content,events,identity}-on-sx.md.
Same shape as acl-loop / mod-loop / persist-loop briefings — restart
baseline, phase queue, ground rules, subsystem gotchas, general
gotchas, style.

Substrate dependencies noted in each:
  commerce -> minikanren + persist + flow
  content  -> smalltalk + persist
  events   -> datalog + persist + flow
  identity -> erlang + persist + acl

Phase 1 of each is unblocked by the substrate that already exists;
later phases gate on persist (and friends) landing.
2026-06-06 23:25:15 +00:00

5.3 KiB

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.