Appearance
Pair
This runbook walks through pairing a clean local install against a HiveCast cloud (production https://hivecast.ai or a sibling Host playing the platform role).
Prerequisites
A working local install:
bash
# Build the wrapper and supporting packages, in source-checkout layout:
pnpm install
pnpm --filter @open-matrix/host-service build
pnpm --filter @open-matrix/host-control build
pnpm --filter @matrix/mx-cli build
pnpm --filter hivecast build
# Install + start a fresh local Host:
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs install --home /tmp/matrix-home
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs start --home /tmp/matrix-home
# Verify it's running:
curl -fsS http://127.0.0.1:3100/healthz | jq .
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs status --home /tmp/matrix-homeYou should see a healthy Host with the default runtimes (system, host-control, system-gateway-http, matrix-web, matrix-edge) listed.
Pairing — headless device-code flow
bash
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs login \
--device \
--cloud https://hivecast.ai \
--device-name "richard-laptop" \
--home /tmp/matrix-homeWhat you see:
Starting device pairing against https://hivecast.ai
User code: ABCD-EFGH
Open this URL to approve:
https://hivecast.ai/devices/connect?user_code=ABCD-EFGH
Polling for approval... (interval: 2s, expires in 30 min)In a separate browser session:
- Navigate to the URL the CLI printed (or to
https://hivecast.ai/devicesand enterABCD-EFGHmanually). - Sign in (Google / GitHub / your enterprise IdP).
- If your principal has no Space yet, the page asks you to claim a Space-path. (You can also pre-supply one with
--route-key <key>.) - Click "Approve".
The CLI returns:
Approved by principal p_<sha20>.
Exchanging device code for credentials...
Device linked.
hostName: richard-laptop
deviceSlug: richard-laptop
hostLinkId: hostlink_<24 hex>
authorityRoot: SPACE.SPC-<hex>
cloudUrl: https://hivecast.ai
Credentials written to /tmp/matrix-home/credentials/.Pairing — dev mode against a sibling Host
For dev work without a production HiveCast, point --cloud at a sibling Host that plays the platform role (typically a matrix-web runtime running on 127.0.0.1:3100):
bash
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs login \
--device \
--cloud http://127.0.0.1:3100 \
--route-key codex-proof-$(date -u +%Y%m%d-%H%M) \
--home /tmp/matrix-homeThe pairing protocol is identical; the cloud is just played by the sibling Host. The prove-fresh-device-link.ts script under projects/matrix-3/scripts/ automates this.
Verify the pairing
bash
# From the Device side:
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs whoami --home /tmp/matrix-home
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs link-status --home /tmp/matrix-home
# From the cloud side, list this principal's Devices:
matrix invoke system.devices devices.list \
'{"principalId":"p_<sha20>","includeOffline":true}'Expected results:
whoamiprintsprincipalId,hostName,deviceSlug,installId,cloudUrl.link-statusprintslinked: true,hostConfigLinked: true,natsCredentialsPresent: true.devices.listreturns a record withsource: 'merged'(after the first heartbeat) orsource: 'host-link'(before the first heartbeat arrives — usually <1s).
Files written
After pairing, <host-home>/credentials/ contains:
hivecast-install.json (mode 0o600 — installId)
hivecast-link.json (mode 0o600 — link mirror)
hivecast-nats.json (mode 0o600 — device-scoped NATS user JWT + seed)
hivecast-host-link-token (mode 0o600 — heartbeat bearer token, single line)And <host-home>/host.json is rewritten so its transport block points at the cloud NATS URL with mode: 'external'.
What if pairing fails
| Symptom | Cause | Fix |
|---|---|---|
Error: cloud endpoint unreachable | The --cloud URL is wrong, the cloud is down, or the local network blocks it | Verify URL + reachability with curl <cloud>/healthz |
Approval required: principal has no Space — claim a Space-path first | Principal has not yet claimed any namespace | Re-run with --route-key <key>, or approve a namespace claim in the cloud UI first |
| Polling times out | The user did not approve within 30 min | Re-run hivecast login --device |
User code expired | Approval not completed within DEVICE_LINK_DURATION_MS | Re-run |
Setup-exchange failed: hostId already linked under different principal | A previous pairing left an active link for this hostId under a different account | Use hivecast logout --revoke-cloud-link against the original account, or contact your HiveCast admin |
See also
- Pairing / Login — what
logindoes op-by-op. - Pairing / Device flow — the device-code protocol detail.
- Disconnect — running it back.
- Troubleshoot — symptom-driven recovery.
Source:
projects/matrix-3/packages/hivecast/bin/hivecast.mjs(dispatch);projects/matrix-3/packages/mx-cli/src/utils/hivecast-link-store.ts(saveHiveCastHostLink()); CLAUDE.md § "Host Service / Docker-NPM parity dev loop".