Summary
Request a GSTACK_CODEX_NO_SANDBOX=1 opt-in env override that makes the Codex passes in /review and /ship run with Codex's OS sandbox bypassed, for environments where Codex's bubblewrap sandbox cannot create user namespaces (containers / devcontainers / Flatpak / WSL / Replit).
This mirrors the existing GSTACK_CHROMIUM_NO_SANDBOX=1 escape hatch that already exists for the /qa Chromium sandbox on AppArmor/root Linux — the Codex adversarial review has the exact same class of problem with no equivalent knob today.
Environment
- gstack
1.55.0.0
- codex-cli
0.136.0
- Linux devcontainer on OrbStack (kernel
7.0.5-orbstack); unprivileged user namespaces are not permitted
bwrap not on PATH → Codex falls back to its bundled bubblewrap, which fails the same way
The problem
Every Codex pass in /review (always-on adversarial + the 200+ line structured review) and /ship (Step 11 adversarial) runs Codex with -s read-only. On Linux, -s read-only wraps every shell command Codex executes in bubblewrap, which needs unprivileged user namespaces. In a locked-down container these aren't available, so every command Codex runs (git diff, file reads) fails instantly:
bwrap: No permissions to create a new namespace, likely because the kernel
does not allow non-privileged user namespaces.
/bin/bash -lc 'git status --short' exited 1 in 0ms
Confirming the kernel side:
$ unshare --user true
unshare: unshare failed: Operation not permitted
$ cat /proc/sys/kernel/unprivileged_userns_clone # knob doesn't exist on this kernel
The insidious part: it fails silently and looks like a clean review
- A trivial Codex prompt with no shell commands succeeds (the model replies fine), which masks the problem.
- But the review prompt instructs Codex to run
git diff to see the changes. That command — and every command after it — exited 1 in 0ms with the bwrap error, so Codex produces output like "Could not run the requested commands … No repository status available" — i.e. a non-review.
- Critically,
codex exits 0, and the current error handling in ship/sections/adversarial.md / review/SKILL.md only treats stderr as an error when it matches auth / login / unauthorized / API key, a timeout, or empty output. A bwrap / namespace failure matches none of those, so gstack presents the empty "review" verbatim as a success. No gate, no warning. Users believe they got cross-model adversarial coverage when they got nothing.
Repro
# Works (no shell commands → sandbox never engaged) — this is the false reassurance
codex exec "Reply with exactly: PROBE_OK" -C "$PWD" -s read-only < /dev/null
# Fails (the real review path: Codex must run git/file reads)
codex exec "Run 'git status --short' then read README.md, summarize." \
-C "$PWD" -s read-only -c 'model_reasoning_effort="low"' < /dev/null
# → bwrap: No permissions to create a new namespace; every command exits 1 in 0ms
Proposed solution
Add a GSTACK_CODEX_NO_SANDBOX opt-in (off by default; identical ergonomics to GSTACK_CHROMIUM_NO_SANDBOX). When set to 1, the Codex invocations in codex/SKILL.md, review/SKILL.md, and ship/sections/adversarial.md swap their sandbox flag:
codex exec passes: -s read-only → --dangerously-bypass-approvals-and-sandbox
codex review (the 200+ line structured pass): it rejects -s and (per codex review --help) does not appear to accept --dangerously-bypass-approvals-and-sandbox — so use the config form -c sandbox_mode="danger-full-access" (please verify the exact accepted mechanism for the review subcommand).
The rationale is exactly what Codex's own flag help states: "Skip all confirmation prompts and execute commands without sandboxing. EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed." A container/devcontainer is that externally-sandboxed environment, so Codex's nested OS sandbox is redundant there.
Secondary ask (independent of the env gate): stop the silent failure
Even without the env gate, the error handling should treat a sandbox/namespace failure as a Codex failure. Suggest adding bwrap / namespace / sandbox failed to the stderr error patterns so the review reports "Codex sandbox failed — set GSTACK_CODEX_NO_SANDBOX=1 if this environment is already externally sandboxed" instead of presenting an empty review as success. This is arguably the more important half — a silent no-op is worse than a loud skip.
Prior art / references
- gstack's own
GSTACK_CHROMIUM_NO_SANDBOX=1 for the analogous Chromium-sandbox-in-container case (the accepted pattern this request mirrors).
- Upstream Codex, same
bwrap: No permissions to create a new namespace class, with danger-full-access repeatedly confirmed as the working path:
- OpenAI Codex sandboxing docs (prerequisites): https://developers.openai.com/codex/concepts/sandboxing
Affected files
codex/SKILL.md / codex/SKILL.md.tmpl
review/SKILL.md
ship/sections/adversarial.md (+ .tmpl)
Summary
Request a
GSTACK_CODEX_NO_SANDBOX=1opt-in env override that makes the Codex passes in/reviewand/shiprun with Codex's OS sandbox bypassed, for environments where Codex'sbubblewrapsandbox cannot create user namespaces (containers / devcontainers / Flatpak / WSL / Replit).This mirrors the existing
GSTACK_CHROMIUM_NO_SANDBOX=1escape hatch that already exists for the/qaChromium sandbox on AppArmor/root Linux — the Codex adversarial review has the exact same class of problem with no equivalent knob today.Environment
1.55.0.00.136.07.0.5-orbstack); unprivileged user namespaces are not permittedbwrapnot onPATH→ Codex falls back to its bundled bubblewrap, which fails the same wayThe problem
Every Codex pass in
/review(always-on adversarial + the 200+ line structured review) and/ship(Step 11 adversarial) runs Codex with-s read-only. On Linux,-s read-onlywraps every shell command Codex executes inbubblewrap, which needs unprivileged user namespaces. In a locked-down container these aren't available, so every command Codex runs (git diff, file reads) fails instantly:Confirming the kernel side:
The insidious part: it fails silently and looks like a clean review
git diffto see the changes. That command — and every command after it —exited 1 in 0mswith the bwrap error, so Codex produces output like "Could not run the requested commands … No repository status available" — i.e. a non-review.codexexits 0, and the current error handling inship/sections/adversarial.md/review/SKILL.mdonly treats stderr as an error when it matchesauth/login/unauthorized/API key, a timeout, or empty output. Abwrap/namespacefailure matches none of those, so gstack presents the empty "review" verbatim as a success. No gate, no warning. Users believe they got cross-model adversarial coverage when they got nothing.Repro
Proposed solution
Add a
GSTACK_CODEX_NO_SANDBOXopt-in (off by default; identical ergonomics toGSTACK_CHROMIUM_NO_SANDBOX). When set to1, the Codex invocations incodex/SKILL.md,review/SKILL.md, andship/sections/adversarial.mdswap their sandbox flag:codex execpasses:-s read-only→--dangerously-bypass-approvals-and-sandboxcodex review(the 200+ line structured pass): it rejects-sand (percodex review --help) does not appear to accept--dangerously-bypass-approvals-and-sandbox— so use the config form-c sandbox_mode="danger-full-access"(please verify the exact accepted mechanism for thereviewsubcommand).The rationale is exactly what Codex's own flag help states: "Skip all confirmation prompts and execute commands without sandboxing. EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed." A container/devcontainer is that externally-sandboxed environment, so Codex's nested OS sandbox is redundant there.
Secondary ask (independent of the env gate): stop the silent failure
Even without the env gate, the error handling should treat a sandbox/namespace failure as a Codex failure. Suggest adding
bwrap/namespace/sandbox failedto the stderr error patterns so the review reports "Codex sandbox failed — set GSTACK_CODEX_NO_SANDBOX=1 if this environment is already externally sandboxed" instead of presenting an empty review as success. This is arguably the more important half — a silent no-op is worse than a loud skip.Prior art / references
GSTACK_CHROMIUM_NO_SANDBOX=1for the analogous Chromium-sandbox-in-container case (the accepted pattern this request mirrors).bwrap: No permissions to create a new namespaceclass, withdanger-full-accessrepeatedly confirmed as the working path:Affected files
codex/SKILL.md/codex/SKILL.md.tmplreview/SKILL.mdship/sections/adversarial.md(+.tmpl)