Contract status: v1 static schema and service-local behavior verified in isolated tests. Live YSQL/provider/Redis integrations remain unverified. This is an internal data contract, not a public HTTP API.
Incoming provider catalog reads
- An approved, authenticated Provider API data-plane recipient should expose read-only catalog operations, such as
GET /api/v1/productsandGET /api/v1/products/{id}. - Catalog identity may read products and metadata; it cannot submit, cancel or refund orders or access a Provider Host Manager lifecycle interface.
- Contract version and product identifiers must be validated before using data. Unsupported versions, malformed payloads and unreviewed opaque IDs fail closed.
- Runtime direct Adapter/mTLS integration and authenticated provider discovery are not yet connected. The current process can use an injected fetch client for isolated verification.
Outgoing catalog snapshot: Redis v1
Sole publisher: Catalog Aggregator.
| Key | Meaning | Ownership |
|---|---|---|
catalog:current |
UTF-8 JSON catalog snapshot, schema version 1; no TTL |
Catalog Aggregator writes; approved browse/read consumers read |
catalog:staging:<generation> |
Ephemeral complete snapshot before atomic rename | Publisher only |
catalog:publisher |
Time-bounded single-publisher claim | Publisher only |
catalog:rebuild:requested |
Best-effort catalog-refresh request | Authorized policy owner requests; publisher consumes |
Document format:
{
"schema_version": 1,
"published_at": "2026-10-28T00:00:00Z",
"items": [
{
"id": "example-product",
"name": "Example Product",
"upstream_price_usd": "10.00",
"price_usd": "13.00",
"markup_percent": "30",
"stock": 5,
"in_stock": true,
"provider_id": "example-provider",
"offer_id": "example-offer",
"upstream_product_id": "example-sku",
"currency": "USD",
"priority": 100,
"healthy": true
}
]
}
Decimal fields are exact, and a snapshot may include additional optional item fields. Consumers must validate schema_version=1. Browse may show an older snapshot, but purchase admission must reject one older than 180 seconds or more than 60 seconds in the future, and must revalidate any real purchase through the proper financial/provider authorities.
Failure and recovery contract
- If one Provider times out, the publisher continues with healthy Providers. Failed Provider offers are omitted from that cycle’s new snapshot; they are not silently presented as freshly available.
- If all enabled Providers fail, no replacement is published; the last successful Redis snapshot remains. Consumers must still reject stale snapshots for purchase admission.
- If Redis is unavailable, the long-running Worker catches the error, backs off, and retries after recovery rather than crashing. A failed atomic rename must not erase the preceding snapshot.
- Losing the publisher fence prevents replacement. This Redis get/refresh fence is not a proven distributed atomic lease; deployment must prevent split-brain publication.
- A missing, unreadable or malformed snapshot fails closed for consumers; Redis unavailability must never authorize a purchase or create a substitute local catalog authority.
Deployment boundary
The service is a separately packaged, non-root container. It does not require a public subdomain: its standard interface is the internal versioned Redis document plus the authenticated Provider-read contract. The build has no access to other services’ source trees, Docker socket, live payments or secrets.
YSQL-backed Provider Registry and operator policy persistence, authenticated mTLS Adapter discovery and real Redis integration remain explicit production-readiness gates.