The daemon opens a single persistent outbound WebSocket to the Halyard
control plane and keeps it open. There is no inbound network surface on the
node — nothing listens for connections, and there is no broker in between. Over
that one connection the node:
registers itself and advertises its capacity;
heartbeats so the control plane knows it is healthy;
receives dispatches and streams live output back.
If a node goes offline, its sessions stay queued; the control plane dispatches
them the moment the node reconnects and reports capacity — durable-queue
behavior without a queue to operate. A node that stops heartbeating past the
timeout is marked offline and its in-flight sessions are unstuck.
Once the binary is on the machine, a single command sets everything up:
Terminal window
sudohalyard-nodeinstall\
--control-url<url>--bootstrap-token<token>
That copies the binary to /usr/local/bin/halyard-node, creates /opt/halyard,
registers a systemd service (launches the daemon on boot, restarts it if it
exits), enrolls the node, and starts it — so it reports online within seconds.
After a reboot or a transient failure it recovers on its own, no manual restart.
Manage it like any service: systemctl start|stop|status halyard-node, and read
its logs with journalctl -u halyard-node.
The daemon is semantically versioned. To upgrade, download
the latest binary and re-run install — it detects the version already
installed, replaces it in place, and restarts the service:
It prints what it’s doing — for example upgrading halyard-node 0.1.0 → 0.2.0 —
and keeps the node’s existing identity, so no re-enrollment is needed. Re-running
the same version is a harmless no-op. Check the running version any time with
halyard-node version (or systemctl status halyard-node).
Prefer two steps? Run sudo halyard-node install on its own to set up the
service without enrolling — it then waits, harmlessly retrying, until you run
halyard-node enroll --control-url <url> --bootstrap-token <token> separately.
No sudo on that second command: install already handed /opt/halyard to
your account.
Re-installing or re-enrolling? If this machine was enrolled before —
you deleted the node in the app and want to register it again, say — its old
identity is still on disk. Re-run install with a new bootstrap token and
it notices the existing enrollment and asks before overwriting it:
Terminal window
sudohalyard-nodeinstall\
--control-url<url>--bootstrap-token<new-token>
# This node is already enrolled (node_id=…). Overwrite it and re-enroll
# with the new token? … [y/N]
Answer y to discard the old identity and enroll fresh; anything else keeps
the existing one untouched. For an unattended overwrite (scripts, config
management — where there’s no terminal to answer the prompt), pass --force
to skip the confirmation:
Without a new token, a plain re-run always keeps the existing identity, so
upgrading the daemon never disturbs a live enrollment.
Agent CLIs such as claude often live in your ~/.local/bin. The installed
service puts that directory on its PATH so the daemon can find them; if you
install the CLI somewhere unusual, adjust the unit’s Environment=PATH= line.
A node belongs to an enclave. Sessions are only ever
scheduled onto nodes within the project’s enclave, so an agent working a
public repo can never land on a machine that holds corporate credentials.
Each session chooses how its workspace is set up on the node:
Host directory — the agent works directly in an existing directory on the
machine, reusing already-configured toolchains and build state.
Containerized — the node provisions an ephemeral environment from a
Dockerfile or Docker Compose, mounts the cloned repository, and tears it down
when the session ends.
Bring nodes online and offline and watch their health and capacity under
Nodes in the app. Once a node is online in your project’s enclave, you can
dispatch an agent onto it.