fabro/docs/public/reference
Bryan Helmkamp 3606ba6a0f
feat(sandbox): standardize command execution on non-login Bash
Fabro advertised Bash while its three backends implemented three
different contracts: Daytona evaluated commands through `sh`, and
Docker's streaming, stdio, and setup paths used a login shell. Bash-only
syntax silently misbehaved depending on provider and code path, and
login profiles could change PATH and command behavior per image.

Make `bash -c` the enforced interpreter for every command string the
Unix sandbox API accepts, on every production backend and through both
buffered and streaming execution. This selects the interpreter only —
no `errexit`, no `pipefail`, no login mode — so `false | true` still
succeeds and a workflow that wants other semantics writes them into its
own command.

Local resolves `bash` through the worker's PATH (NixOS has no
/bin/bash) and reuses that one executable across all three command
paths. Docker and Daytona require /bin/bash with no `sh` fallback.

Fresh initialization and resume/start now verify Bash through a shared
marker-validating probe before reporting the sandbox usable, so a
missing or non-Bash interpreter fails at the lifecycle boundary with
provider-specific remediation instead of on the first command. The
probe also rejects Bash in POSIX mode, which an image whose `bash` is
really `sh` would otherwise pass.

Sandbox MCP scripts and the detached launch wrapper move under the same
contract; host-side stdio MCP scripts, hooks, and interactive terminals
are separate executors and keep their existing `sh` behavior.

The `shell` tool's name and JSON schema are unchanged across providers;
only its prose now identifies `command` as Bash source.

BREAKING CHANGE: sandbox commands no longer load login-shell profiles,
so environment set in /etc/profile.d/*.sh, ~/.bash_profile, or
nvm/rbenv/sdkman initializers is gone. Move those exports into the
Dockerfile's ENV or the Daytona snapshot image.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 21:26:05 -04:00
..
acknowledgements.mdx refactor(docs): split docs/ into public/ and internal/ 2026-04-27 07:21:13 -07:00
architecture.mdx docs: add child runs guide 2026-05-25 15:43:53 -04:00
cli.mdx Add fabro variable CLI namespace for server-managed variables (#434) 2026-05-27 13:57:25 -04:00
dot-language.mdx Merge branch 'main' into feat/shared-checkout-parallel 2026-07-24 06:29:57 -04:00
run-directory.mdx refactor(workflow): remove retro stage (#230) 2026-05-09 10:18:20 -04:00
sdk.mdx fix(agent): remove dead execution limits 2026-07-23 19:36:29 -04:00
server-operations.mdx refactor: rationalize server secret scopes (vault-only for optional int… (#401) 2026-05-25 17:26:01 -04:00
shell-completions.mdx refactor(docs): split docs/ into public/ and internal/ 2026-04-27 07:21:13 -07:00
user-configuration.mdx feat(sandbox): standardize command execution on non-login Bash 2026-07-24 21:26:05 -04:00
verifying-releases.mdx refactor(docs): split docs/ into public/ and internal/ 2026-04-27 07:21:13 -07:00