Runs & environments
The daemon assembles the current repo context, chooses the configured execution environment, starts a CLI runner, keeps the conversation live, and preserves the outcome in git or the reply thread.
Every project chooses one of five shipped environments. These modes isolate different kinds of friction; none is a cage for a hostile agent.
| Mode | What it isolates | Use it when |
|---|---|---|
host |
Nothing beyond your shell. Changes hit the working tree immediately. | You trust the agent and want minimum friction. |
worktree |
A separate worktree and branch. It still shares .git, credentials, network, and the host filesystem. |
You want code runs kept off the main working tree. |
sandbox |
The host behind a Docker Sandbox microVM; the repo workspace remains mounted at its host path, while credentials are injected by the sandbox proxy. | You want the VM boundary and have sbx; set its github secret to the bot token before forge work. |
solitary |
Docker with provider-only network egress and no forge credentials. | You want the hardened route for untrusted sources. |
docker |
Dependencies and network; host-file visibility is narrowed to the repo and mounted credential paths. The repo is read-write, credentials cross in, and network is on by default. | You want a clean toolchain or network control as defense in depth. |
Select the mode in security.config (the daemon-owned file in the brnrd
account home, typically
~/.local/state/brnrd/<account>/home/security.config):
environment=worktreeFor Docker, set an image and optionally disable networking:
environment=dockerdocker.image=your-runner-image:tagdocker.network=noneenvironment and docker.* are security keys — they are ignored if placed in
.brr/config. brnrd init writes them to the right place automatically.
For an existing install that has them in .brr/config, run
brnrd config promote to migrate them.
Durability
Section titled “Durability”For modifying work, the reliable receipt is a git commit on the run branch. The current-thread response is also preserved. Failed or conflicted worktree and Docker runs keep their recovery surfaces for inspection; clean successful runs can remove scratch state.
Trust boundary
Section titled “Trust boundary”The runner executes commands with the authority brnrd grants it, and its
approval prompts are bypassed deliberately. worktree protects your working
tree, not your credentials or machine. Docker narrows filesystem visibility but
is not a credential or containment boundary. Read Security & privacy
before accepting tasks from other people.
Source-trust tiering
Section titled “Source-trust tiering”The environment isn’t only a static config choice — it’s also picked per event by the trust of the source, resolved deterministically when the run manifest is built (no LLM in the loop). An untrusted commenter’s run no longer executes with the same authority as your own. Three tiers:
- owner — you: the paired chat, the bound account, and every owner-only path (schedule wakes, self-wakes, CLI). Gets the configured default environment — today’s behaviour, unchanged.
- collaborator — a repo write+ collaborator, an allowlisted sender, a
member of a configured room. Gets the configured default too, tightenable to
a stricter environment with
trust.collaborator_env. - untrusted — anything else that still reaches the queue. Routed to
trust.untrusted_env(solitaryby default, orsandboxwhen that is the configured default environment), or refused when isolation is unavailable ortrust.untrusted=refuse. The isolated backends need their CLI and a live daemon, checked before a runner starts. Settingtrust.untrusted_envto a weaker env (worktree,host) is your explicit choice and is honoured.
An event’s own environment key can never lift an untrusted event out of its
tier: the tier wins.
Config keys — these are security keys and belong in security.config
(daemon-owned, not repo-writable). Use brnrd config promote to migrate
any that ended up in .brr/config:
trust.collaborator_env=solitary # optional: tighten the collaborator envtrust.untrusted_env=solitary # default: env for untrusted sourcestrust.untrusted=refuse # or: refuse untrusted runs outright (default: solitary)At zero config, owner and collaborator behave exactly as before; untrusted
fails closed. The resolved tier rides the run metadata (trust_tier), so
surfaces can show which trust level a run executed at.
Your own runs use your configured environment, unwrapped unless you choose
isolation. Untrusted ingress uses solitary or a configured sandbox, or is
refused before a runner starts, unless you named a weaker env yourself. The harness’s own sandbox is a separate opt-in:
Claude’s sandbox covers shell commands only. For Codex, set these runner options
in the account’s daemon.config (ordinary repo config is not read for runner.*):
runner.codex_sandbox=workspace-writerunner.codex_sandbox_network_access=trueThis replaces the bundled Codex approval/sandbox bypass with --sandbox workspace-write and -c approval_policy="never" for non-interactive execution.
Network access defaults to false when this sandbox is enabled; the second option
allows it explicitly. Leaving runner.codex_sandbox unset preserves today’s
unwrapped default. A pinned runner_cmd is used verbatim and owns its own flags.
Harness sandboxing does not replace the environment boundary for untrusted runs.