Sidecar
The supervisor process that runs inside each sandbox.
Overview
The sidecar is a single Node.js process that runs inside the sandbox as a detached process. It has four responsibilities: supervising the agent daemon, sending heartbeats, serving health checks, and installing tools.
Initialization order
The sidecar starts its subsystems in a specific order:
- Health server. Starts first on port 3001, since the parent begins polling immediately after launching the sidecar
- Supervisor. Spawns the agent daemon and begins port probing
- Heartbeat. Sends an immediate first tick, then continues every 60 seconds
- Tools. Installs required tools in the background (non-blocking, fire-and-forget)
Supervisor
The supervisor spawns and monitors the agent daemon:
- Starts the daemon process (e.g.,
zeroclaw serve --port 3000 --host 0.0.0.0) - Monitors via TCP port probe every 500ms, checking if the daemon is listening
- Restarts on crash after a 2-second delay, up to 5 times. The counter resets after 60 seconds of stable operation. After 5 failed restarts, the daemon status is reported as
"failed"and the lifecycle manager stops the sandbox. - Reports daemon status in each heartbeat
- Shutdown sends
SIGTERMto the daemon and waits up to 5 seconds for graceful exit
If the daemon hasn't started listening after 3 seconds, the supervisor logs a warning but continues probing. This is not a hard timeout.
Heartbeat
Every 60 seconds, the sidecar POSTs to the parent server:
{
"sandboxId": "sbx_abc123",
"lastChangedAt": 1710000000000,
"sandboxCreatedAt": 1709990000000,
"root": "/home/user",
"daemonStatus": "running",
"daemonRestarts": 0
}lastChangedAtis epoch milliseconds (number), tracking the most recent filesystem modification. Used by the file-activity extend reason.sandboxCreatedAtis epoch milliseconds (number), used by the grace-period extend reason.daemonStatusis one of"starting","running","stopped", or"failed".
The parent uses this to decide whether to extend the sandbox TTL or snapshot and stop. If daemonStatus is "failed", the parent stops the sandbox immediately.
Health server
An HTTP health server runs on port 3001 inside the sandbox:
{
"ok": true,
"daemon": {
"status": "running",
"pid": 1234,
"restarts": 0
},
"heartbeat": {
"lastTick": 1710000060000,
"lastSuccess": true
},
"uptime": 3600
}okistruewhen the daemon status is"running".daemonreports the current daemon process state.heartbeattracks the last heartbeat tick time (epoch ms) and whether it succeeded.uptimeis seconds since the sidecar started.
The parent polls this endpoint during startup to verify the sandbox is healthy.
Tools
The sidecar handles tool installation inside the sandbox at startup. When the agent requires external tools (e.g., a browser), the sidecar provisions them in the background.
- Installation is retried up to 3 times with a 5-second delay between attempts
PATHis augmented with~/.local/binfor tools installed to the user's local directory- Tool installation is non-blocking. If all attempts fail, the sidecar logs a warning and continues without the tool
Configuration
The sidecar receives its configuration as a JSON file written into the sandbox. The heartbeat secret is passed via the CLAWRUN_HB_SECRET environment variable (not in the command line, for security).
Logging
The sidecar logs to {root}/logs/sidecar.log inside the sandbox. Daemon output is captured and prefixed:
- stdout lines are prefixed with
[daemon:out] - stderr lines are prefixed with
[daemon:err]