Skip to content

What is Matrix?

Matrix is docker-for-actors / npm-for-actors. Same shape as Docker and npm, mapped onto a typed actor system. You publish a Package; a Runtime hosts it as a DeploymentInstance; the instance's actors live at typed Mounts on a pub/sub/RPC bus.

Docker / npm worldMatrix substrate
Image / npm package you publishPackage (@open-matrix/<x>)
Registry (Docker Hub, npm)Gitea (Matrix-native) or HiveCast-hosted package registry
Container (the running thing)DeploymentInstance (a running copy of a Package)
Engine (the runtime that runs containers)Runtime (a Node process that hosts actors)
Host machine (the box that runs engines)Host (the user's laptop, VPS, workstation)
Inter-container commsNATS subjects, typed bus messages
Isolation declaration (seccomp, namespaces)matrix.json runtime.isolation field
docker run --name foo <image>matrix deploy <package> --instance-name foo

Strip the jargon and the substrate is one thing: a typed pub/sub/RPC fabric where every Feed, every Service, and every Component is the same primitive — a typed actor on a federated bus — and where any consumer can find, install, instantiate, and meter those primitives across machines, organizations, registries, languages, and execution environments.

Three primitive types every actor is one of:

  • Feed — publishes a stream (market ticks, news events, sensor data, LLM token streams, file-change events, heartbeats).
  • Service — responds to requests (inference, database query, image transform, translation, code search, OCR, RPC call).
  • Component — consumes feeds, calls services, optionally has a UI surface (charts, dashboards, form widgets, whole pages, an agent's reasoning loop).

All three are typed (declared accepts / emits / streams), all three have identity (a Space-rooted bus address), all three are discoverable (through the capability catalog), all three can be instantiated on demand and metered.

Source: the substrate framing is normative in WORKSTREAMS/thesis/THESIS.md Parts 1–2; the docker-for-actors mapping is the central pitch documented in P1.40. The 1990s precedent is COM/COM+ apartment models — the object declares its threading model (Apartment / Free / Both / Neutral); the activator honours it.

What an address looks like

matrix://richard-santomauro@gmail.com/chat
matrix://jane@acme.com/support-agent
matrix://amazon.com/product-search
matrix://nimbletec.com/sales

The grammar is matrix://<user>@<domain>/<path> (or matrix://<domain>/<path> for organization-rooted addresses). The address resolves deterministically to a NATS subject prefix:

Email or domainWire root
richard-santomauro@gmail.comCOM.GMAIL.RICHARD-SANTOMAURO
jane@acme.comCOM.ACME.JANE
amazon.comCOM.AMAZON

Reverse the domain, uppercase, append the username (uppercase, hyphens preserved). No lookup table. No DNS-of-actors database. The address is its own resolver.

Note: gmail.com resolves to COM.GMAIL, not COM.GOOGLE. Email providers are NOT canonicalized; the domain is taken verbatim. This is a hard rule because Hosts discover each other via this prefix; a mismatch breaks every cross-root call.

The eight-point specification

Source: WORKSTREAMS/matrix-protocol/MASTER-PLAN.md Part 1 ("The spec").

  1. Addressingmatrix://user@domain/path.
  2. Resolution — email → reverse DNS → NATS subject (deterministic).
  3. Transport — NATS (WebSocket for browsers, TCP for Host-to-Host).
  4. Federation — NATS leaf nodes between providers (outbound only, no open ports).
  5. Discovery$introspect on any actor returns what it accepts, emits, and contains.
  6. Messaging{op, payload, id} JSON envelope on $inbox topics.
  7. Identity — OIDC (Google, enterprise SSO, any provider).
  8. Permissions — NATS ACL per root, capability-based grants.

Eight points. Shorter than HTTP/1.1.

Why this is a real protocol

Matrix sits in a gap that HTTP, SMTP, and REST do not fill:

CapabilityHTTPSMTPRESTMatrix
Addresses serversyesnoyesyes
Addresses mailboxes / actorsnoyesnoyes
Pub/subnononoyes
Request/responseyesnoyesyes
Self-describing schema at runtimenonosometimesyes ($introspect)
Federation across providersyesyesyesyes
Same address from browser, CLI, agent, gRPCnononoyes

A single Matrix address is reachable from a browser (which renders the actor's web view), a CLI (which invokes its ops), an LLM agent (which uses it as an MCP tool), a gRPC client (which calls typed protobuf methods), and another actor (which pub/subs over NATS). The underlying transport (NATS) supports request/reply AND pub/sub natively, which is why the same address works for all of them.

Three execution tiers

The substrate runs code in three places (full detail in thesis Part 2):

  • Tier 1 — Local Runtime. A Host the user owns and operates: laptop, workstation, VPS, on-prem server. Holds OAuth tokens, talks to local databases, drives a COM object or Win32 API. Long-running.
  • Tier 2 — Hosted Runtime. A Host that the user does not own personally — a self-hosted VPS, a HiveCast-managed Host, or eventually an on-demand edge runtime (Cloudflare Workers, AWS Lambda, Modal). Same Host code; just different ownership.
  • Tier 3 — External Connectors. Packages that wrap a foreign ecosystem (system.com, system.win32, future system.npm, system.pypi, system.openapi, system.dotnet). Each connector exposes that ecosystem's registry and APIs as Matrix actors.

Status: tiered execution at maturity. Tier 1 ships in v0. Tier 2 hosted Hosts ship in v0/v1; on-demand edge providers are post-v1. Tier 3 connectors land per-package, with system.com and system.win32 wrapped in v0.5. See THESIS.md Part 8 (Roadmap).

Account root vs runtime root

Identity is permanent. Where it runs is not.

COM.NIMBLETEC.RICHARD-SANTOMAURO              ← account root, forever
COM.NIMBLETEC.RICHARD-SANTOMAURO.TABLET       ← runtime: laptop right now
COM.NIMBLETEC.RICHARD-SANTOMAURO.SILO-7       ← runtime: HiveCast hosting
COM.NIMBLETEC.RICHARD-SANTOMAURO.P53          ← runtime: another machine

matrix://richard-santomauro@nimbletec.com/chat resolves to the account root. The routing layer sends it to whichever runtime is currently active. Switch machines, switch providers — the address never changes. This separation of account root (durable identity) from runtime root (current process) is what the addressing pages develop in detail. See Authority roots and Runtime wire roots.

What you actually get when you build on Matrix

For each actor a package author writes:

  • A canonical NATS subject prefix is allocated ({root}.{mount}.$inbox, $events, $state).
  • $introspect returns the actor's full surface — accepts, emits, streams, state, subscribes, blackboard — without any extra registration step (projects/matrix-3/packages/core/src/core/MatrixActor.ts).
  • The runtime registers a logical mount claim with system.registry and a physical record with system.runtimes.
  • The HTTP gateway exposes the actor at /{spacePath}/{appName}/ if a webapp surface is declared. Inventory queries (apps, devices, runtimes, packages, mounts) are bus invocations, not HTTP endpoints — the closed list of allowed HTTP boundaries lives in P1.43. Where a target adapter (REST/OpenAPI, gRPC, AsyncAPI, MCP) is documented, see Protocol Adapters.

The package author writes one class. The protocol gives them registration, discovery, control, observability, and the entire adapter surface for free.

What is NOT in scope here

  • The product launch path (Device enrollment, Host installation, OAuth flows) is in WORKSTREAMS/product-launch/ and the docs-hivecast package.
  • Inference adapters, chat semantics, the cognitive director — these are packages built on the protocol, not part of the protocol itself.
  • The viral signup, billing, and federation provider model — these are HiveCast-the-product, not Matrix-the-protocol.

See also

  • Actors — what every actor declares about itself.
  • Subjects — how the wire grammar encodes addresses.
  • Mounts — three names every live thing has.
  • Authority roots — account vs runtime vs Space identity stack.
  • $introspect — how an agent discovers an actor's full interface.