Skip to main content
PRAISON_SHELL decides what praisonai code does when a command contains a shell operator (>, |, &&, $(...)): refuse it, run it inside an OS sandbox, or run it uncontained.

Quick Start

1

Default — operators are refused

Without PRAISON_SHELL, the coding agent runs plain commands as before, but a command with a shell operator fails loudly instead of silently dropping it.
2

Enable a real, contained shell

Set PRAISON_SHELL=sandboxed to run a real /bin/sh -c inside OS-native containment (Seatbelt on macOS, bwrap on Linux).

The Three Modes

PRAISON_SHELL (or the mode= argument to execute_command) selects one behaviour. Aliases resolve to these three: 1/true/yes/sandbox/nativesandboxed; raw/hostunsafe; empty/0/false/no/noneoff.

Why the default refuses

The plain executor runs shlex.split + subprocess.Popen(shell=False), so an operator becomes a literal argument.
The model is told a redirect it never performed succeeded — strictly worse than an error. Refusing names the operator and tells the agent what to do instead.

Quote-Aware Detection

Detection looks for operators outside quotes, so ordinary strings are never refused. $(...) and backticks are detected even inside double quotes because POSIX shells evaluate them there — reporting them as inert would reintroduce the false-success bug.

Approval

The real-shell path is wrapped in require_approval(risk_level="critical") under the tool name execute_command.
Both sandboxed and unsafe route through the same critical-risk approval as the plain executor — same tool identity, so existing allowlists and path_overlap serialisation still apply. Denying approval raises PermissionError and no file is written.
The approval wrap fails closed: if the approval machinery can’t be imported, the real shell does not run.

When Your Agent Hits a Refusal

An agent that hits PRAISON_SHELL=off refusal has three honest paths.
The operator can instead launch the session with PRAISON_SHELL=sandboxed to allow real operators inside a jail.

Best Practices

off never runs an uninterpreted operator and never claims false success. Reach for sandboxed only when a real shell is genuinely needed.
sandboxed gives a real /bin/sh while a kernel keeps writes inside the workspace. unsafe removes that boundary entirely — use it only when you accept an uncontained shell deliberately.
Two execute_command calls (one per && step) work in every mode and keep each step’s success signal honest.
Replace cmd > file.txt with a plain cmd call plus write_file. This works in off mode and keeps the file-creation step explicit.

OS Sandbox

Seatbelt and bwrap containment that sandboxed mode runs inside.

Safe Tools by Default

Why tools refuse rather than degrade.

Interactive Tools

The execute_command tool in the coding session.

Tool Approval

The critical-risk approval wrap on the real-shell path.