openai / openai/codex-plugin-cc

`thread/resume` sandbox is ignored while the thread is still live in the shared app-server, so `task --resume-last --write` cannot write after a read-only run

Open
#740 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
33.3k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

What happens

task forwards the requested sandbox on thread/resume (buildResumeParams in plugins/codex/scripts/lib/codex.mjs). Codex applies it only when the app-server loads the thread again from its rollout. While the thread is still live in the app-server, the resumed turns keep the sandbox the thread already has. The plugin keeps one shared app-server per Claude Code session (the broker), so inside a session every resume hits the live case: a rescue thread that began read-only ("investigate") stays read-only when it is resumed with --write, and the write attempt is refused inside Codex with no error from the plugin. The reverse also holds: a thread started with write access keeps it when resumed without --write.

Observed with Codex CLI 0.153.2 and plugin 1.0.6 (main at db52e28).

Reproduction

In any git repository, inside one session (so the broker keeps the app-server):

node "$PLUGIN/scripts/codex-companion.mjs" task \
  "Create a file named probe.txt containing ok in the current directory using a shell command. Reply WRITE DENIED if the write is refused, WRITE OK otherwise."
# -> WRITE DENIED (expected: the thread is read-only)

node "$PLUGIN/scripts/codex-companion.mjs" task --resume-last --write \
  "Create a file named probe2.txt containing ok in the current directory using a shell command. Reply WRITE DENIED if the write is refused, WRITE OK otherwise."
# -> WRITE DENIED, probe2.txt does not exist (expected: WRITE OK)

The other direction, same session:

node "$PLUGIN/scripts/codex-companion.mjs" task --write "Create probe.txt ... (same prompt)"
# -> WRITE OK
node "$PLUGIN/scripts/codex-companion.mjs" task --resume-last "Append a line to probe.txt ... Reply WRITE DENIED / WRITE OK."
# -> WRITE OK (expected: WRITE DENIED, the resumed request asked for read-only)

Then stop the broker (broker/shutdown, or end the session) and resume the write-capable thread once more without --write: the write is now refused, and the thread/resume response echoes {"type":"readOnly","networkAccess":false}. Resuming a read-only thread with danger-full-access after a restart echoes {"type":"dangerFullAccess"}. So the override works on a cold load and is dropped on a live thread.

Why it matters

/codex:rescue defaults to --write, so most threads start writable, but the common sequence "investigate (read-only), then --resume apply the fix" silently cannot apply anything within the same session. The plugin reports a completed task. The opposite case keeps write access on a follow-up the user meant to be read-only.

Possible fix

Either send the requested policy on every turn/start (TurnStartParams.sandboxPolicy is documented as "Override the sandbox policy for this turn and subsequent turns"), which needs a full SandboxPolicy object rather than a mode string and touches the same ground as #575 and #613, or treat a sandbox change on --resume-last as "start a fresh thread" in the plugin. This is probably also worth a report against the app-server itself, since ThreadResumeParams.sandbox is documented as an override without the live-thread exception. Until one of those lands, the docs should say the sandbox is fixed for the life of the session's thread and --fresh is the way to change it; the --sandbox PR says that in the README.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with buildResumeParams in plugins/codex/scripts/lib/codex.mjs and the shared app-server broker path used by codex-companion.mjs task. Reproduce the read-only-then-write and write-then-read resumes in one session, then compare the requested sandbox with the live thread behavior. Done means sandbox changes on resume are honored or the supported fresh-thread behavior is clearly documented and tested.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.