Appearance
Host link schema
The Host Link is the durable record of a paired Device. It exists in two places — one authoritative, one a Device-side mirror — and the two disagree on certain fields by design.
Cloud authority: IHostLinkRecord
Source: projects/matrix-3/packages/system-auth/src/host-auth.ts:94-113.
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | Primary key. hostlink_<24 hex>. Mint per pairing. |
hostId | string | yes | Stable Device identity. host_<20 hex>. Reused across re-pairings of the same install. |
hostName | string | no | Mutable human label. displayName is forbidden. |
deviceSlug | string | yes | Stable address-safe management projection key. |
natsUserPublicKeys | readonly string[] | no | Public keys for the device-scoped NATS user JWTs (audit correlation). |
heartbeatTokenHash | string | no | SHA-256 (base64url) of the plaintext token. The token itself is never persisted. |
heartbeatTokenIssuedAt | string (ISO) | no | Last rotation. |
principalId | string | yes | Owner. p_<20 hex>. |
spaceId | string | yes | Space. space_<20 hex> or spc_<hex>. |
routeKey | string | no | v1 alias for spacePath. |
publicNamespace | string | no | Typed namespace claim, e.g. space.alt.stories. |
authorityRoot | string | yes | Bus / security / runtime authority root. |
scopes | readonly string[] | yes | Sorted, de-duplicated capability list. |
status | 'active' | 'revoked' | yes | Active or revoked. |
createdAt | string (ISO) | yes | Creation time. |
updatedAt | string (ISO) | yes | Last mutation time. |
lastRefreshedAt | string (ISO) | no | Set on refresh / heartbeat-token verify. |
revokedAt | string (ISO) | no | Set on revoke. |
Device mirror: IHiveCastHostLinkRecord
Source: projects/matrix-3/packages/mx-cli/src/utils/hivecast-link-store.ts:19-38.
| Field | Type | Required | Notes |
|---|---|---|---|
version | 1 | yes | Schema version literal. |
cloudUrl | string | yes | Where to post heartbeats. |
deviceRegistryRoot | string | no | Cloud-side device registry routing root, if set. |
hostLinkId | string | no | The cloud's id. |
hostId | string | no | The cloud's hostId. |
principalId | string | no | Owner. |
hostName | string | no | Mutable human label. |
deviceSlug | string | no | Stable management projection key. |
spaceId | string | no | Space. |
routeKey | string | no | v1 alias for spacePath. |
publicNamespace | string | no | Typed namespace claim. |
authorityRoot | string | yes | Bus / security / runtime authority root. |
linkedAt | string (ISO) | yes | When this mirror was written. |
credentials.hostLinkTokenRef | string | no | File reference, e.g. file:credentials/hivecast-host-link-token. |
credentials.registryTokenRef | string | no | File reference if the link issued a registry token. |
credentials.natsCredentialRef | string | yes | File reference, e.g. file:credentials/hivecast-nats.json. |
Differences between cloud and mirror
The mirror intentionally omits these cloud fields:
scopes[]— recorded on the cloud authority for audit; not read by the Device.natsUserPublicKeys— cloud-only correlation aid.heartbeatTokenHash— Device holds the plaintext token; cloud holds the hash.status— Device assumesactiveuntil heartbeats start failing.createdAt,updatedAt,lastRefreshedAt,revokedAt— Device only recordslinkedAtfor its own bookkeeping.
The mirror adds these Device-only fields:
cloudUrl— heartbeat endpoint.deviceRegistryRoot— cloud routing root.linkedAt— when this Device wrote the mirror.credentials.*Ref— local file references rather than inline secrets.
Other auth state shapes (referenced by Host Link)
Pairing also produces and consumes records in these stores:
IHostDeviceLinkRecord
Pending records for the device-code flow.
| Field | Type | Notes |
|---|---|---|
deviceCode | string | base64url, 32 random bytes. |
userCode | string | XXXX-XXXX, 32-char alphabet. |
hostId | string? | Optional pre-known hostId. |
hostName | string? | Suggested label. |
routeKey | string? | Pre-claim. |
scopes | readonly string[] | Capability hint. |
intervalSeconds | number | Poll hint. Default 2. |
createdAt | string (ISO) | |
expiresAt | string (ISO) | createdAt + DEVICE_LINK_DURATION_MS (30 min). |
status | 'pending' | 'approved' | 'namespace_required' | 'exchanged' | 'cancelled' | State machine. |
updatedAt | string (ISO) | |
error | string? | Set when status moves to namespace_required. |
approvedAt | string? (ISO) | |
approvedByPrincipalId | string? | |
hostLinkId | string? | Set when approve mints the Host Link. |
exchangedAt | string? (ISO) | |
cancelledAt | string? (ISO) |
IHostPairingRecord
Pending records for the interactive browser-pair flow. Symmetrically shaped to IHostDeviceLinkRecord but keyed by pairRequestId and includes localReturnUrl, nonce, approvalCode. TTL PAIRING_DURATION_MS = 10 min.
Identity-fields summary
The five-source-of-truth identity table (CLAUDE.md § "Identity lifecycle"):
| Concept | Field | File / location | When generated |
|---|---|---|---|
| Install identity | installId | <host-home>/credentials/hivecast-install.json | First hivecast install |
| Link identity | hostId | <host-home>/credentials/hivecast-link.json | First hivecast login --device |
| Device label | hostName | <host-home>/credentials/hivecast-link.json | Set via --device-name <name> |
| Device projection key | deviceSlug | <host-home>/credentials/hivecast-link.json | Allocated by system-auth |
| (forbidden) | displayName | n/a | n/a — principal/user identity only |
See also
- Device schema — what
system.devicesproduces consuming this record. - Pairing / Host link — narrative.
- Pairing / Pairing grant — wire shape that delivers this to the Device.
Source:
projects/matrix-3/packages/system-auth/src/host-auth.ts(cloud authority);projects/matrix-3/packages/mx-cli/src/utils/hivecast-link-store.ts(Device-side mirror).