SSyncropel Docs

Catalog

A curated discovery surface that publishes workspace manifests as records — the layer between what exists in registries and what an operator actually wants to mount.

Overview

Every spl serve ships with a registry — a content-addressed store of every record the daemon has ever seen, including any core.workspace.v1 manifests it has accepted. Registries are private, complete, and unopinionated. They tell you what a particular daemon knows about. They don't tell you what is good, current, recommended, or safe to mount in your /local.

The catalog is the layer above. It is a curated discovery surface — a small, explicit set of workspace manifests an operator deliberately chose to publish for others to consume. Today the catalog at catalog.syncropel.com publishes the four core.workspace.v1 manifests that back /local/{tasks, dashboard, governance, secrets}. Tomorrow it can host hundreds of manifests across multiple publishers, each subscribed to via the federation pair primitive.

The architectural framing matters because it constrains the choices. The catalog is not a hub, not a proprietary marketplace, not the canonical source of truth. It is one curated view over the substrate, which itself is the canonical store.

What the catalog is not

The framing is easier with the negative space drawn first.

  • Not a hub. A hub centralizes — it owns the data, and clients depend on it being up. The catalog publishes records to the substrate. If catalog.syncropel.com goes dark, the manifests it published are still in every daemon that fetched them, still content-addressed, still verifiable. The catalog is a cache that warmed, not a system that owns.
  • Not a registry. A registry is the local store inside every spl serve. The catalog is one publisher whose records the registry can accept. Anyone running spl serve already has a registry; choosing whether to subscribe to the catalog is a separate decision.
  • Not a gatekeeper. The catalog publishes the workspaces we curate. It does not approve, deny, or rank workspaces published elsewhere. The substrate routes by DID; if you publish did:sync:alice/notebook, my daemon fetches it from your endpoint, not through any catalog. The catalog only mediates did:sync:syncropel-team/*.
  • Not a marketplace. No payments, no ratings, no leaderboards, no recommendation algorithm. Curation today means "the syncropel team thinks this should ship as a default surface" — nothing else.

What the catalog serves today

https://catalog.syncropel.com/v1/records/query (unauthenticated reads of core.workspace.v1 records) returns four manifests:

DIDSlugWhat it backs
did:sync:syncropel-team/taskstasks/local/tasks
did:sync:syncropel-team/dashboarddashboard/local/dashboard
did:sync:syncropel-team/governancegovernance/local/governance
did:sync:syncropel-team/secretssecrets/local/secrets

Each manifest declares components — folds, projections, policy refs — that the renderer mounts. When /local/tasks loads, the syncropel-web client hits the catalog for did:sync:syncropel-team/tasks, validates the manifest, and renders the table projection over task.todo.* records pulled from the local daemon. If the catalog is unreachable or the manifest is malformed, the renderer falls back to a hardcoded React surface — a safety net the architecture preserves on purpose.

How publishing works

A catalog is just an spl serve instance configured for read-only public access. To publish a manifest into a catalog you operate, point SPL_DAEMON_URL at the catalog's URL, supply a token with publish scope, and run:

SPL_DAEMON_URL=https://my-catalog.example.com \
SPL_TOKEN=$(cat ~/.syncro/secrets/my-catalog.token) \
spl workspace publish --manifest path/to/workspace.json --release

The daemon validates the manifest against the core.workspace.v1 schema, content-addresses the body, and emits a record with lifecycle: published. Re-publishing identical content is a no-op (idempotent by content hash).

Public reads are gated by a single CEL permission rule on the catalog instance:

resource == "record_read" && record.body.kind == "core.workspace.v1"

Everything else (writes, queries against other body kinds, the admin surface) requires a bearer token. The asymmetry is the point — a catalog is read-by-default, write-by-credential.

Substrate placement

The five layers, from operator-private to public:

  1. Registry — every spl serve's local store. Private. Complete. Unopinionated.
  2. Workspace — a core.workspace.v1 record in some registry. Author-private until published.
  3. Catalog — a curated subset of workspaces a publisher chose to make discoverable. One catalog per publishing entity.
  4. Federation — the protocol by which one daemon's records reach another's registry. Pair-based, consent-gated.
  5. Discovery — DNS manifests, mDNS, optional DHT. Names → endpoints.

The catalog sits at layer 3 because that's where curation belongs. Lower layers are about capability (can these two daemons talk?). Higher layers are about naming (where do I find a daemon?). The catalog is about which manifests an operator recommends — a different axis from connectivity or naming.

The roadmap

Today's catalog is a single Fly instance with hand-authored manifests and a single permission rule. That's enough to validate the architecture but not enough to be the long-term home of the workspace ecosystem.

What comes next:

  • Auto-publish manifest. The catalog announces itself via a federation manifest at /.well-known/syncropel, including a list of workspace DIDs it publishes. Subscribing daemons replicate updates automatically.
  • Pair primitive. A catalog can pair with another catalog (or a daemon can pair with a catalog) and federate workspace updates without polling. The pair handshake replaces today's "manually configure DNS + emit records" workflow.
  • PARC-gated multi-publisher. Multiple did:sync:* publishers under the same catalog endpoint, each with their own scoped permission rules. The Foundation operates one catalog; community stewards operate others; large enterprises run private catalogs. All speak the same protocol.
  • Browse UI. Today the renderer is the only consumer of the catalog. A future browse surface lets operators discover, preview, and pin workspaces interactively — same primitives, different rendering.

Each step preserves the existing substrate: every catalog ever published is still accessible by content hash, still verifiable against its publisher's signing key, still independent of any specific catalog instance staying online.

Why a curation layer at all

The substrate alone is not enough. A registry containing every workspace manifest the daemon has ever seen is correct, complete, and unhelpful for picking which one to mount on /local/dashboard. Curation is the missing ingredient — and curation is irreducibly opinionated. Someone has to choose what's recommended; someone has to be accountable for the recommendation.

The catalog gives that opinion a shape: it's a record in a substrate, signed by a publisher, addressable by DID, replicated by federation. Disagreement about curation is a disagreement about which catalog to subscribe to — not a disagreement about the substrate. That's the property we wanted: opinion at the edges, mechanism at the core.

On this page