Appearance
Device vs host
Host and Device are two different things in this code base. They are 1-to-1 today; they are not the same concept.
Definitions
Host is a process supervisor. Concretely: the @open-matrix/host-service package. It is Docker Desktop for Matrix runtimes. A Host:
- starts and stops package runners as supervised child processes
- starts shared local NATS when configured
- persists runtime records under
<MATRIX_HOME>/runtimes/ - exposes a control protocol via
@open-matrix/host-control - exposes HTTP routes via
@open-matrix/system-gateway-http
A Host has its own identity: a host.json config file at the root of <host-home>, plus a per-install identity file at <host-home>/credentials/hivecast-install.json containing installId. That identity exists whether or not the Host is paired.
Device is a linked compute participant on a HiveCast account. The Device record only exists once hivecast login --device (or an equivalent pairing flow) has succeeded. The Device contract lives in system.devices and system.auth.hostLinks.
Why we keep them separate
The product-launch spec (HIVECAST-DEVICE-ENROLLMENT-SPEC.md § "Current Install Identity Boundary") spells this out:
Do not pretend [
installId] is a complete physical-device model. A physical machine can eventually group multiple local installs, containers, or service stacks. Today the product-visible device id maps to the stable install identity; later a separate physical-device grouping layer can sit above it.
Today: one Host install = one Device. Tomorrow: one physical machine may host multiple Host installs (containers, VMs, alternate environments), each of which is a separate Device. The product is built so the language can absorb that change without renaming everything.
Identity layering
The mapping is:
text
physical machine
|
+-- Host install A (installId: install_aaa…)
| |
| +-- Host Link (hostId: host_aaa…, hostLinkId: hostlink_…)
| |
| +-- Device record (deviceId = hostId, deviceSlug = laptop)
|
+-- Host install B (installId: install_bbb…)
|
+-- Host Link (hostId: host_bbb…, hostLinkId: hostlink_…)
|
+-- Device record (deviceId = hostId, deviceSlug = laptop-2)In the current code, that physical-machine grouping does not exist. Each Host install gets its own installId and pairs to its own Device. Slug collisions within one principal's Space are handled by allocateDeviceSlug() (suffix -2, -3, …) in system-auth/src/host-auth.ts.
What lives where
| Artefact | Belongs to Host | Belongs to Device |
|---|---|---|
<host-home>/host.json (config) | yes | n/a |
<host-home>/host.status.json (live status) | yes | n/a |
<host-home>/runtimes/<runtime-id>/runtime.json | yes | indirectly — runtimes show up under a Device when the Host is linked |
<host-home>/credentials/hivecast-install.json (installId) | yes | n/a |
<host-home>/credentials/hivecast-link.json (hostLinkId, hostId, …) | yes (it's local) | yes (it IS the Device link) |
<host-home>/credentials/hivecast-host-link-token | yes | yes (proof for heartbeats) |
<host-home>/credentials/hivecast-nats.json | yes (it's local) | yes (the device-scoped credential) |
Cloud-side hostLinks[] row in system.auth | n/a | yes |
Cloud-side system.devices record | n/a | yes |
Files in the left column exist on every Host. Files in the right column only exist after pairing.
Local-only Hosts
A Host can exist without ever being paired to a HiveCast account. This is the "local-only" mode: hivecast install + hivecast start + no hivecast login. In that mode:
installIdexists.hostLinkId,hostId,principalId,spaceId,authorityRootare absent.system.devicesshows zero linked devices.system.auth.hostLinkshas no row.
A local-only Host is not a Device. It has runtimes, packages, and an HTTP gateway, but it has no account-facing inventory presence. This is by design: "Local mode" and "Connected mode" are explicit product states (see HIVECAST-DEVICE-ENROLLMENT-SPEC.md § "Product Summary").
When you actually need both terms
You need to use "Host" (not "Device") when you are talking about:
- starting/stopping the supervisor (
hivecast start,hivecast stop) - runtime records and runtime supervision
- the local HTTP gateway
- the local config file
host.json - the install identity
installId - bootstrap, seeding, or self-healing of the supervisor
You need to use "Device" (not "Host") when you are talking about:
- inventory listing on an account dashboard
- pairing or unlinking against HiveCast
system.devicesandsystem.auth.hostLinks- the heartbeat that posts
Bearer <hostLinkToken>to/_auth/host-link/heartbeat
See also
- Device model — the formal definition of a Device.
- Device vs runtime — what a Device contains.
- Pairing / Login — what
hivecast loginactually does and which artefacts it writes.
Source:
WORKSTREAMS/product-launch/HIVECAST-DEVICE-ENROLLMENT-SPEC.md§ "Current Install Identity Boundary";projects/matrix-3/packages/mx-cli/src/utils/hivecast-link-store.ts(path layout);projects/matrix-3/packages/system/src/SystemDevicesActor.ts.