5.2 KiB
Coordination note: m2-market ↔ fedlearn MVP
Addressed to: the fedlearn MVP effort (plan: /home/m2/m2o/.planning/federated-learning/PLAN.md
— referenced here, not edited; that plan is fedlearn's to own).
From: m2-market spec 001-market-first-wedge (research.md §R2, §R3, §R5; contracts/apply-adapter.md; contracts/registry-layout.md; data-model.md §Solution).
1. Context
m2-market froze schemas/solution.schema.json v1 on 2026-07-02. This happened because
the fedlearn manifest freeze (fedlearn's own Task 1.1) had not landed yet. We verified the
same day that none of the expected fedlearn rails exist: no m2/m2-core repo, no capture or
curator CLIs. Per the m2-market constitution (Principle VII, "Simplicity & Sequenced
Wedges"), blocking indefinitely on an unlanded dependency wasn't an option, so we froze our
own side and are coordinating via this note rather than waiting or forking fedlearn's
in-flight work (constitution: "consume, not fork").
This is not a request for fedlearn to change direction — it's a record of what we assumed, so fedlearn's actual manifest freeze can either confirm compatibility or tell us we need a v1→v2 migration on our side.
2. The compatibility ask
solution.schema.json v1 embeds a "manifest-core" subset of fields that we shaped to match
the fedlearn submission/manifest design as we understood it from the fedlearn plan. When
fedlearn's Task 1.1 manifest freeze lands, we're asking that it remain field-compatible
with this core — same field names, same types/shapes. Everything outside this list is
fedlearn's to define freely; we have no opinion on it.
The frozen manifest-core fields, as they appear in solution.schema.json v1
(specs/001-market-first-wedge/data-model.md §Solution):
| Field | Type |
|---|---|
schema_version |
const string (ours is m2.solution.v1) |
applicability.image_classes |
array |
applicability.roles |
array |
applicability.tool_requirements |
array |
tenant_scope |
string (m2-core or a tenant id) |
evidence |
array of {source, excerpt?, machine?, session?, tokens?, wall_time?} |
content_hash |
string, sha256 |
scrub_status |
object (present when tenant_scope is a tenant id; carries double_scrubbed) |
If fedlearn's manifest freeze diverges on any of these (different field name, different shape), tell us — we'll plan a schema migration at integration rather than silently drift.
3. The commercialize seam
When fedlearn's curation pipeline lands, we'd like its commercialize disposition to emit a
PR against m2/market-registry (the Forgejo repo we stood up as registry-of-record — see
research.md §R2), in the shape defined by
specs/001-market-first-wedge/contracts/registry-layout.md §Publish protocol. In short:
- A branch
listing/<listing_id>adding/updatinglistings/<listing_id>/(alisting.json, asolution.json, and anevidence/directory). - A PR carrying an evidence summary, price, a permissions diff, and a rollback note.
- CI validates the PR mechanically (schema-validate against the mirrored frozen schemas,
evidence non-empty, tenant-firewall rules,
content_hashmatches the attached release asset) before any human looks at it. - Human review resolves via label:
veto→ closed/back to draft;approved+ merge → published, which triggers catalog re-index.
This is the same PR/veto shape m2-market's own listing builders use — fedlearn's
commercialize disposition would be just another producer of this PR shape, not a new
protocol.
4. The adapter swap
m2-market ships a frozen ApplyAdapter protocol (contracts/apply-adapter.md) with two
implementations in v1: local (real, ships now) and m2core-sync (a stub that raises
RailsNotLanded, CLI exit 6). When fedlearn's m2-core-sync / m2-core pull --apply lands,
it becomes the real backing for the m2core-sync adapter — no changes needed to m2-market's
CLI or Store, because they only ever talk to the ApplyAdapter interface.
Acceptance for the swap: all quickstart.md scenarios pass unchanged with
adapter = m2core-sync selected (config.toml: apply_adapter = "m2core-sync" or
--adapter m2core-sync). See contracts/apply-adapter.md for the full protocol
(plan/apply/verify/rollback, all idempotent) and the state-file merge expectation
(~/.m2-market/state.json merging with fedlearn's state.json design).
5. What m2-market does NOT need from fedlearn
To keep expectations tight on both sides:
- No ledger. Value movement and balances are m2-market's own
m2-ledgerservice (append-onlytxtable); fedlearn doesn't need to model credits, payouts, or grants. - No catalog.
market:catalogis a memory-api partition owned and indexed bym2-market-indexerfromm2/market-registry; fedlearn's manifest doesn't need catalog- or listing-shaped fields (pricing, seller, revenue split, listing status) — those live only in m2-market'ssolution.json/listing.json, layered on top of the manifest-core. - No store dependency. The M2 Store (cargstore fork) talks to
market:catalogand shells out to them2-marketCLI for installs; it has no direct dependency on fedlearn services.
Questions about this note → m2-market spec 001-market-first-wedge (research.md §R3, "Open coordination items").