Codex ensemble dispatch grants write access to five read-only review sites (--no-write missing from canonical snippet)
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Problem
scripts/codex_task.py defaults to --write (grant Codex file-mutation access):
scripts/codex_task.py:1907 # Default for --write is True (grant write) unless --no-write was passed.
scripts/codex_task.py:1716 "--write", / :1722 "--no-write", / :640 cmd.append("--write")
The canonical orchestrator dispatch snippet in .claude/rules/codex-ensemble-review.md does NOT
pass --no-write:
uv run python scripts/codex_task.py --issue <N> --effort <high|xhigh> \
--prompt-file /tmp/codex-prompt-issue-<N>.md --output-file /tmp/codex-output-issue-<N>.md
All FIVE doubled review sites are read-only reviewer roles by definition — critic,
code-reviewer, interpretation-critic, clean-result-critic, follow-up-critic. The
codex-* composers already know this and RETURN it in their dispatch config; every one of the
three composers on #2544 returned the line:
Codex write mode: false (read-only critic)
The orchestrator has no documented flag to honor that with, so the declared read-only contract is silently dropped at dispatch and Codex reviews its target with write access to the repo.
Write access is not needed for the output path: the wrapper captures Codex stdout into
--output-file itself (codex_task.py docstring: "Write Codex stdout to --output-file").
Observed
#2544 Phase 2, 2026-08-24: three Codex critic jobs dispatched from the canonical snippet, all
three marker-recorded as write=True against composer configs declaring write mode false. No
mutation occurred — the completed alternatives job left plan v4 byte-identical and the working
tree clean on every reviewed source — so this is a latent exposure, not a live incident. The
prompts' own read-discipline headers appear to be doing the work that a flag should do.
Why it matters
A reviewer with write access can "helpfully" edit the artifact it is reviewing. At the plan-critic
site that means the plan under review; at the code-reviewer site, the diff under review. Either
silently destroys the review's independence — the property the whole Claude+Codex ensemble exists
to provide — and at the plan site it could mutate a persisted plans/v<K>.md out from under the
Goal-currency and Edit-success gates, which compare against what they last wrote.
Proposed fix
- Add
--no-writeto the canonical dispatch snippet in.claude/rules/codex-ensemble-review.md, and to any sibling copies of the snippet in the/issuestep bodies and agent specs (grep forcodex_task.py --issue). - Consider inverting the helper default for the reviewer path. Safest minimal form: keep the
--writedefault for any non-review Codex use, but have the five review sites pass--no-writeexplicitly; a stronger form is a--role reviewerthat implies read-only. - Optional hardening: have
codex_task.pyrefuse--writewhen the prompt file contains theepm:*-critique-codex/epm:code-review-codexmarker tags, since those tags identify a review dispatch unambiguously.
Acceptance
- The canonical snippet and every in-repo copy pass
--no-write. - A dispatched review job's
epm:codex-task-spawnednote recordswrite=False. - A test pins the snippet so the flag cannot silently regress out again (the same shape as the
existing region-anchored surface pins in
workflow_lint.py).
Provenance
Found by the #2544 orchestrator while auditing why spawn markers read write=True against
composer configs declaring read-only. Not a #2544 experiment defect; a workflow-surface gap that
affects every Codex ensemble round fleet-wide.