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.
113 lines
5.3 KiB
Markdown
113 lines
5.3 KiB
Markdown
# 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.
|