Running Commands
wardcell run [OPTIONS] -- <command> [args...]Everything after -- is the command. wardcell resolves the policy, renders it
for the host backend, starts the proxy, and execs.
Selecting what applies
Section titled “Selecting what applies”Three ways, and they compose:
# By command name — fragments with selects_on = { commands = ["git"] }wardcell run -- git push
# By profile — loads <name>.sbx from the policy root as a root fragmentwardcell run --profile developer -- bash
# By zone — when the machine defines zones.tomlwardcell run --zone user -- git pushselects_on matching always applies. --profile adds a named fragment on top.
Both then expand requires.
Launching a macOS application
Section titled “Launching a macOS application”On macOS the command may be an application bundle:
wardcell run -- /Applications/Claude.appNothing else is needed — not the executable inside the bundle, not a
--profile, not the bundle identifier. wardcell reads the bundle’s
Contents/Info.plist and takes two things from it: CFBundleExecutable, which
is the program it execs, and CFBundleIdentifier, which selects any fragment
whose selects_on = { app_bundles = [...] } names it.
Reading the plist is not optional politeness — the executable is often not
named after the bundle. Codex.app runs Contents/MacOS/ChatGPT.
A bare name works too, searched in the working directory, then /Applications,
~/Applications and /System/Applications:
wardcell run -- Claude.appArguments after the bundle go to the application:
wardcell run -- /Applications/Codex.app --disable-gpuA fragment may append arguments of its own — every Chromium application needs one or two before it will start or can be inspected. Those are announced on stderr, and yours always win: see Program Arguments.
Fragments for a bundle grant read on the bundle with the $APP_BUNDLE token,
which expands to wherever it is installed — so a fragment works whether the
application is in /Applications or ~/Applications. Without that grant the
launch aborts in dyld, because the executable cannot read the frameworks beside
it.
Chromium-based applications — Claude, Codex, VS Code and anything else built on Electron — need more than this, and it is worth reading macOS: Chromium applications before writing a fragment for one.
Options
Section titled “Options”--policy-root, --profile and --zone choose what resolves; --yes and
--no-init control the first-run picker. The full option table, with defaults,
is in the CLI reference.
Setting up a new directory
Section titled “Setting up a new directory”The first wardcell run in a directory with no
.wardcell.sbx opens a
setup picker before the
sandbox starts — it scans the checkout, offers the toolchains and integrations
it found, and writes your choice so the run, and every run after it here, starts
with that reach. It opens only on a terminal; a piped or CI run prints a one-line
hint and carries on, and --yes / --no-init skip or silence it.
What the process inherits
Section titled “What the process inherits”| Working directory | yours — and $WORKDIR in policy expands to it |
| stdin/stdout/stderr | inherited, so it is interactive |
| Environment | only what the env blocks build, plus proxy variables wardcell sets |
| Exit code | passed straight through |
The environment is the one that surprises people: it is not your shell’s environment minus some entries, it is empty plus whatever policy adds. See Environment Variables.
What a run prints
Section titled “What a run prints”A run prints a few lines before the sandboxed child takes over — the run id,
where its log is, and how to tail it — then one summary line after the child
exits. Between the two wardcell writes nothing of its own, so a TUI agent in the
sandbox is never corrupted. The summary names anything that was blocked with the
exact DSL line that would allow it; everything else — every request, grant and
denial — goes to the run’s log. See Viewing
Logs for the summary and how to read the log,
and re-run under policy draft to turn denials into
rules.
Filesystem and process denials aren’t in wardcell’s data path — the kernel
enforces them, so an enforcing run gets no per-path signal and a blocked file
surfaces only as the command’s own non-zero exit. wardcell notices that, and on
any non-zero exit prints what the code means and (unless the command was simply
stopped) the policy draft --print command that reveals what was denied without
touching your .wardcell.sbx. The CLI reference
has the full exit-code table.