BlaiseBlaise
Documentation
Runner and PlugsExplanation

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.

ThingRuns on
Plug handlers (onSession, onMessage)the runner
Commands from plugs before a host plugthe runner
Commands from plugs after a host plugthe host
The agentthe innermost host
The runner token and Blaise credentialsthe 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

HostIsolationOutlives the session
localnone; the agent has the runner's rightsn/a
sandboxOS limits on files and network, for the processes it wrapsn/a
dockera container, with the isolation of your Docker setupuntil teardown
sshthe other machine's own account and permissionsyes

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.

On this page