The upstream openai_codex SDK defaults `approval_mode` to
`ApprovalMode.auto_review` (described in the SDK docs as "automatically
execute tools when permission escalations occur, without user
intervention") and leaves `sandbox` unset. Studio drives Codex from
a server-side chat request with no per-action approval UI, so leaving
those at the SDK defaults would let a model decide on its own to run
shell commands, write files, or hit the network on the operator's
machine.
This wires every `thread_start` call (single-turn, parallel-worker,
synthesis) through a helper that pins:
- `approval_mode = ApprovalMode.deny_all` -- reject any tool /
command escalation rather than auto-approving it.
- `sandbox = SandboxMode.read_only` -- the policy that bans file
writes and disables network.
The kwargs are looked up dynamically: when the installed SDK is too
old to expose either enum we log a structured warning and proceed
without them rather than refusing to run, so users on pre-release
alpha builds are not bricked. Once the canonical openai-codex SDK
is what every install pulls, the warning will be silent and the
safety pins will always apply.
Tests: three new regressions in TestCodexHardenedRegressions cover
the safe-pin path on a fake SDK that exposes the enums, the
warn-and-proceed path on a fake SDK that does not, and the same
pins on the synthesis turn so a fan-out tab cannot sneak an unsafe
default into the unification step.