4.6 KiB
PR#123: The Codex Runner Checks Its Sandbox before It Reviews
Version: minor
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
Related Links
- PR#88: the Codex runner and its
bwrapjail.
Problem
The Codex runner runs Codex in a bwrap jail, and Codex starts its own bwrap sandbox inside it.
On 2026-10-16 at 19:53 the AppArmor profile bwrap was unloaded on the workstation, while bwrap-userns-restrict was disabled.
Until it was loaded again on 2026-10-17 at 12:38, bwrap fell under unprivileged_userns
and failed with "bwrap: setting up uid map: Permission denied".
Each attempt for PR#115 and PR#116 failed this way and counted against MAX_ATTEMPTS; PR#115 waited 16.6 hours.
With bwrap-userns-restrict active, the nested bwrap fails too,
and Codex rates a PR critical because its shell sandbox failed.
A later update of the AppArmor package can bring either fault back.
Non-Goals
- No change of the jail or of the AppArmor profiles of the workstation.
- No detection of a failed sandbox inside a Codex answer; the check before the run covers it.
Specification
Feature: the Codex runner reviews only with a working sandbox
Scenario#123.01: a broken sandbox stops the reviews of a run
… so that a fault of the workstation neither uses up the attempts of a PR nor produces a wrong verdict.
- Given a ready PR, and a nested
bwrapthat fails on the workstation - When the runner runs
- Then the PR gets no review, its attempts stay unchanged, the log names the cause, and the run exits with 1
Verified by
- test_codexrunner.CodexRunnerTest.test_a_broken_sandbox_stops_the_reviews
- test_codexrunner.CodexRunnerTest.test_the_run_exits_with_1_after_a_sandbox_fault
- test_codex.CodexTest.test_the_sandbox_check_runs_a_bwrap_inside_the_jail
Scenario#123.02: a jail that fails during a review costs no attempt
… so that a fault that starts after the check does not count against the PR either.
- Given a ready PR, a check that passes,
and a review whose
bwrapfails with "bwrap: setting up uid map: Permission denied" - When the runner runs
- Then the attempts of the PR stay unchanged, and the run exits with 1
Verified by
- test_codexrunner.CodexRunnerTest.test_a_jail_fault_in_a_review_costs_no_attempt
- test_codex.CodexTest.test_only_a_failed_bwrap_is_a_jail_fault
Solution
codex.check_sandboxrunsbwrap --ro-bind / / trueinside the jail thatcodex.jailbuilds for a review, with the same environment; it returns the cause, orNone.Runner.runcalls the check first. On a failure, it logs the cause with the next steps, reviews nothing in this run and returnsFalse;tools/codex-runnerthen exits with 1, and the systemd unit shows as failed.- A review whose
bwrapfails, i.e. a non-zero exit with an error that contains "bwrap: ", counts no attempt and stops the reviews of the run in the same way. - The runner still collects the PRs while the sandbox fails:
a PR with a Codex comment gets its gate status, the others keep
pending"waiting for the Codex review". - Tests inject the check; a
Runnertakes it assandbox_check. - README "Codex runner" and the plan describe the check.
- Version 0.51.0.
Open Questions
- Exit code 0 or 1 on a failed check?
1: the systemd unit then shows as failed, which
systemctl --user --failedand the desktop show. A failed oneshot service does not stop a timer withOnUnitInactiveSec; a test withsystemd-runfired 3 failed runs in 12 s. - Does a PR keep "waiting for the Codex review" while the sandbox fails? Yes: the cause lies on the workstation, not in the PR, and the failed unit shows it to the human. A gate PR stays held, as with a workstation that is off.
- Does a review whose
bwrapfails count as an attempt? No: the jail fails before Codex starts, so the review uses no quota, and the PR is not at fault. A PR cannot bypass the gate this way: a run that fails like this posts no comment, so the PR stayspending. - Does the check detect a failed sandbox inside a Codex answer, e.g. a verdict "critical" because the shell sandbox failed?
No; the check runs the nested
bwrapbefore the review, which is the cause of such an answer.