m2-market/specs/001-market-first-wedge/quickstart.md

3.8 KiB

Quickstart — validate 001-market-first-wedge end-to-end

Runnable validation scenarios proving the wedge works. These are the converge-stage gates; SC references map to spec.md Success Criteria.

Prerequisites

  • m2-ledger deployed on Coolify (GET /health → healthy), admin + service keys in env.
  • m2/market-registry exists on Forgejo with schemas mirrored and CI validation active.
  • memory-api reachable; market:catalog partition created.
  • m2-market CLI installed on two machines mapped to two DIFFERENT operator_ids (e.g. m2bd and sdjs-operator); apply_adapter = "local".
  • ≥1 Solution bundle packaged from solutions/ and listed (published) with real evidence.

Scenario A — publish with evidence (Story 2, SC-002)

m2-market publish solutions/mm-pdf-report        # opens listing PR
# expect: PR with evidence/price/permissions/rollback template; CI green
# reviewer merges (no veto label)
m2-market search "branded pdf report"            # expect: listing returned with price

Negative: strip evidence[] from a copy → m2-market publish exits 5 (or CI hard-fails).

Scenario B — funded install, the money move (Story 1, SC-001/003/005)

# seller: sdjs-operator (listing owner) · buyer: m2bd
curl -X POST $LEDGER/grant/starter -H "X-API-Key: $ADMIN" -d '{"operator_id":"m2bd"}'
m2-market wallet                                  # expect: 100 cr
time m2-market install lst_mm_pdf_report --yes    # expect: exit 0, entrypoint hint printed
m2-market wallet                                  # expect: 100 - price
curl $LEDGER/balance/sdjs-operator                # expect: +price*0.9
curl $LEDGER/balance/platform                     # expect: +price*0.1
curl $LEDGER/license/m2bd/lst_mm_pdf_report       # expect: 200 grant
# invoke the installed solution's documented entrypoint → produces its outcome (AC-4)

time for the whole discover→install path < 10 min (SC-005).

Scenario C — refusal, idempotency, refund (Story 1 AC-2/3, Story 4 AC-3)

# fresh operator, no grant:
m2-market install lst_mm_pdf_report --yes         # expect: exit 3, no tx, no grant, no files
# re-run a completed install:
m2-market install lst_mm_pdf_report --yes         # expect: exit 0 no-op, no second debit
# force an apply failure (recipe check that fails on this machine):
m2-market install lst_broken_fixture --yes        # expect: exit 4, refund rows present:
curl "$LEDGER/tx?reason=refund"                   # expect: compensating pair for that ref

Scenario D — ledger audit properties (SC-003/004)

curl -X POST $LEDGER/snapshot -H "X-API-Key: $ADMIN"
# in m2/market-registry: audit/<today>.json committed
pytest ledger/tests/test_properties.py            # balance==fold(log); grants all have tx

Scenario E — catalog rebuildability (constitution II)

# memory-api has no delete: rebuild = fresh-partition switch (docs/runbook.md)
MEMORY_API_PARTITION=market:catalog-e2e python3 -m m2_market_indexer.reindex
M2_MARKET_CATALOG_PARTITION=market:catalog-e2e \
  m2-market search "branded pdf report"           # same results as the live partition

Scenario F — M2 Store on canary (Story 4) [after row 8]

On chris-m2o: open M2 Store → seeded listings render → install from a Solution page → Scenario B post-conditions hold; UI reports the result truthfully.

Scenario G — Scout v0 on canary (Story 5, SC-006) [after row 9 + spike]

On the opted-in canary, run a session resembling a seeded listing's intent → one proposal toast with deep link; opt-out desktop shows nothing; 6th proposal of the day suppressed; outcomes appear in market:evidence.

The wedge gate

SC-001 is met when Scenario B (and C's guards) pass between two real operators with a real listing — via CLI alone. Scenarios F/G extend the same loop to Store and Scout surfaces.