commerce: time-windowed promotions (19 tests) — Phase 5 ext
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m9s

window.sx — a validity window kept separate from the promo tuple (promo.sx
untouched): windowed promo (promo from until), inclusive int timestamps, nil =
open bound. active-ruleset filters to promos live at `at` and feeds the existing
promo/stack/quote pipeline; active-codes is the backward "which codes live at
T?" query; windowed-quote is the datetime-aware, deterministic quote.
Total 228/228 across 14 suites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 11:35:53 +00:00
parent eb7e6be147
commit 2ebe5f0c31
6 changed files with 186 additions and 8 deletions

View File

@@ -21,7 +21,7 @@ reconciliation — all auditable via the event log.
## Status (rolling)
`bash lib/commerce/conformance.sh`**209/209** (13 suites; + payment) — **roadmap complete; Phase 5 extensions in progress**
`bash lib/commerce/conformance.sh`**228/228** (14 suites; + window) — **roadmap complete; Phase 5 extensions in progress**
## Ground rules
@@ -81,8 +81,9 @@ that unlocks the most tests per effort each iteration.
- [x] line-level discount attribution — "which line item triggered this discount?"
as a backward miniKanren query (`attribution.sx`: `promo-toucheso` relation,
`lines-for-code`/`codes-for-line` both directions, `order-level-codes` for fixed).
- [ ] time-windowed promotions — promos gated by a validity window; quote takes a
datetime, determinism preserved. (quote.sx already documents datetime intent.)
- [x] time-windowed promotions — `window.sx`: windowed promo `(promo from until)`,
`active-ruleset`/`active-codes`/`windowed-quote` gate by datetime; feeds the
existing promo/stack/quote pipeline unchanged. Determinism preserved.
- [ ] discount-aware tax policy — alternative `cart-quote` computing tax on the
net (post-discount) base via proportional class allocation; explicit + tested.
- [ ] refund as a flow — refund lifecycle (request → approve → settle) as a second
@@ -96,6 +97,13 @@ that unlocks the most tests per effort each iteration.
agnostic; `order-settle!(ref, amount)` is the resume seam.
## Progress log
- 2026-06-07 — `window.sx` (Phase 5 ext): time-windowed promotions. A validity
window is kept SEPARATE from the promo tuple — windowed promo `(promo from
until)` (inclusive int timestamps, nil = open bound). `active-ruleset` filters
to the plain promos live at `at` and feeds the existing promo/stack/quote
pipeline unchanged (promo.sx untouched); `active-promoo`/`active-codes` is the
backward "which codes are live at T?" query; `windowed-quote` is the
datetime-aware quote (deterministic in `at`). window suite 19/19; total 228/228.
- 2026-06-07 — `payment.sx` (Phase 5 ext, the item the user asked about):
provider-neutral payment-request envelope, materialised at the IO edge from the
ledger amount + host-supplied currency/return-url — keeps lib/commerce vendor-