Appearance
Runtime records
A runtime record is a JSON file at <host-home>/runtimes/<sanitizedRuntimeId>/runtime.json. It is the durable state for one supervised runtime. Bus-side surfaces project from it; the Host process reconstructs in-memory state from it on restart.
Schema: Runtime record schema.
Who writes it
Only the Host process writes runtime records. Six paths reach HostStateStore.writeRuntimeRecord (host-state-store.ts:90-95):
| Caller | When | What changes |
|---|---|---|
startRuntimeProcess | on successful spawn | full record with status: "running", pid, startedAt |
| readiness probe failure | spawn ok but runtime.ready did not respond | status: "failed", failedReason, log tail |
child.exit handler | runtime exited unexpectedly | status per exit code/signal, stoppedAt, exitCode, signal |
stopRuntimeProcess | matrix down | first status: "stopping", then status: "stopped", stoppedAt |
_refreshRuntimeRecordLiveness | any time listRuntimeRecords runs | mark stale records failed with reason |
_refreshRuntimeEnvironmentFile | Host start, config reload | rewrite runtimeWireRoot, metadata.transport, envFileRefreshedAt |
All writes go through atomicWriteJson. The record is consistent at every moment; readers cannot observe a half-written file.
Who reads it
| Reader | Why |
|---|---|
| Host bootstrap | recover auto-start runtimes after a Host restart |
matrix status / matrix runtimes | report inventory to operators |
host.control heartbeat | publish to system.devices.devices.runtimes.register |
| Out-of-band tools | inventory and health checks that bypass the bus |
The Host always reads through HostStateStore.listRuntimeRecordsAndCorrupt which never throws, so a single bad record does not blind the Host.
Anatomy
json
{
"runtimeId": "RUNTIME-HOST-LOCAL-ABC123-CHAT",
"packageRef": "@open-matrix/chat",
"packageDir": "/home/me/.matrix/packages/system/node_modules/@open-matrix/chat",
"environment": "host",
"pid": 41522,
"status": "running",
"startup": "auto",
"restart": "always",
"startedAt": "2026-05-04T18:21:01.103Z",
"updatedAt": "2026-05-04T18:21:02.991Z",
"runtimeMount": "system.runtimes.RUNTIME-HOST-LOCAL-ABC123-CHAT",
"controlMount": "system.runtimes.RUNTIME-HOST-LOCAL-ABC123-CHAT.control",
"runtimeWireRoot": "COM.OPEN-MATRIX.LOCAL.AUTHORITY",
"localMounts": [
"chat",
"system.runtimes.RUNTIME-HOST-LOCAL-ABC123-CHAT",
"system.runtimes.RUNTIME-HOST-LOCAL-ABC123-CHAT.control"
],
"metadata": {
"source": "matrix-cli",
"target": "@open-matrix/chat",
"envFile": "/home/me/.matrix/runtime-env/RUNTIME-HOST-LOCAL-ABC123-CHAT.environment.json",
"command": "/usr/bin/node",
"args": ["/opt/hivecast/dist/.../mx-cli/dist/index.cjs", "run", "...", "--serve", "--env", "host", "--env-file", "..."],
"cwd": "/home/me/.matrix/packages/system/node_modules/@open-matrix/chat",
"logDir": "/home/me/.matrix/logs/runtimes/RUNTIME-HOST-LOCAL-ABC123-CHAT",
"controlReadyTimeoutMs": 30000,
"transport": { ... },
"webapp": { "appName": "chat", "routePrefix": "/apps/chat/", "port": 5183, "origin": "http://127.0.0.1:5183", ... },
"autoStartReason": "host-autostart",
"autoStartOrdinal": 6
}
}The metadata block is where most of the per-runtime detail lives; schema-wise it is a free-form Record<string, unknown> so that operators can store whatever the runtime found useful at start time. The Host itself adds standard keys (command, args, cwd, logDir, autoStartReason, etc.) and reads them back on restart.
Editing records by hand
The Host re-reads records on every operation and re-writes them on every transition. Editing a record by hand is safe only when the Host is stopped:
bash
hivecast stop --home <home>
$EDITOR <home>/runtimes/<sanitizedId>/runtime.json
hivecast start --home <home>Common edits:
- Toggle
startup:"auto"↔"manual"to keep an unhealthy runtime out of the auto-start sweep. - Toggle
restart:"always"↔"never"to break a respawn loop. - Delete the directory entirely: retire a runtime fully.
What you must not edit:
runtimeId— the directory name and the field must match.pid— the Host re-validates against process-table reality.runtimeWireRoot— gets overwritten by the Host on next start anyway.
Cleanup
Empty runtime.json (zero bytes) is the original 22-hour crash-loop bug. If hivecast seed reports it, you can either:
- Delete the runtime directory and re-create the runtime via
matrix up. - Leave it; the next Host start will overwrite it from desired state if the runtime is auto-start.