m2-market/specs/001-market-first-wedge/spec.md
m2 (AI Agent) e8ee3920de factory-loop: onboard spec-kit, ratify constitution v1.0.0, draft 001-market-first-wedge spec
- spec-kit initialized (claude integration; /speckit.* skills in .claude/skills/)
- constitution: 7 principles from CONCEPT.md v0.2 + inherited fleet constraints
- spec 001-market-first-wedge: 5 prioritized stories, FR-001..015, SC-001..007
- operator steer from README §open-forks folded into assumptions (ledger standalone
  now / m2-gpt-billing crypto later, fixed pricing + job headroom, Electron MVP
  store, Scout host = explore spike)
- .m2herd/ context fabric initialized (gitignored)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:03:14 +02:00

281 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature Specification: M2 Marketplace — First Wedge
**Feature Branch**: `001-market-first-wedge`
**Created**: 2026-07-02
**Status**: Draft
**Input**: User description: "M2 Marketplace first wedge: schemas, m2-ledger, commercialize curation, market:catalog + m2-market CLI, cargstore revival to M2 Store, 3-5 seeded Solutions, Solution Scout v0, one real paid install between two operators" (CONCEPT.md v0.2 §12)
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Paid install via CLI (Priority: P1)
An operator (buyer) searches the catalog for a capability they need, inspects a listing's
evidence and price, and installs it. The install debits their credit wallet, credits the
seller (minus platform cut), grants a license, and applies the Solution bundle to their
machine through the existing sync/apply path. This is the commercial loop's spine — every
other story feeds it.
**Why this priority**: Without buy→debit→grant→apply working end-to-end, nothing else in the
marketplace has meaning. It is independently valuable: even with zero storefront UI and zero
Scout, two operators can transact via CLI.
**Independent Test**: On a machine with a funded wallet, run `m2-market search <term>`,
`m2-market show <listing>`, `m2-market install <listing>`; verify ledger shows the debit and
seller credit, a license grant exists, and the bundle's files/config are applied and
invocable.
**Acceptance Scenarios**:
1. **Given** a listed Solution priced at 40 credits and a buyer wallet holding ≥40 credits,
**When** the buyer runs `m2-market install <listing-id>`, **Then** the ledger records a
debit of 40 from the buyer, a credit of 36 to the seller and 4 to the platform (10% cut),
a license grant is recorded, and the bundle is applied idempotently to the buyer's machine.
2. **Given** a buyer wallet holding fewer credits than the listing price, **When** they
attempt install, **Then** the install is refused before any apply happens and no ledger
transaction or license grant is created.
3. **Given** a completed install, **When** the same install is re-run, **Then** the apply is
idempotent (no duplicate debit; re-apply is safe or a no-op with the existing license).
4. **Given** an applied Solution, **When** the operator invokes its documented entrypoint,
**Then** the packaged outcome executes on their machine.
---
### User Story 2 - Publish a Solution with evidence (Priority: P1)
A builder packages a proven outcome (e.g. the mm-pdf branded-report generator) as a Solution:
a manifest-superset bundle with price, seller, license, and provenance evidence. They submit
it for listing; it passes the curation pipeline (scored PR, human veto) with the
`commercialize` disposition and lands in the registry of record and the semantic catalog.
**Why this priority**: Supply side of the loop. Story 1 cannot demo without at least one real
listing; seeding 35 Solutions from proven outcomes is part of this wedge.
**Independent Test**: Package one existing proven outcome, submit it, approve the listing PR,
and verify it is retrievable via `m2-market search` with its evidence and price visible.
**Acceptance Scenarios**:
1. **Given** a valid Solution bundle with price and provenance, **When** the builder submits
it for listing, **Then** a review PR is created carrying evidence, price, permissions, and
rollback info, and the listing is NOT discoverable until the PR is merged.
2. **Given** a submitted listing missing provenance evidence, **When** it enters curation,
**Then** it is rejected by validation before human review.
3. **Given** a merged listing, **When** any operator searches the catalog semantically,
**Then** the listing is returned with name, summary, price, rating placeholder, and
evidence summary.
4. **Given** tenant-derived work, **When** submission is attempted by anyone other than the
owning operator, **Then** the submission is refused (tenant firewall).
---
### User Story 3 - Credit wallets and starter grants (Priority: P2)
Each operator has a wallet. The platform issues starter grants to active operators so the
economy can bootstrap. Balances derive from an append-only transaction log; a daily snapshot
is committed to the registry host for audit.
**Why this priority**: Story 1 needs wallets to debit, but a minimal hardcoded grant would
suffice for the very first transaction; full wallet lifecycle is its own increment.
**Independent Test**: Issue a starter grant to a fresh operator id; verify balance query
returns the grant amount; verify the daily snapshot job writes a balance file into version
control.
**Acceptance Scenarios**:
1. **Given** a new operator id, **When** a starter grant (default 100 cr) is issued, **Then**
their balance reflects it and the grant appears as an append-only transaction with reason
`grant`.
2. **Given** any sequence of transactions, **When** balances are queried, **Then** they equal
the fold of the transaction log (no stored balance drifts from derived balance).
3. **Given** a day with ≥1 transaction, **When** the snapshot job runs, **Then** a balance
snapshot is committed to the audit repo.
---
### User Story 4 - M2 Store (cargstore revival) on canaries (Priority: P3)
An operator on a canary desktop opens the M2 Store app, browses the catalog rendered from
`market:catalog`, opens a Solution page showing evidence, price, and permissions diff, and
installs with one click — same ledger + apply path as the CLI.
**Why this priority**: The storefront makes the loop humane but the CLI already closes it.
Canary-only (chris-m2o, gunnar-m2o) per the constitution's deployment principle.
**Independent Test**: On one canary desktop, open the store, find a seeded listing, click
install, and verify the same post-conditions as Story 1's scenario 1.
**Acceptance Scenarios**:
1. **Given** the store app pointed at the live catalog, **When** it renders the front page,
**Then** seeded listings appear with name, summary, category, price.
2. **Given** a Solution page, **When** the operator clicks Install, **Then** the identical
debit→grant→apply sequence of Story 1 executes and the UI reports success/failure
truthfully.
3. **Given** an install failure after debit, **When** the failure is detected, **Then** the
operator sees a clear error and a compensating refund transaction is recorded.
---
### User Story 5 - Solution Scout v0 on one canary (Priority: P3)
While an operator works, a per-desktop watcher summarizes session intent from structured
lifecycle/run summaries (never raw keystrokes), matches it against tenant-allowed catalog
listings, and — on a high-confidence hit — shows a non-blocking proposal with a deep link to
the listing. Propose-only, opt-in, rate-limited.
**Why this priority**: Demand-side engine; valuable but the wedge's success criterion only
requires discovery "via Scout **or** Hermes/CLI". Ships last, on one canary.
**Independent Test**: On an opted-in canary, run a session that resembles a seeded listing's
intent; verify a proposal appears within the session with a working deep link, and that
opting out or exceeding the daily rate cap suppresses proposals.
**Acceptance Scenarios**:
1. **Given** an opted-in desktop and a session whose summary semantically matches a listing
above threshold, **When** the match fires, **Then** a non-blocking notification with the
listing's name, rating, coverage, and price appears with an install deep link.
2. **Given** an opted-out desktop, **When** the same session runs, **Then** no session data
leaves the machine and no proposal is shown.
3. **Given** N proposals already shown today (rate cap), **When** another match fires,
**Then** it is suppressed.
4. **Given** a proposal, **When** the operator dismisses or accepts it, **Then** the outcome
is recorded as listing-quality evidence (conversion signal).
---
### Edge Cases
- Install interrupted between ledger debit and apply completion → apply must be resumable or
a compensating refund recorded; never a paid-but-not-applied end state without a visible
remediation path.
- Listing updated (new version) after purchase → existing license covers which versions?
(v1: license covers the purchased major version; updates within it are free re-applies.)
- Seller delists a purchased Solution → existing licenses and installed bundles remain valid.
- Two installs of the same listing racing on one machine → second is a no-op under the
existing idempotent apply semantics.
- Catalog index diverges from registry of record → registry wins; index must be rebuildable
from it (constitution II).
- Buyer and seller are the same operator (self-purchase) → allowed but flagged; conversion
signals from self-purchases are excluded from listing quality metrics.
- Scout matches against a listing the tenant may not see → must be impossible by
construction: matching runs against tenant-allowed listings only.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The system MUST define a frozen v1 `solution.schema.json` as a superset of the
fedlearn manifest, adding at minimum: price, seller/operator id, license terms, and
revenue-split fields.
- **FR-002**: The system MUST define a frozen v1 `listing.schema.json` covering catalog
presentation: id, name, summary, category, keywords, price, seller, evidence references,
rating/conversion placeholders, and install reference.
- **FR-003**: The system MUST provide an append-only credit ledger recording transactions
`{ts, from, to, amount, reason: install|payout|grant|route|earn, ref}` with balances always
derived from the log.
- **FR-004**: The ledger MUST authenticate API callers (per-key auth) and MUST commit a daily
balance snapshot to the version-controlled audit location.
- **FR-005**: Installing a listing MUST atomically-in-effect: verify funds, debit the buyer,
credit the seller minus the platform cut (default 10%, configurable), record a license
grant, then trigger the existing sync/apply path; on apply failure a compensating refund
transaction MUST be recorded.
- **FR-006**: The curation pipeline MUST support a third disposition `commercialize`
alongside promote-to-core and reject/park, using the existing PR + human-veto flow, with a
listing PR template requiring evidence, price, permissions, and rollback notes.
- **FR-007**: The system MUST index merged listings into a semantic catalog partition
(`market:catalog`) searchable by meaning, scoped to tenant-allowed listings, and fully
rebuildable from the registry of record.
- **FR-008**: The system MUST provide an `m2-market` CLI with at minimum `search`, `show`,
and `install` commands, where `install` performs the FR-005 sequence.
- **FR-009**: Operators MUST have wallets keyed to operator identity (fleet tenancy model),
and the platform MUST be able to issue starter grants (default 100 cr).
- **FR-010**: The storefront (M2 Store, evolved from cargstore) MUST render the catalog,
show listing detail with evidence/price/permissions, and drive installs through the same
ledger + apply path as the CLI; deployment is canary-only in this wedge.
- **FR-011**: The Solution Scout MUST run per-desktop, opt-in via desktop policy config,
consume only structured session/run summaries (never raw keystrokes or raw client data),
summarize on-box before any egress, match only tenant-allowed listings, be rate-limited
(default: max 5 proposals/day), and be propose-only (install always requires a human
click).
- **FR-012**: Accepted and dismissed Scout proposals MUST be recorded as listing quality
evidence (proposal→install conversion).
- **FR-013**: At least 3 Solutions packaged from already-proven outcomes MUST be listed with
real evidence (proposed set: mm-pdf branded-report generator, agent-scaffold workspace
generator, competitor-scan report).
- **FR-014**: Install telemetry (who/when/machine/outcome) MUST land back in the memory
system as pricing/quality evidence attached to the listing.
- **FR-015**: Tenant-derived work MUST be commercializable only when owner-initiated and
doubly-scrubbed; submissions violating the tenant firewall MUST be rejected automatically.
### Key Entities
- **Solution**: installable bundle — intent, agent behavior, tools, runtime refs, memory
schema, permissions, deployment recipe, price, evidence. Conforms to
`solution.schema.json`; versioned in the registry of record.
- **Listing**: the catalog-facing record of a Solution (or other inventory type) —
presentation + commercial fields + evidence refs. Conforms to `listing.schema.json`;
truth in the registry, indexed in `market:catalog`.
- **Operator**: human identity over N machines (fleet tenancy); may act as buyer, builder,
seller, resource owner. Owns exactly one wallet in v1.
- **Wallet / Transaction**: operator's credit position, derived from append-only transactions
`{ts, from, to, amount, reason, ref}`.
- **License Grant**: record tying an operator to a purchased listing version, checked by the
install/apply path.
- **Proposal**: a Scout suggestion event — listing, confidence, shown/dismissed/accepted,
feeding conversion metrics.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: One real paid install completes between two distinct operators (e.g. m2bd buys
sdjs-operator's package): discovered via CLI/Hermes/Scout, bought with credits, applied via
the standard path, ledger reflecting debit/credit/cut — the loop closes commercially once.
- **SC-002**: ≥3 Solutions listed with real provenance evidence, each passing curation review.
- **SC-003**: 100% of installs have a matching ledger transaction and license grant; zero
applies without a recorded debit (audited from the daily snapshot).
- **SC-004**: Ledger balances recomputed from the transaction log match reported balances
exactly at every daily snapshot.
- **SC-005**: An operator can go from `m2-market search` to an invocable installed Solution
in under 10 minutes on a canary desktop.
- **SC-006**: Scout v0 on one canary produces ≥1 correct proposal (matching listing shown for
a genuinely related session) with zero raw-input egress, honoring opt-in and rate caps.
- **SC-007**: Install telemetry from SC-001's install is queryable as evidence on the listing
afterward.
## Assumptions
Recorded per constitution: recommended defaults from CONCEPT.md §14 open forks are ASSUMED
here and flagged until the operator confirms (also mirrored in `.m2herd/overview.json`
open_questions):
- **Ledger substrate** (operator steer, README 2026-07-02): standalone `m2-ledger` service
(SQLite, API-key auth) NOW; recorded future direction — it may evolve into a crypto-style
ledger managed inside extended m2-gpt billing. v1 interfaces must not preclude that
migration (keep ledger API separable from storage).
- **Pricing v1** (operator steer): fixed price per install as the default; the operator
notes that sometimes another m2o takes a *job* for a solution — service-style fulfillment
pricing. v1 transacts fixed-price installs only, but `listing.schema.json` must not
preclude a job/service fulfillment variant (reason codes `route|earn` already exist).
- **Storefront path** (operator steer): MVP Electron app (cargstore revival) that connects
to Coolify and other platform parts using credentials issued via m2-gpt; `web/` variant
deferred.
- **Scout host**: OPEN — operator marked "explore solution" (§14.4). Plan phase must carry a
short exploration spike (standalone supervised watcher vs Hermes plugin vs herdr plugin)
before Scout implementation; Scout v0 remains last-sequenced so this does not block the
wedge.
- **First Solutions**: mm-pdf, agent-scaffold, competitor-scan (§14.5 proposed).
- **Economics**: platform cut 10%, starter grant 100 cr, both configurable (§14.6 defaults).
- **Dependency**: fedlearn MVP rails (manifest schema, `m2/m2-core` registry, capture CLI,
curation PR/veto, `m2-core-sync` apply, memory partitions) are in herd execution NOW and
land before or during this wedge; where a rail is not yet landed, the plan phase must
sequence around it or stub against its frozen interface.
- Payout to fiat/external money is out of scope; payouts are manually reconciled.
- Resource/Service inventory types are catalog-schema-ready but not transacted in this wedge;
only Solutions are bought/sold.
- Public web marketplace, external payments, and public coin/exchange are out of scope.