2.9 KiB
Contract: market:catalog partition (memory-api) (v1)
The semantic index over published listings. Derived data only — rebuildable from
m2/market-registry at any time.
Partition
- Namespace:
market:catalog(memory-api partition, same mechanism asfedlearn:core-indexdesign). - Document = one published listing: embedded text =
name + summary + keywords + intent + evidence_summary(BGE-M3 hybrid dense+sparse); payload = fulllisting.json+tenant_visibility. - Endpoint: the stack behind
memory.machinemachine.ai(split-brain caveat: research.md R4 — pinned until fedlearn T13 resolves; recovery = reindex).
Writers
ONLY m2-market-indexer:
watch— on registry merge (webhook or poll ≤5 min), upsert changed listings, remove delisted.reindex— drop partition, rebuild from registrymain(constitution II gate; must complete < 5 min at wedge scale).
Readers
- CLI
m2-market search→ memory-api semantic query, server-side filtertenant_visibility ⊇ {caller tenant | "*"}(FR-007; Scout edge case "impossible by construction"). - M2 Store front page/search → same query path (via CLI or direct HTTP with desktop creds).
- Scout matcher → same query path, additionally thresholded by confidence.
Query contract (via memory-api HTTP)
Request: {query_text, partition: "market:catalog", tenant, limit} →
Response items: {listing_id, score, listing: <payload>} ordered by hybrid score.
Telemetry write-back (FR-012, FR-014)
Install + proposal events land as memory records in market:evidence partition keyed by
listing_id; a periodic indexer pass folds counts into stats in the registry (PR-less
stats commit or scheduled batch PR — implementation's choice, registry remains truth).
AS-BUILT AMENDMENT (2026-07-02, analyze finding I1)
The live memory-api (agent.memory.system) exposes /memory/store + /memory/search
only — no partition drop, no delete, no upsert-by-id, and its server-side tenant filter
is a scalar tenant_id (not an array match). The implementation therefore deviates:
- Partition = the
agent_idnamespace; documents are memories with the listing inmetadata.listingandmetadata.listing_id. - Writer upsert = search-first for
metadata.listing_id, store only if absent (idempotent fill). Listing UPDATES and delist removal require memory-api delete — until then, delisted/updated listings are filtered/handled at read time. - Reader tenant filter
tenant_visibility ⊇ {caller tenant | "*"}is enforced in the ONE shared reader client (cli/src/m2_market/catalog.py), which every surface uses. - Full rebuild = fresh-partition switch (
MEMORY_API_PARTITIONwriter-side,M2_MARKET_CATALOG_PARTITIONreader-side) — docs/runbook.md.
The original section above is retained as the target contract for when memory-api grows partition CRUD (fedlearn T13 follow-up).