Files
werkrevisor/docs/prs/2026-10-18-PR#123-codex-sandbox-check.md
claude-code a6185f0949
werkator build succeeded after 00:09
werkator/werkrevisor-statistics build succeeded after 00:26
werkator/release build succeeded after 00:12
werkrevisor 0.51.0: the Codex runner checks its sandbox before it reviews (#123)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-18 20:38:01 +02:00

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.

  • PR#88: the Codex runner and its bwrap jail.

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 bwrap that 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

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 bwrap fails 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

Solution

  • codex.check_sandbox runs bwrap --ro-bind / / true inside the jail that codex.jail builds for a review, with the same environment; it returns the cause, or None.
  • Runner.run calls the check first. On a failure, it logs the cause with the next steps, reviews nothing in this run and returns False; tools/codex-runner then exits with 1, and the systemd unit shows as failed.
  • A review whose bwrap fails, 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 Runner takes it as sandbox_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 --failed and the desktop show. A failed oneshot service does not stop a timer with OnUnitInactiveSec; a test with systemd-run fired 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 bwrap fails 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 stays pending.
  • 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 bwrap before the review, which is the cause of such an answer.