Hosts and where code runs
What a host is, what runs where, and what each kind of host protects.
A host is a machine described lazily
A host is the machine the agent runs on: a way to start processes, a file system, and optionally
port forwarding. Plugs reach the machine only through ctx.host, so the same plug works on the
runner's own machine, over SSH, or in a container.
Hosts connect when first used. A plug that offers a host to the plugs after it describes the machine and does nothing else; the connection, and for some plugs the machine itself, is made when something runs on it. This is why the same description can be offered during a run and during teardown: during teardown, nothing connects unless an inner plug has work to do there.
What runs where
All plug code always runs on the runner, in the run's own process. Only the effects of plugs
happen on the host. A plug listed below ssh still runs its JavaScript on the runner, and its
commands and file operations go to the machine.
| Thing | Runs on |
|---|---|
Plug handlers (onSession, onMessage) | the runner |
| Commands from plugs before a host plug | the runner |
| Commands from plugs after a host plug | the host |
| The agent | the innermost host |
| The runner token and Blaise credentials | the runner only; never given to a host |
Why the runner token never reaches the host
Wrapping the whole runner in a container puts its token next to the agent. With hosts, the token
stays in the runner, and the agent's machine receives only what plugs put in ctx.agent.env. The
agent's messages travel to the runner over the process's input and output.
What each host protects
| Host | Isolation | Outlives the session |
|---|---|---|
| local | none; the agent has the runner's rights | n/a |
sandbox | OS limits on files and network, for the processes it wraps | n/a |
docker | a container, with the isolation of your Docker setup | until teardown |
ssh | the other machine's own account and permissions | yes |
Isolation is a property of the host and of how you configure it. A container with the Docker socket mounted, or a volume of your home directory, is not isolated.
Machines that outlive the session
A machine reached over SSH keeps running when the session pauses, and when the runner crashes. An
agent started there could keep running with nobody listening. Hosts marked persistent start the
agent under a small supervisor that ends it when the SSH session process is gone. It checks every
two seconds, asks the agent to stop, and kills it two seconds later.
Why the file system is the same everywhere
The fs of every host follows the node:vfs interface, including the local one. A plug that reads
a config file does not care where the machine is. The cost is the sync methods: on a remote host
they need a second connection in a worker thread, and each call waits for the network. Use
fs.promises.
The runner uses node-vfs-polyfill, pinned to a GitHub commit. A small import module exports the
polyfill's JavaScript implementation with the native VFS types from @types/node 26. The host
adapter adds promises.rm, promises.mkdtemp and promises.truncate using provider operations on
every host.