export const meta = {
  title: 'System Process',
  description: 'Run executions as host OS processes with worker-sys.',
  section: 'Runtimes',
  order: 46,
  slug: 'worker-sys',
}

# System Process Runtime

`worker-sys` executes code directly as host OS processes without any container isolation. This is suitable for real-device control or scenarios where direct host access is required.

The current version of `worker-sys` is feature-complete in terms of capabilities and implementation. However, given its dangerous nature, we will not mark it as production-ready in the near term.

## When to use

- You need direct access to host hardware or peripherals
- Container overhead is unacceptable
- You are running on a dedicated, trusted machine
- OpenClaw-like scenarios

> **Warning:** `worker-sys` provides no sandbox isolation. Terminal commands execute directly on the host. Only run it on dedicated machines.

## How it works

1. The worker connects to the control node over gRPC.
2. Execution requests are spawned as native OS processes on the host.
3. Process stdout/stderr is streamed back through the control plane.

### Shell selection (cross-platform)

`computerUse` runs commands through the host's system shell. The shell is selected per platform:

- Linux / macOS: `/bin/sh -lc <command>`
- Windows: `powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command <command>`, with `[Console]::OutputEncoding` and `$OutputEncoding` forced to UTF-8 so output is not garbled on systems whose default code page is not UTF-8 (e.g. GBK on Chinese Windows).

When deploying a Windows worker, entries in `WORKER_COMPUTER_USE_COMMAND_WHITELIST` must be in PowerShell form (e.g. `Get-ChildItem`, `Get-Process`) — Unix-style commands such as `ls` or `cat` will not match. The whitelist is matched as a literal prefix/exact string and must align with whatever shell the worker's platform uses.

## Prerequisites

- Network access to the control node gRPC endpoint
- Appropriate OS-level permissions for the workloads you intend to run

## Starting the worker

Download the latest `worker-sys` binary from the [GitHub releases page](https://github.com/Coooolfan/onlyboxes/releases/latest), then run:

```bash
WORKER_CONSOLE_GRPC_TARGET=<console_grpc_target> \
WORKER_ID=<worker_id> \
WORKER_SECRET=<worker_secret> \
./onlyboxes-worker-sys
```

Set `WORKER_CONSOLE_INSECURE=true` when connecting without TLS.

Windows / PowerShell startup example:

```powershell
$env:WORKER_CONSOLE_GRPC_TARGET = "<console_grpc_target>"
$env:WORKER_ID = "<worker_id>"
$env:WORKER_SECRET = "<worker_secret>"
.\onlyboxes-worker-sys.exe
```

## Environment variables

### Connection

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `WORKER_CONSOLE_GRPC_TARGET` | No | `127.0.0.1:50051` | Control node gRPC address |
| `WORKER_CONSOLE_INSECURE` | No | `false` | Set `true` to allow insecure connections (non-TLS) |
| `WORKER_ID` | Yes | | Worker ID from the dashboard |
| `WORKER_SECRET` | Yes | | One-time secret from worker creation |

### Identity

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `WORKER_NODE_NAME` | No | | Human-readable node name |
| `WORKER_VERSION` | No | build version | Version reported to console |
| `WORKER_LABELS` | No | | CSV labels, e.g. `region=us,owner=team-a` |

### Computer use

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `WORKER_COMPUTER_USE_OUTPUT_LIMIT_BYTES` | No | `1048576` | Output limit per stream (bytes) |
| `WORKER_COMPUTER_USE_COMMAND_WHITELIST_MODE` | No | `exact` | `exact` / `prefix` / `allow_all` |
| `WORKER_COMPUTER_USE_COMMAND_WHITELIST` | No | `[]` | JSON array of allowed commands, e.g. `'["echo","time"]'` |
| `WORKER_READ_IMAGE_ALLOWED_PATHS` | No | `[]` | JSON array of allowed paths for reading images |

### Heartbeat

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `WORKER_HEARTBEAT_INTERVAL_SEC` | No | `5` | Heartbeat interval (seconds) |
| `WORKER_HEARTBEAT_JITTER_PCT` | No | `20` | Jitter percentage (0–100) |
| `WORKER_CALL_TIMEOUT_SEC` | No | `ceil(2.5 * interval)` | gRPC call timeout (seconds) |

### Logging

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `WORKER_LOG_LEVEL` | No | `info` | `debug` / `info` / `warn` / `error` |
| `WORKER_LOG_FORMAT` | No | `json` | `json` / `text` |
| `WORKER_LOG_ADD_SOURCE` | No | `false` | Include source file and line |

## Related docs

- [Architecture](/en/docs/architecture)
- [Docker Runtime](/en/docs/worker-docker)
- [Boxlite Runtime](/en/docs/worker-boxlite)
