Appearance
What is a Runtime Host?
In docker-for-actors terms, the Host is the substrate's docker-engine. It does five things:
- Owns one local NATS bus (either a sibling
nats-serverit manages, or a pre-existing external NATS at a configured URL). - Spawns runtimes as child processes. A runtime is a Node process that hosts one or more Matrix packages — a substrate for actors, not "the runtime for one specific package."
- Records their lifecycle in
<host-home>/runtimes/<id>/runtime.jsonfiles so they survive Host restarts. - Recovers auto-start runtimes after a Host crash, including parse-and-skip over corrupt records.
- Exposes a control interface over NATS (
host.controlmailbox) and over a CLI (matrix status,matrix runtimes,matrix up,matrix down).
The implementation is MatrixHostService in projects/matrix-3/packages/host-service/src/matrix-host-service.ts. The public CLI is projects/matrix-3/packages/host-service/src/cli.ts.
Multi-package runtimes (target shape)
A package's matrix.json declares an isolation level; the Host honors it when accepting deployments:
runtime.isolation | What it is | When to use | Cost |
|---|---|---|---|
shared | Co-tenanted in any compatible runtime; one Node process, one V8 heap | Trusted first-party; control-plane services; lightweight utilities | ~free per additional package |
process | Own Node process; no co-tenancy | Untrusted third-party; native deps; independent crash domain | ~50-100 MB per package |
worker | Node worker thread inside a host runtime; separate V8 isolate, shared OS process | Semi-trusted; CPU-bound work | ~5-15 MB + startup latency |
vm | vm.runInContext sandbox in same process; same heap, separated globalThis | Trusted-but-buggy; limit blast-radius; not a security boundary | marginal |
Default when absent: process (preserves today's one-package-per-runtime behavior; no breaking change).
Status: target state — ships with P1.40-a. Today the codebase implements one package per runtime. The substrate target shape is multi-package runtimes per P1.40. When P1.40-a lands, default-runtime grouping co-tenants
sharedpackages by substrate role (CONTROL-PLANE,USER-APPS); a fresh Host comes up with ~4 runtimes instead of 12.
What a Host does NOT do
The Host is intentionally narrow. The full constraint set lives in projects/matrix-3/packages/docs/content/architecture/host-service-boundary-rule.md.
| The Host does NOT | Why | Where it lives instead |
|---|---|---|
Instantiate MatrixActor or MatrixRuntime in its own process | Isolation. One bad actor cannot crash the supervisor. | inside spawned runtime processes |
| Implement HTTP, REST, or browser routing | HTTP is one transport, not a Host concern. | @open-matrix/system-gateway-http |
| Implement OAuth, sessions, or device approval | Auth is product policy, not supervision. | @open-matrix/system-auth |
| Render UI | Supervisors do not have UIs. | @open-matrix/matrix-web, @open-matrix/matrix-edge |
| Hold credentials beyond the local NATS handshake | Factotum (system.factotum) owns credentials. | system.factotum package |
| Know about specific packages by name | Generic. The Host does not import chat, director, etc. | the supervised package itself |
| Serve inventory questions over HTTP | Inventory is bus authority. | system.runtimes, system.registry, system.devices |
A Host that grows any of these duties is broken. The hivecast.deb installer and the default hivecast install set ship the gateway, auth, web, and edge packages as supervised runtimes; they are not part of the Host.
What a Host owns
A Host owns the contents of its home directory, which defaults to ~/.matrix on Linux and macOS, %USERPROFILE%\.matrix on Windows, or /var/lib/hivecast on a .deb-installed Linux service. See Filesystem layout for the complete inventory. Quick map:
<host-home>/
host.json host config (single source of truth)
host.status.json current Host status (atomic-written)
host.pid supervisor pid
runtimes/<id>/runtime.json per-runtime durable record
runtime-env/<id>.environment.json per-runtime env file (transport, mounts)
logs/ host stdout/stderr + nats logs
logs/runtimes/<id>/{stdout,stderr}.log
packages/system/node_modules/ system package store (seeded)
packages/global/node_modules/ user-installed package store
bin/nats-server[.exe] bundled NATS binary
nats/host-default/ JetStream data dir + nats-server.conf
credentials/hivecast-install.json install identity (always present)
credentials/hivecast-link.json Device Link record (only when linked)
instances/<instanceId>/ per-DeploymentInstance state directory
(target state — P1.42)Status: target state —
instances/<instanceId>/directory. Today instance state collides underruntimes/<runtimeId>/because each runtime hosts one package. P1.42 introduces DeploymentInstance as a first-class registry citizen with its own state dir. See P1.42.
A minimal Host run
bash
node projects/matrix-3/packages/host-service/dist/cli.js init --home /tmp/h
node projects/matrix-3/packages/host-service/dist/cli.js start --home /tmp/h --port 0
node projects/matrix-3/packages/host-service/dist/cli.js status --home /tmp/h
node projects/matrix-3/packages/host-service/dist/cli.js runtimes --home /tmp/h
node projects/matrix-3/packages/host-service/dist/cli.js stop --home /tmp/hIn production this is wrapped by hivecast install / hivecast start / hivecast stop, which additionally seeds the system package store, supervises NATS as an independent sibling process, and starts the default runtime set (see projects/matrix-3/packages/hivecast/bin/hivecast.mjs:28-39).
See also
- Host vs runtime
- Host vs device
- Host lifecycle
- Filesystem layout
- Host control plane
- P1.40 — Docker-for-actors / multi-package runtimes
Source: the boundary rule is the architectural constraint; the code is the truth. See
host-service-boundary-rule.mdandmatrix-host-service.ts:58-1056.