Skip to content
Chock

Comparison

How other harnesses sandbox their agents

We compared Chock with three other harnesses by reading their source code, not their documentation, at the commit or tag beside each name and on the date beside that. We did it for a reason: in the one case where we compared the documentation against the code, the documentation was wrong twice and the code corrected it both times.

Every entry says what we read in the source and nothing beyond it. Chock's own column is checked against the Chock repository, and it has been wrong and corrected twice.

What is comparedChockthis projectZed5a9b955, read 2026-09-05OpenCode012c2f5 (v1.18.11), read 2026-08-21oh-my-pi9350b799, read 2026-08-21
Tool calls inside the operating system's sandbox
Every one of them.
The terminal and the fetch tool. Reading, writing and deleting a file run in process.
None. Their SECURITY.md calls the permission prompt a user interface feature with no isolation behind it.
None anywhere in the tree.
Language servers, MCP servers and plugins
Sandboxed, the same as every other tool call.
An MCP server and a language server each get an ordinary child process, outside the sandbox.
Unsandboxed. A plugin is handed a shell and the cleartext token.
An extension runs in process, their words, beside every credential.
Where a tool call writes
A throwaway copy of your project.
Your real working tree.
A git worktree, which is what they mean by their sandbox.
A copy on write layer for subagents. It is built for concurrency, and containment is not its purpose.
What a tool call can read
A minimal mount tree. The credential store is never mounted, and the environment is scrubbed.
The mount is the whole root, read only. Nothing scrubs the environment, so every token in the parent shell arrives with it.
The whole machine.
The whole machine.
The system call filter, on Linux
A denylist, the same shape as Zed's. 31 calls killed, 2 more rules that read an argument, and a test that names every call which must be blocked.
A denylist of 6 calls. None on macOS, and none at all on an architecture it does not know.
None.
None.
A kernel module holding the filesystem, on Linux
Landlock, and it is mandatory. On a kernel without it the tool call fails.
None. Landlock enforcement was written twice and removed both times without ever running.
None.
None.
Turning the sandbox off
There is no switch. A layer that fails to apply fails the tool call.
The Linux failure path offers a Run Unsandboxed button, so fail open is a choice a person can make.
There is nothing to turn off.
There is nothing to turn off.
What a rule is matched against
The act a call performs, and the directory the binary came from. A git shim does read the argument vector, and the documentation says the shim stops a mistake and does not stop an attack.
Regular expressions over the command text, with chained commands parsed across 14 shells. A wrong parse is a way through.
The tool's input: the command text, the path, the URL.
A regular expression denylist of dangerous commands. Writing the argument into a variable first walks past it.
What the policy permits when nothing is configured
Reading, writing and running a command need no prompt, because the sandbox and the throwaway copy are what answer for them. Every act that leaves them is a separate name in the table, and asks.
It asks per tool call, and matches the rule against the command text.
It asks, and a non interactive run refuses everything unless you pass a flag.
Reading, writing and running a command are approved with no prompt, on your machine.

HoldsIn partNot there

Why the source and not the manual

One harness documents its own hole: a deny rule on its shell tool misses the same command run through its eval tool. No summary says so. The method has also corrected us twice, most recently about Chock's own system call filter.

Two projects did leave Landlock

Zed (#58355, 2026-06-09) and Codex (#13996, merged 2026-03-12) both moved to bubblewrap. Landlock grants rights and cannot take one back, so a writable repository cannot have its .git carved out again. Neither pull request calls Landlock weak, and both ran one that skipped what the kernel lacked. Chock builds its own mount namespace, so it has the carve out and a Landlock that fails the call.

Rules match the act, not the command text

Three of these decide a shell command by matching its text. GTFOBins lists dozens of ordinary programs that walk straight through such a rule, so one permitting find permits everything. Chock keys on the act and on where the binary came from.

What this table does not say

All three have years of work behind them and do far more than Chock, which is pre-alpha. This table compares one thing: what a tool call can reach. They were built as coding tools that later added a sandbox. Chock started at the sandbox and the record, and the rest is being built behind them.

The status page says what is built and what is not.

What we read

  • Zed at 5a9b955, read 2026-09-05
  • OpenCode at 012c2f5 (v1.18.11), read 2026-08-21
  • oh-my-pi at 9350b799, read 2026-08-21

A project is in the table only where we can name the commit we read. Claude Code and Codex are absent for that reason alone. We have read both, and those reads are not pinned to a commit we can put beside a cell, so they stay out until we read them again.