# Runtime

**The model in one line:** secrets live on the house and reach every sandbox by default; environments are recipes that select a runtime (and can restrict secrets to a subset); sandboxes built from those recipes run code on [Daytona](sandbox-daytona.md) by default.

Three CLI command groups manage arbe's runtime layer: sandboxes run code, environments configure them, and secrets store credentials. For the underlying concepts, see [daytona runtime](sandbox-daytona.md), [system/environments](environments.md), and [system/secrets](../access/secrets.md).


## What it takes to dispatch

Dispatch runs inside the backstage — see [dispatch](../chat/dispatch.md). An env-bound thread is a normal thread whose bots get a sandbox to reach via the `run_command` tool; selection and authorship are identical to a local thread. Two things must line up for it to round-trip:

- the provider key required by the model is available from a house secret or the worker fallback (for example, `openrouter/...` needs `OPENROUTER_API_KEY`);
- the environment names a runtime the backstage can reach: daytona provisions on demand via `DAYTONA_API_KEY` ([secrets](../access/secrets.md)).

The sandbox is the bot's hands, reached per tool call. Environments provide named runtime and secret-scoping recipes.


## Sandboxes

A sandbox is a remote machine + working tree where a bot's hands run. Daytona is the runtime; you rarely provision one by hand — creating an environment auto-provisions a Daytona box (`DAYTONA_API_KEY`), and `delegate_task` creates or reuses the box bound to its parent thread. See [Daytona runtime](sandbox-daytona.md) for how a run mirrors into its child thread and resumes.

`arbe sandbox` inspects and manages machines. Identity is the daytona `sandbox.id`:

```sh
arbe sandbox list            # house's live daytona machines
arbe sandbox <id>            # detailed view
arbe sandbox stop <id>       # stop (start to resume)
arbe sandbox start <id>
arbe sandbox destroy <id>    # delete
```

The CLI reads the house's `DAYTONA_API_KEY` server-side, so no local key is needed for any verb. `arbe env diagnose <env>` checks the environment recipe and required credentials.

All commands accept `--json` for machine-readable output.


## Environments

Environments link a sandbox to a house and choose which house secrets to inject (all, by default). A sandbox is created once and reused across runs.

```sh
arbe env list                                              # list all in the active house
arbe env view staging                                      # detailed view with the secrets policy
arbe env create staging                                  # auto-provision Daytona
arbe env create ci --only-secret GITHUB_TOKEN              # restricted env; default is all house secrets
arbe env secrets staging                                   # show which secrets this env's boxes see
arbe env secrets staging --only GITHUB_TOKEN --only NPM_TOKEN
arbe env secrets staging --all                             # back to the default
arbe env delete staging                                    # remove it
```

When creating an environment, omit `--sandbox` to auto-provision on the selected runtime (Daytona by default), or pass it to wrap an existing sandbox. Every house secret is available by default; restrict at creation with `--only-secret NAME` (repeatable) or afterward with `arbe env secrets <env> --only NAME` / `--all`. The policy stores names; values resolve at dispatch — see [secrets](../access/secrets.md).

Aliases: `ls`/`l` for list, `rm`/`del` for delete.


## Secrets

Secrets are house-scoped encrypted values. Every house secret is injected into the house's sandboxes at runtime, unless an environment restricts itself to a subset.

```sh
arbe secret list                                    # see all in the active house
arbe secret view OPENAI_API_KEY                     # metadata and timestamps
echo "sk-..." | arbe secret set OPENAI_API_KEY      # create (or rotate if it exists)
arbe secret delete OPENAI_API_KEY                   # remove it
```

Values are always read from stdin, never passed as arguments — so they don't end up in shell history. If a secret with the same name already exists, `set` rotates it rather than creating a duplicate.

Secrets are house-scoped; use `--house <house>` or the active house.

Aliases: `ls`/`l` for list, `rm`/`del` for delete. All commands accept `--json`.


## Typical setup workflow

Starting from nothing, here's the sequence to get ready for dispatching work:

```sh
# 1. Store credentials (values come from stdin)
printf '%s' "$OPENROUTER_API_KEY" | arbe secret set OPENROUTER_API_KEY
printf '%s' "$GITHUB_TOKEN"       | arbe secret set GITHUB_TOKEN

# 2. Create the environment — daytona auto-provisions the sandbox
arbe env create prod --only-secret OPENROUTER_API_KEY --only-secret GITHUB_TOKEN

# 3. Dispatch work
arbe env use prod                                      # set active env once
THREAD_ID=$(arbe thread create <parent-ref>)           # active env fills in --env
arbe thread entries create "$THREAD_ID" "implement the login page"
```

`arbe thread create --env prod <parent>` is the explicit form; without `--env` it falls back to the active env. The leading entry kicks off dispatch — tail with `arbe thread entries read "$THREAD_ID"` (exits on dispatch terminals, non-zero on failed).

On www at `/threads/new`, step 2 collapses to "+ Create env": the server auto-provisions the daytona box when `sandbox_id` is omitted, given `DAYTONA_API_KEY` is configured.

Day-to-day usage is `arbe thread create` + `arbe thread entries create`, plus `arbe sandbox list` to check live machines.

Each bot replies with its own model ref (`agent.model`, defaulting to `DEFAULT_BOT_MODEL` in `@arbe/core/schemas/agent-model`). A thread-level model override can pin a conversation when needed; otherwise each agent keeps its assigned model. `OPENROUTER_API_KEY` is the base credential for both local pi and in-thread bot replies.

See [dispatch](../chat/dispatch.md) for how a bot's turn reaches a sandbox in the first place, and [daytona runtime](sandbox-daytona.md) for what happens on the machine once it does.
