Skip to content

docs(codex-implementer): list the sandbox preconditions before the invocation - #15

Open
wooter wants to merge 1 commit into
DannyMac180:mainfrom
wooter:fix/sandbox-preconditions
Open

docs(codex-implementer): list the sandbox preconditions before the invocation#15
wooter wants to merge 1 commit into
DannyMac180:mainfrom
wooter:fix/sandbox-preconditions

Conversation

@wooter

@wooter wooter commented Aug 10, 2026

Copy link
Copy Markdown

--sandbox workspace-write is the right default, but it's genuinely restrictive and none of its limits announces itself clearly at runtime. Each of the three below has burned a full invocation in my logs.

Independent of #12 and #14 — disjoint hunks, any merge order works.

1. No network

npm install fails with ENOTFOUND registry.npmjs.org. The bad part isn't the failure — it's that in one observed run codex "recovered" by copying node_modules out of an unrelated sibling project, which is far worse than erroring out.

-c sandbox_workspace_write.network_access=true opens it when a task legitimately needs the registry. Key confirmed present in codex-cli 0.147.0.

2. No docker socket

Any spec whose verification command is docker build / docker run cannot self-verify. One Dockerfile task became five codex round-trips because failures were only visible at container runtime, outside the sandbox.

3. Cannot commit inside a git worktree — and the obvious workaround is a sandbox escape

In a linked worktree .git is a file, so index.lock lands in the main repo's .git, outside the writable root. Codex can never commit; it hit 2 of 2 lanes in one session.

The tempting fix is to add .git to writable_roots. Don't. Tested against codex-cli 0.147.0 under macOS seatbelt:

Writable roots Commit
worktree only index.lock: Operation not permitted
+ .git/worktrees/<name> clears the lock, then fails writing objects
+ whole .git escape
repo parent alone roots are not recursive

With .git writable, a sandboxed process wrote .git/hooks/pre-commit. On the orchestrator's next normal commit the hook executed outside the sandbox and created a file outside every declared writable root. Verified end to end.

A narrow set does commit without the escape:

[<worktree>, <main>/.git/worktrees/<name>, <main>/.git/objects, <main>/.git/refs, <main>/.git/logs]

.git/hooks and .git/config stay unwritable, closing both the hook and the core.hooksPath route (both confirmed denied). It still fails softly on packed-refs.lock.

Even so: five paths reconstructed per worktree, one omission from re-opening the escape, to save a single git commit. The PR recommends the orchestrator commits instead — which is where you inspect the diff anyway.

The change

A precondition table before step 3, the escape warning with its tested results, and an explicit statement that an unsatisfiable precondition is a STATUS: unavailable — not a retry.

Docs-only.

…vocation

`--sandbox workspace-write` is the right default but is genuinely restrictive,
and each of these limits has burned a full invocation. None of them announces
itself clearly at runtime:

- No network. `npm install` fails with ENOTFOUND against the registry. In one
  observed run codex "recovered" by copying node_modules out of an unrelated
  sibling project instead of failing cleanly, which is worse than an error.
  `-c sandbox_workspace_write.network_access=true` opens it when a task
  legitimately needs the registry (key confirmed present in codex-cli 0.147.0).
- No docker socket, so any spec whose verification is `docker build`/`docker run`
  cannot self-verify; the orchestrator has to run that step outside codex.
- In a git worktree, `.git` is a file pointing at
  <main-repo>/.git/worktrees/<name>/, which is outside the writable root — so
  index.lock cannot be created and codex can never commit.

Also warn against the obvious workaround. Widening writable_roots to the whole
.git does let codex commit, and also lets it write .git/hooks/pre-commit, which
then executes OUTSIDE the sandbox as the orchestrator on the next git operation.
Verified end to end against codex-cli 0.147.0 under macOS seatbelt: a sandboxed
process planted the hook and the payload ran on the next commit, writing a file
outside every declared writable root. writable_roots is also not recursive, so
naming the repo parent grants nothing under .git.

A narrow root set (worktree + worktrees/<name> + objects + refs + logs) commits
without the escape, but it is five reconstructed paths per worktree and one
omission from re-opening it. Recommend the orchestrator commits instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@wooter
wooter force-pushed the fix/sandbox-preconditions branch from d3921f5 to b376073 Compare August 10, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant