Repository navigation
Description
Summary
The plugin sends an explicit sandbox value on every thread/start / thread/resume, so the sandbox_mode a user configured in ~/.codex/config.toml never applies to plugin-launched jobs. A user who sets sandbox_mode = "workspace-write" expecting delegated tasks to edit files still gets read-only unless every single invocation remembers --write; other config keys (model, reasoning effort) flow through to plugin jobs as defaults, but sandbox_mode is the one setting that silently cannot.
Evidence (at HEAD db52e28, plugin v1.0.6)
buildThreadParamsandbuildResumeParamsalways materialize a sandbox:sandbox: options.sandbox ?? "read-only"(plugins/codex/scripts/lib/codex.mjs:68,:81) — the config value can never surface.- Task path hardcodes the pair:
sandbox: request.write ? "workspace-write" : "read-only"(plugins/codex/scripts/codex-companion.mjs:491). - Review paths pin
read-only(codex.mjs:1012,codex-companion.mjs:414). - The app-server does fall back to config when the parameter is omitted. Verified live (Codex CLI 0.145.0-alpha.2) with a minimal JSON-RPC client:
thread/startwithsandboxomitted → the responsesandboxmatched thesandbox_modeconfigured in config.toml, alongside the config-resolvedmodelandreasoningEffort.thread/startwithsandbox: "read-only"→ responsesandbox: {"type":"readOnly","networkAccess":false}, overriding config as expected.
So the ?? "read-only" default and the two hardcoded call sites are the only thing standing between config.toml and plugin jobs.
Repro
- Set
sandbox_mode = "workspace-write"in~/.codex/config.toml. - Run
node scripts/codex-companion.mjs task --background "any prompt"without--write. - The job executes
read-onlyregardless of config. There is no flag, config key, or environment variable that lets the configuredsandbox_modethrough.
Proposed fix
When the caller passes no explicit sandbox-affecting flag, omit sandbox from the thread params and let the app-server resolve it from config.toml — the same fallback the app-server already performs for model and reasoning effort. --write stays as an explicit override, and the review paths can reasonably remain pinned read-only if reviews are meant to be side-effect-free; that call is yours.
An alternative shape with the same effect is a --sandbox <read-only|workspace-write|danger-full-access> passthrough on task, mirroring the Codex CLI's own --sandbox flag and defaulting to today's behavior.
Happy to follow up with a PR once a direction is picked.
Related
- Add --full-access flag to companion task for unsandboxed execution #145 / PR feat: add --full-access flag for sandboxed execution (#145) #147 —
--full-accessflag ontask; a per-run escape hatch, complementary to (not a substitute for) honoring the configured default. - Windows: /codex:review and /codex:rescue silently return empty results because plugin forces broken sandbox modes #349 — Windows sandbox coercion; adjacent sandbox-selection behavior.
- Codex returns 'verdict: blocked' on completed work — three distinct causes mask successful task output #273 — sandbox-blocked verdicts; another symptom of sandbox policy being invisible to callers.
Environment
- Plugin
codex@openai-codexv1.0.6 (upstream HEAD db52e28) - Codex CLI 0.145.0-alpha.2
- Claude Code on WSL2 Ubuntu 26.04, Node v24.18.0
Activity
nayots commentedon Jul 27, 2026
Additional data point on the impact of the hardcoded value at
codex-companion.mjs:491, from an A/B test on Windows. The consequence isn't only thatsandbox_modeis ignored — underworkspace-writethe sandboxed commands appear to run as a different Windows security principal than the user, which breaks git independently of filesystem permissions.Setup. Windows 11, plugin v1.0.6, codex-cli 0.144.6, Node v26.3.0. Throwaway git repo; a background write task dispatched via
codex-companion.mjs task --background --write --fresh --prompt-file …, asking Codex to create a file,git addit, thengit commit. The only variable between the two runs was the value on line 491.A — as shipped (
sandbox: request.write ? "workspace-write" : "read-only")Both git commands failed:
B — same line changed to
"danger-full-access", nothing else touchedWhy this might be worth calling out separately from the config-override framing. The ownership error isn't a filesystem-permission denial, so the remedies people reach for don't apply:
trust_level = "trusted"and[windows] sandbox = "elevated"inconfig.tomlchange nothing — neither affects which principal the commands run as.git config --global --add safe.directory …) is a dead end, since the sandboxed git isn't reading the invoking user's global config.In a plan-driven workflow the user-visible symptom is that a task implements and verifies successfully and then cannot commit — surfacing as
dubious ownershipin some repos andUnable to create '.../.git/index.lock': Permission deniedin others, apparently from the same cause. Any "one commit per task" discipline stalls at the first commit after all the work is done.This should resolve along with the config-override issue if a per-invocation sandbox selector lands, or if the parameter stops being sent unconditionally. Flagging the principal mismatch mainly because it makes the failure look like a git configuration problem rather than a sandbox one, which sends people down the wrong path.
cubicj commentedon Jul 28, 2026
@nayots
Thanks for the A/B probe — the principal-mismatch detail is a good catch, and I agree it disguises a sandbox problem as a git configuration one. The linked PR #508 resolves this case: it stops sending the hardcoded sandbox value from
codex-companion.mjs:491, so the failure you traced becomes reachable-by-configuration instead of baked in. Before replying I verified that on a Windows 11 host against the #508 branch (codex-cli 0.146.0-alpha.10, Node v24.16.0), alongside a protocol-level check of what the plugin actually sends.With #508, a task invoked with neither
--writenor--read-onlypassessandbox: null, and athread/startprobe against a directly spawned app-server confirms that resolves to whateversandbox_modeis set inconfig.toml, with the response echoing the resolved policy. On Windows withsandbox_mode = "danger-full-access"and no sandbox flag, your probe sequence (create a file,git add,git commit) completed with the commit landing. The same task with--writestill pinsworkspace-writeand still fails on Windows — though on 0.146.0-alpha.10 it fails earlier than what you observed on 0.144.6: the file write itself is rejected withpatch rejected: writing is blocked by read-only sandbox; rejected by user approval settings, so the run never reaches git. Same conclusion either way:workspace-writeon Windows is not currently usable for write tasks, and #508's config-driven path is the one that works.Two clarifications on scope. An explicit
--writestill pinsworkspace-writeby design — and in practice that flag comes from the delegating Claude session, not from anything you type: the plugin's skill guidance tells the model to add--writeby default for write tasks, which is what produced the invocation in your A run. So the migration on Windows has two parts: setsandbox_mode = "danger-full-access"inconfig.toml, and instruct your Claude session (user-level CLAUDE.md works) not to pass sandbox flags so the config governs. And with nosandbox_modeconfigured at all, the flagless path resolves toread-only(the codex config default), which matches the plugin's pre-#508 default exactly — unconfigured setups see no behavior change, and the config override is what #508 adds.The write-rejection behavior under
workspace-writeon 0.146.0-alpha.10 looks like a codex-side regression or an intentional tightening of the Windows sandbox — either way it's independent of this plugin and probably worth tracking upstream.AzmainMahatab commentedon Oct 8, 2026
Another data point from Windows 11 (codex-cli 0.161.0, plugin v1.0.6): with the plugin's forced sandboxes, every shell command in a task failed for me, while
codex execwith the sameconfig.tomlworked. Two separate causes, both only reachable because the plugin pins the sandbox:C:\Program Files\WindowsApps\...\pwsh.exe) cannot be started under the restricted-token sandbox (CreateProcessAsUserWerror 5 / 1920).[windows] sandbox = "elevated", the setup refresh tries to update ACLs on the desktop app's runningnode_repl.exeand fails withos error 32(file in use), so every command is rejected withhelper_unknown_error: setup refresh had errors.Letting the sandbox and approval policy come from config (#646 for the sandbox, #806 for the approval policy) avoids both. Until something lands, I keep a patched build that tracks upstream releases: https://github.com/AzmainMahatab/codex-plugin-cc-patched
unitea1992 commentedon Oct 10, 2026
Another data point from Linux (codex-cli 0.162.1, plugin v1.0.6), with
sandbox_mode = "danger-full-access"andapproval_policy = "never"in~/.codex/config.toml:codex:codex-rescuetask could not create a git worktree (.git/refs/heads/...lock: Read-only file system) and could not write its report file outside the repository, because the rescue agent ran it without--write(read-only) and--writewould still beworkspace-write.thread/startto the app-server withsandbox: nullandapprovalPolicy: null; the response resolved todangerFullAccess/neverfrom config.toml. So omitting or nulling both fields is enough to honor the user's config.+1 for #508. It would also help if the rescue agent could be told to keep the user's configured sandbox (for example a
--sandbox configoption), so diagnosis tasks that need to write outside the workspace do not silently fall back to read-only.blake-tisbury commentedon Oct 21, 2026
Same on Windows 11 (codex-cli 0.159.2, plugin 1.0.6). Our
config.tomlhassandbox_mode = "danger-full-access", because the elevated Windows sandbox was too slow on our machine and we turned it off. Every plugin task and review still asked forread-only/workspace-write, went throughcodex-windows-sandbox-setup.exe, and failed withorchestrator_helper_exit_nonzerobefore its first command.Letting the configured mode win fixed it locally: tasks and reviews start shells again.
scripts/lib/codex.mjs:buildThreadParams/buildResumeParamsusesandbox: options.sandbox ?? null, andrunAppServerReviewstops passingsandbox: "read-only".scripts/codex-companion.mjs: the adversarial review andtaskstop passingsandbox(--writeno longer picks a mode).A flag or a config key that lets the user's
sandbox_modewin (or #145's--full-access) would remove the need to patch.