- Зачем:
- ретро трёх циклов конвейера показало: находки ревью проходили через
контекст оркестратора до шести раз, review-промпт дублировался, ~7
пустых ходов на idle-пингах teammate-ревьюера.
- Что:
- SKILL.md: механика «индекс у оркестратора, нагрузка файлами» — вердикты
в файлы обменного temp-каталога, fix-промпт конкатенацией, один
канонический review-промпт на обоих ревьюеров, idle-пинги как шум;
- новый references/prompt-templates.md — скелеты четырёх промптов;
- codex-exec.md: сборка промптов cat'ом, боевая модель gpt-5.5 явно
(фронтир из конфига не наследовать);
- codex-sandbox-fix-handover: рабочий AppArmor-фикс (ловушка memfd,
профиль на бинарь codex), проверен на обоих режимах;
- lessons.md: датированные записи ретро, казуса Sol и memfd.
- Проверка:
- чтение SKILL.md и references/, следующий прогон конвейера.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8.2 KiB
Handover: починка sandbox Codex CLI на Ubuntu 24.04 (2026-07-10)
Для агента, дорабатывающего скилл работы с Codex. Самодостаточно: диагностика и фикс воспроизводимы без контекста исходной сессии.
Симптом
Любая команда внутри sandbox Codex падает до запуска процесса, даже pwd:
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
Проявляется и в read-only, и в workspace-write. Codex не может ни читать файлы через shell, ни выполнять команды — задачи либо виснут, либо честно завершаются отказом.
Корневая причина (подтверждена kernel audit log)
Codex CLI 0.144.1 (npm) сменил Linux-sandbox backend: раньше был Landlock/seccomp без user namespaces, теперь — vendored bubblewrap (…/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources/bwrap), который создаёт unprivileged user namespace + network namespace.
Ubuntu 24.04 с kernel.apparmor_restrict_unprivileged_userns = 1 загоняет такой userns в запретительный AppArmor-профиль unprivileged_userns, который блокирует два шага, нужных bwrap: запись /proc/PID/uid_map и RTM_NEWADDR (поднятие loopback). Доказательство из audit log:
apparmor="AUDIT" operation="userns_create" comm="bwrap" profile="unconfined" target="unprivileged_userns"
apparmor="DENIED" operation="open" name="proc/…/uid_map" profile="unprivileged_userns" denied_mask="wr"
Важные отрицательные результаты (экономят время диагностики):
- Плагин openai-codex (1.0.5 → 1.0.6) ни при чём — он лишь передаёт режимы sandbox бинарю codex; даунгрейд плагина не помогает.
- Системный
/usr/bin/bwrapпадает так же — это не баг vendored-сборки. - Система не менялась (машина без ребута 14 недель, политика AppArmor старая) — это дрейф самого Codex CLI, прилетевший с обновлением npm-пакета.
Применённый фикс без sudo (обратимый)
В ~/.codex/config.toml добавлено:
[features]
use_legacy_landlock = true
Backup рядом: ~/.codex/config.toml.bak-20260710. Откат — восстановить backup или удалить две строки.
Проверка (сквозная, через codex-companion)
- Read-only задача
task --wait --fresh(«pwd + первая строка /etc/os-release») — команды выполняются, вернула корректные значения. - web_search работает: задача сходила на github.com/openai/codex/releases. Нюанс: сетевой доступ из shell-команд внутри sandbox по-прежнему закрыт (
npm viewвиснет) — это корректный read-only режим; инструмент web_search исполняется вне sandbox и не страдает. - Изоляция сохранена: запись вне workspace запрещена.
Известное ограничение фикса
use_legacy_landlock чинит только read-only. Режим --write/workspace-write с этим флагом паникует:
permission profiles requiring direct runtime enforcement are incompatible with --use-legacy-landlock
— workspace-write требует именно bwrap-backend. Полный фикс — ниже, нужен sudo.
Полный фикс (sudo; применён и проверен 2026-07-10)
Ловушка, съевшая первую попытку: профиль на путь vendored bwrap
(**/codex-resources/bwrap) НЕ работает — Codex ≥0.144 исполняет
встроенный bwrap из memfd (linux-sandbox/src/bundled_bwrap.rs,
memfd_create в бинаре), и путевой attachment не цепляется никогда: в audit
виден profile="unconfined" comm="bwrap" → transition в
unprivileged_userns. Прямой запуск vendored bwrap с диска при этом
проходит — ложное подтверждение, не верь ему.
Рабочий вариант: вешать профиль на сам бинарь codex (родителя) —
memfd-exec'нутый ребёнок наследует метку через exec, и правило userns,
разрешает namespace. Стандартный приём Ubuntu для браузеров/Electron.
/etc/apparmor.d/codex-bwrap:
abi <abi/4.0>,
include <tunables/global>
profile codex-cli /home/dmitry/.npm-global/lib/node_modules/@openai/codex/**/bin/codex flags=(unconfined) {
userns,
include if exists <local/codex-cli>
}
profile codex-bwrap /home/dmitry/.npm-global/lib/node_modules/@openai/codex/**/codex-resources/bwrap flags=(unconfined) {
userns,
include if exists <local/codex-bwrap>
}
Загрузить: sudo apparmor_parser -r /etc/apparmor.d/codex-bwrap. После этого убрать use_legacy_landlock из config.toml и проверить оба режима:
codex sandbox -c 'sandbox_mode="workspace-write"' -- sh -c 'touch ./__p && rm ./__p && echo OK'
codex sandbox -- sh -c 'touch ./__p 2>/dev/null && echo BROKEN || echo RO_OK'
Проверено 2026-07-10: WRITE_OK, read-only блокирует запись, workspace-write
не пускает в /etc — изоляция сохранена.
Переносимость: путь в профиле — под конкретную машину (~/.npm-global/...); glob ** переживает обновления версий Codex, но если npm-global живёт в другом месте — путь поправить. Перезагружать профиль нужно только при смене самого расположения.
Вариант B — грубый, не рекомендуется: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 (+ файл в /etc/sysctl.d/). Ослабляет защиту всей машины.
Диагностические команды для другой машины
codex --version # 0.144.1+ → bwrap-backend
sysctl kernel.apparmor_restrict_unprivileged_userns # 1 → будет блокировка
bwrap --ro-bind / / --unshare-net --dev /dev --proc /proc true && echo BWRAP_OK
sudo dmesg | grep -iE 'apparmor.*(userns|bwrap)' | tail # AUDIT/DENIED — подтверждение
Что стоит внести в скилл
- Ловушка: с включённым
use_legacy_landlock--write-задачи паникуют — либо профиль AppArmor и убрать флаг, либо жить в read-only. - web_search Codex работает даже при мёртвом shell-sandbox — «гуглит, но не может выполнить
ls» — характерная сигнатура именно этой поломки. - Поломка прилетает молча с обновлением npm-пакета codex — при странных отказах первым делом
codex --versionи дата установки.
Связанные записи
Принесено 2026-07-10 из ветки codex-sandbox-fix-20260710 (исходная машина —
Ubuntu 24.04; там сжатая версия жила в codex-companion.md, который в основной
линии уже поглощён codex-exec.md). Сжатая версия урока здесь — в
codex-exec.md, сквозное правило «Linux: sandbox может молча
сломаться обновлением Codex»; датированная запись — в
lessons.md.