Skip to content

Package catalog

The package catalog is the answer to "what can I install?" It is not the answer to "what is running?" — that's system.registry.

Everything in this section is implemented in SystemPackageRegistryActor at projects/matrix-3/packages/system-catalog/src/SystemPackageRegistryActor.ts, mounted as system.packages per projects/matrix-3/packages/system-catalog/matrix.json.

Backing store

The catalog reads a single file:

<registryRoot>/discovery-index.json

Where <registryRoot> is resolved (per SystemPackageRegistryActor.resolveRegistryRoot) as:

  1. The explicit registryRoot argument from the search payload, if given (must be inside MATRIX_HOST_HOME if that env var is set);
  2. Otherwise ${MATRIX_HOST_HOME}/registry;
  3. Otherwise ${cwd}/.matrix/registry.

The file shape is documented in WORKSTREAMS/core-and-packaging/MATRIX-DISCOVERY-METADATA-SPEC.md and implemented by the publish-time index updater in projects/matrix-3/packages/mx-cli/src/utils/discovery-index.ts. The actor only reads it; it does not write or maintain the index.

Single op surface

typescript
// SystemPackageRegistryActor.ts
static override accepts: Record<string, unknown> = {
  'registry.search': {
    description: 'Search installable package discovery metadata from the Matrix package registry index',
    schema: {
      text: 'string?',
      tag: 'string?',
      inferredKind: 'string?',
      declaredKind: 'string?',
      capability: 'string?',
      accepts: 'string?',
      emits: 'string?',
      skill: 'string?',
      shells: 'string?',
      registryRoot: 'string?',
      limit: 'number?',
    },
  },
};

That is the entire actor surface. There is no packages.list, no packages.get, and no packages.install. Listing is search-with-no-filters; fetching is "look up the discovery-index.json directly"; installing is mx-cli's job.

Search semantics

Each search field has a defined behavior in searchIndex / scoreMetadata:

FieldSemantic
textTokens are AND'd. Each token must match at least one collected field. packageName/displayName matches score 5; everything else scores 1.
tagCase-insensitive equality against metadata.tags[].
capabilityCase-insensitive equality against metadata.capabilities[].
inferredKind / declaredKindCase-insensitive equality against scalar field.
shellsCase-insensitive equality against webapp.shells[].
accepts / emits / skillGlob (* wildcard) match against components' accepts[]/emits[]/skills[], case-insensitive.
limit1..100, default 20. Fails with REGISTRY_SEARCH_INVALID outside that range.

Results are sorted by score descending, then packageName ascending, then sliced to limit.

Field collection (the searched corpus)

collectFields (in SystemPackageRegistryActor.ts) flattens this set per package:

packageName, displayName, description, inferredKind, declaredKind,
tag*, capability*,
webapp.appName, webapp.displayName, webapp.description, webapp.shells*,
component.type*, component.exportName*, component.mount*, component.surface*,
component.description*, component.kind*,
component.accepts*, component.emits*, component.skills*,
component.tags*, component.capabilities*

text queries hit the union of those values; field-specific queries hit only the named slice.

What the catalog does NOT know

  • Whether a package is currently installed on this Host.
  • Whether the artifact bytes are reachable.
  • Whether any actors from the package are mounted.
  • Whether the user is authorized to install.

For those questions, use:

QuestionAuthority
Is this installed?filesystem under <host-home>/packages/{system,global}/node_modules/
Are the bytes reachable?artifact registry HEAD (registry.hivecast.ai/.../*.tgz)
Are any actors live?system.registry.registry.list
Am I authorized to install?system-auth (out of scope here)

Latest-version semantics

readLatestMetadata returns one entry per package, keyed by latest version (natural numeric sort across version keys in discovery-index.json). The catalog does not surface multiple historical versions through registry.search today.

Note: Searching across non-latest versions is not implemented in the current actor. If you need a specific historical version's metadata, read discovery-index.json directly. A future packages.versions op is plausible but not in the code today.

See also

Source: projects/matrix-3/packages/system-catalog/src/SystemPackageRegistryActor.ts.