или `$(...)` — передавай текст файлом, а не аргументом: шелл выполняет такие фрагменты внутри двойных кавычек, и до Codex доходит искажённый текст либо вызов падает с `command not found`.\n\n```bash\nbash scripts/codex-review.sh code --description-file /path/to/description.md\n```\n\nОпция работает для `init`, `plan` и `code`; на `plan` она называет файл плана — то же, что `--plan-file`. Одновременно с `--plan-file` или с описанием в аргументе — ошибка. Файл читается до последнего байта: пустые строки в конце и отсутствие перевода строки в конце сохраняются.\n\nОтправленный текст сохраняется рядом с логом попытки байт в байт: `codex-\u003cphase>-\u003cN>.request.md` для ревью, `codex-init.request.md` для сессии.\n\n#### Название задачи для `init`\n\n`state.json` хранит одну строку — название задачи, которое видно в `STATUS.md` и в сводке архива. Название даёшь ты сам:\n\n```bash\nbash scripts/codex-review.sh init --description-file task.md --task-label \"JWT auth: middleware + refresh endpoint\"\n```\n\nПравила: одна строка, без двойных кавычек, обратных слешей и управляющих символов, без пробелов в начале и в конце, до 200 символов. Название сохраняется ровно таким, каким передано: скрипт ничего не переписывает и не подчищает, а отклоняет с объяснением. Пустое значение в `--task-label` — ошибка. Если описание задачи занимает больше одной строки, а `--task-label` не передан — запуск завершается ошибкой, ничего не создаётся: назови задачу сам, а не рассчитывай, что скрипт угадает. При однострочном описании название берётся из него.\n\nПолный текст задачи в `state.json` не попадает — он целиком уходит в Codex и лежит в `codex-init.request.md`.\n\n### 5. Управление состоянием\n\n```bash\nbash scripts/codex-state.sh show # Текущее состояние\nbash scripts/codex-state.sh dir # Путь к state-каталогу текущей ветки\nbash scripts/codex-state.sh reset # Сброс итераций (session сохраняется)\nbash scripts/codex-state.sh reset --full # Полный сброс\nbash scripts/codex-state.sh get session_id # Получить поле\nbash scripts/codex-state.sh set session_id \u003cval> # Установить вручную\nbash scripts/codex-state.sh set phase implementing # Обновить фазу\nbash scripts/codex-state.sh set iteration 2 # Откатить счётчик кругов\n```\n\n`get` возвращает значение поля как оно записано: пустое строковое поле — пустой\nстрокой, счётчик — числом. Незнакомое имя поля — ошибка с кодом возврата 1.\nОсобые имена: `session_id` (приоритет у `config.env`) и `verdict` (из\n`verdict.txt`).\n\n`set` принимает поля `session_id`, `phase`, `iteration`, `max_iterations`,\n`reviews_completed`, `last_review_status`, `last_review_timestamp`,\n`task_description`. Неизвестное имя поля, нецелое значение счётчика и значение\nс кавычкой, обратным слэшем, переводом строки или табуляцией — ошибка с кодом\nвозврата 1, состояние не меняется.\n\nДля чтения файлов ревью (notes, STATUS.md и пр.) используй `codex-state.sh dir` — он вернёт абсолютный путь к каталогу текущей ветки.\n\n## Обработка exit-кодов\n\n| Exit | Status | Действие |\n|------|--------|----------|\n| 0 | APPROVED | Обработай `## Non-blocking` и `## Pre-existing` (см. «Разделы ответа ревьюера»), затем продолжай работу |\n| 0 | CHANGES_REQUESTED | Скорректируй и отправь снова (см. «Accept or Argue») |\n| 1 | ERROR | Сообщи об ошибке, предложи проверить session_id |\n| 2 | ESCALATE | Оповести пользователя, выведи краткое резюме, предложи варианты (см. «Обработка ESCALATE») |\n| 3 | NO_SESSION | Спроси: создать сессию через `init`? |\n\nПри `ERROR` круг не состоялся: итерация не израсходована, тот же запрос\nможно отправить повторно. Итерацию расходует прогон, который вернул вердикт,\n— даже если сам запуск завершился ошибкой после этого.\n\n### Обработка ESCALATE (exit 2)\n\nКогда лимит итераций исчерпан:\n\n1. Получи путь: `STATE_DIR=$(bash scripts/codex-state.sh dir)`. Прочитай заметки ревью из `$STATE_DIR/notes/` (файлы `{phase}-review-{N}.md`)\n2. Выведи пользователю краткое резюме:\n - Какой этап (plan/code), сколько итераций прошло\n - Ключевые замечания и статусы по каждой итерации (1-2 строки на итерацию)\n3. Используй `AskUserQuestion` с тремя вариантами:\n - **Ещё одна итерация** — разово расширить лимит на 1\n - **Снять лимит** — убрать ограничение для этой сессии\n - **Прекратить ревью** — вывести финальное резюме и остановиться\n (Вариант «Свой вариант» добавляется автоматически)\n\nОбработка ответа:\n- «Ещё одна итерация» → повтори вызов `codex-review.sh {phase} \"...\" --max-iter $((текущий_лимит + 1))`\n- «Снять лимит» → повтори вызов `codex-review.sh {phase} \"...\" --max-iter 999`\n- «Прекратить ревью» → выведи финальное резюме и заверши процесс ревью\n- Свой вариант → следуй инструкции пользователя\n\n## STATUS.md\n\nФайл `STATUS.md` в state-каталоге ветки (путь: `codex-state.sh dir`) создаётся и обновляется автоматически скриптами. Не редактируй его вручную.\n\n- Файл **появляется** при `init` и обновляется при каждом `plan`/`code` и `codex-state.sh set`\n- Файл **удаляется** при финальном APPROVED на этапе `code` и при `reset --full`\n- Наличие файла = активное ревью, отсутствие = ревью не идёт\n\n## Verdict\n\nCodex пишет свой вердикт в `verdict.txt` внутри state-каталога ветки (одно слово: `APPROVED` или `CHANGES_REQUESTED`). **Для чтения вердикта используй `bash scripts/codex-state.sh get verdict`** — helper возвращает `APPROVED`, `CHANGES_REQUESTED` или пустую строку (нет/невалидно). Файл очищается перед каждым запросом ревью, поэтому слово в нём написано текущим кругом. Вердикт берётся только отсюда: текст ответа на решение не влияет. Если после прогона в файле нет `APPROVED` или `CHANGES_REQUESTED` — круг не состоялся: скрипт возвращает `ERROR` (exit 1), итерация не расходуется, ответ ревьюера сохраняется рядом с логом попытки как `codex-\u003cфаза>-\u003cN>.reply.md`. Рядом с вердиктом лежит `verdict.phase` — одно слово, `plan` или `code`:\nфаза, которая его получила. Оба файла удаляются вместе.\n\nПлагинный хук `ExitPlanMode` связывает вердикт с текущей Claude-сессией через\n`current_session.txt` в том же каталоге — verdict, пришедший из другой сессии,\nудаляется. Хук пропускает `ExitPlanMode` только при `APPROVED` с пометкой\n`plan`. Вердикт с пометкой `code` или без пометки хук удаляет и отвечает\nотказом с указанием запустить ревью плана.\n\n## Завершённый цикл\n\n`APPROVED` на фазе `code` закрывает цикл: `STATUS.md` удаляется, а следующий\n`plan` или `code` завершается с exit 1 и ничего не меняет. Дальше — один из\nдвух путей:\n\n- **Новая задача** — `codex-review.sh init \"\u003cзадача>\"`: прежний цикл уходит в\n архив, открывается новая сессия Codex.\n- **Доработки той же задачи** — `codex-state.sh reset`, затем обычный круг:\n счёт кругов с первого, название задачи и session_id сохраняются.\n\nКаждый круг печатает в stderr, к какой задаче он относится: `Task: \u003cназвание>`\nв первом круге и `Continuing task: \u003cназвание> (previous round \u003cвремя>)`, если по\nэтой ветке уже были круги. Если название не совпадает с текущей задачей — цикл\nпринадлежит другой работе: выбери один из двух путей выше до отправки круга.\n\n## Разделы ответа ревьюера\n\nОтвет ревьюера разложен на три раздела. Что делать с каждым:\n\n| Раздел | Действие |\n|---|---|\n| `## Blocking` | исправь или оспорь каждый пункт — см. «Accept or Argue» |\n| `## Non-blocking` | не исправляй по своей инициативе; вынеси список пользователю через `AskUserQuestion` (взять в работу / отдельной задачей / не делать) |\n| `## Pre-existing` | вынеси каждый пункт уровня `critical` пользователю через `AskUserQuestion` (чинить сейчас / отдельной задачей / не чинить) до того, как объявишь ревью законченным; остальные пункты — вместе с `## Non-blocking` |\n\nПри `APPROVED` с непустым `## Non-blocking` работа считается принятой: отправлять новый круг ревью из-за этих пунктов не нужно.\n\n## Правила\n\n- НИКОГДА не вызывай `codex exec` напрямую — только через скрипты `codex-review.sh` и `codex-state.sh`. Скрипты сами знают модель, конфиг и session_id\n- Описывай ЧТО ты сделал и ПОЧЕМУ, какие решения принимал — используй шаблоны описания\n- НЕ передавай git diff — Codex сам посмотрит, он в той же директории\n- APPROVED → обработай `## Non-blocking` и `## Pre-existing`, затем продолжай работу\n- Перед реализацией вызови `codex-state.sh set phase implementing`\n- Есть заказчик (пользователь) — уточняй у него неоднозначные вопросы\n- Опция `--max-iter N` позволяет изменить лимит итераций\n\n### Worktree & Branch Isolation\n\nСостояние ревью изолировано по ветке. Скрипты автоматически определяют основной репозиторий и текущую ветку. Параллельная работа на нескольких ветках/worktrees безопасна. `config.env` — общий (в корне `.codex-review/`). Для получения пути к state-каталогу текущей ветки используй `codex-state.sh dir`.\n\n### Один запуск на ветку\n\n`init`, `plan`, `code`, `codex-state.sh set` и `codex-state.sh reset` занимают\nветку на всё время работы: каталог `.lock` внутри state-каталога. Второй запуск\nпо той же ветке завершается с exit 1, ничего не меняя, и печатает, какая\nкоманда держит ветку, её pid, машину и время начала.\n\nЕсли в тексте ошибки сказано, что процесс работает, — дождись его конца и\nповтори команду.\n\nЕсли сказано, что процесс не работает или что это нельзя определить (замок с\nдругой машины, от другого системного пользователя, без записи о владельце), —\nубедись, что по этой ветке ничего не выполняется, удали названный в ошибке\nкаталог `.lock` и повтори команду. Замок снимает только тот запуск, который его\nвзял, или человек.\n\nЧтение состояния замок не берёт: `show`, `get` и `dir` отвечают всегда.\n\n### Auto-Workflow (AUTO_REVIEW=true)\n\nWhen `AUTO_REVIEW=true` in `.codex-review/config.env`, the entire review cycle runs automatically. A plugin hook blocks `ExitPlanMode` until Codex approves the plan.\n\n#### Plan phase\n\n1. Write the plan in plan mode as usual\n2. Before calling `ExitPlanMode`, run review:\n ```bash\n bash scripts/codex-review.sh init \"task description\" # ALWAYS init for a new plan — archives previous session\n bash scripts/codex-review.sh plan --plan-file ~/.claude/plans/\u003cslug>.md\n ```\n **IMPORTANT**: Always run `init` before the first `plan` review in a conversation. Even if `codex-state.sh show` reports an existing session, it may be stale (from a previous conversation). The `init` command safely archives the old session and creates a fresh one. Only skip `init` when re-submitting after `CHANGES_REQUESTED` within the same review cycle.\n3. **Formal verdict check** — run `bash scripts/codex-state.sh get verdict`. Proceed ONLY if it outputs the exact string `APPROVED`. Do NOT interpret review text — only the helper output matters.\n4. `CHANGES_REQUESTED` → fix the plan, resubmit (follow «Accept or Argue» rules). Iterate automatically up to the iteration limit.\n5. `APPROVED` → handle `## Non-blocking` and `## Pre-existing` first (see «Разделы ответа ревьюера»), then call `ExitPlanMode` (the hook auto-approves it)\n\n#### Implementation phase\n\n6. Implement as usual. Set phase: `bash scripts/codex-state.sh set phase implementing`\n\n#### Code phase\n\n7. After implementation, run code review:\n ```bash\n bash scripts/codex-review.sh code \"code description\"\n # or, when the description contains backticks / ` codex-review · Skills-SI 市场 / `$(...)`:\n bash scripts/codex-review.sh code --description-file /path/to/description.md\n ```\n8. **Formal verdict check** — same as step 3: run `bash scripts/codex-state.sh get verdict` and check for exact string `APPROVED`.\n9. `CHANGES_REQUESTED` → fix code, resubmit automatically.\n10. `APPROVED` → handle `## Non-blocking` and `## Pre-existing` (see «Разделы ответа ревьюера»), then report to user.\n\n#### ESCALATE handling in auto mode\n\nSame as standard ESCALATE handling — present summary and ask user via `AskUserQuestion`.\n\n### Accept or Argue\n\nПри получении CHANGES_REQUESTED:\n\n1. Прочитай предыдущую review note из `$(bash scripts/codex-state.sh dir)/notes/{phase}-review-{N}.md`\n2. Критически оцени каждый пункт раздела `## Blocking`. В описании к повторной отправке адресуй каждый из них поточечно:\n - **Исправлено**: [что именно исправил и как]\n - **Не согласен**: [контраргумент с обоснованием — Codex видит историю и может принять или настоять]\n - **Отложено**: [причина — только с согласия пользователя через AskUserQuestion]\n3. Запиши в то же описание решение пользователя по пунктам `## Non-blocking` и `## Pre-existing`\n4. Если один и тот же пункт `## Blocking` повторяется 2+ раза без нового содержания (Codex настаивает, ты уже аргументировал) — эскалируй пользователю через AskUserQuestion: покажи замечание, свои аргументы, и спроси решение\n5. Если два круга подряд весь `## Blocking` состоит из дефектов в коде, который породили правки прошлых кругов, — останови круги и спроси пользователя через AskUserQuestion: ещё круг правок или откат механизма к состоянию до ревью\n6. При исчерпании лимита итераций — следуй процедуре «Обработка ESCALATE»\n","licenseDocuments":[]}}
界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
开发与工程 · SKILL.md

codex-review

codex-review

【开发与工程】Workflow кросс-агентного ревью с Codex. Triggers (RU): "кодекс ревью". Triggers (EN): "with codex review", "codex review workflow", "start codex review". ВАЖНО: при срабатывании триггера прочитай SKILL.md до любых других шагов.

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: codex-review description: | Workflow кросс-агентного ревью с Codex. Triggers (RU): "кодекс ревью". Triggers (EN): "with codex review", "codex review workflow", "start codex review". ВАЖНО: при срабатывании триггера прочитай SKILL.md до любых других шагов.

Codex Review Workflow

Кросс-агентное ревью: Claude реализует, Codex (GPT) ревьюит. Codex работает в той же директории и может самостоятельно смотреть код.

Расположение скриптов

Скрипты лежат в scripts/ рядом с этим SKILL.md. Определи полный путь:

  • Этот файл: путь из которого ты прочитал SKILL.md
  • Скрипты: замени SKILL.md на scripts/codex-review.sh (и scripts/codex-state.sh)

Все команды ниже используют относительный scripts/ — подставь полный путь при вызове.

CRITICAL: Sandbox

Codex CLI использует macOS system API (SCDynamicStore), которые блокируются sandbox Claude Code. Все вызовы codex-review.sh и codex-state.sh ОБЯЗАНЫ выполняться с dangerouslyDisableSandbox: true в Bash tool. Без этого codex крашится с паникой Rust.

Workflow

1. Инициализация сессии

Создай сессию Codex с описанием задачи.

bash scripts/codex-review.sh init "Implement JWT authentication for API"

Сессия может быть также задана вручную в .codex-review/config.env: CODEX_SESSION_ID=sess_...

Если сессии нет (exit 3 — NO_SESSION), спроси пользователя:

  • Есть ли уже живая сессия с Codex? → пусть впишет id в config.env
  • Или создать новую через init?

2. Ревью плана

Передай путь к файлу плана через --plan-file. НЕ вставляй содержимое плана в аргумент командной строки — скрипт сам читает файл и отдаёт содержимое Codex на stdin, поэтому размер плана ничем не ограничен.

С plan mode

Если используешь plan mode — отправь план на ревью перед ExitPlanMode:

  1. Написал план → CC сохраняет его в ~/.claude/plans/<slug>.md (автоматически)
  2. Передай этот путь в --plan-file:
    bash scripts/codex-review.sh plan --plan-file ~/.claude/plans/<slug>.md
    
  3. CHANGES_REQUESTED → скорректируй план в файле, отправь снова (см. «Accept or Argue»)
  4. APPROVED → обработай ## Non-blocking и ## Pre-existing (см. «Разделы ответа ревьюера»), затем вызови ExitPlanMode для одобрения пользователем

Таким образом план проходит два ревью: техническое (Codex) и бизнес-приоритетное (пользователь).

Без plan mode

Если план написан в отдельный файл внутри проекта:

bash scripts/codex-review.sh plan --plan-file docs/plan.md

Шаблон плана (рекомендуемая структура файла)

What: [problem being solved]
Approach: [chosen approach and why]
Alternatives considered: [what was rejected and why]
Files to change: [list]
Addressed concerns: [if resubmit — point-by-point from previous review]

3. Реализация

Перед началом реализации обнови фазу:

bash scripts/codex-state.sh set phase implementing

Имплементируй по утвержденному плану.

4. Ревью кода

Опиши ЧТО сделал, КАКИЕ решения принимал. НЕ передавай git diff — Codex сам посмотрит.

Шаблон описания кода

What changed: [summary of changes]
Key decisions: [non-obvious decisions made during implementation]
Files modified: [list with brief description per file]
Tests: [what tests were added/run, results]
Addressed concerns: [if resubmit — point-by-point from previous review]
bash scripts/codex-review.sh code "What changed: JWT auth middleware + refresh endpoint. Key decisions: RS256 over HS256 for key rotation. Files: auth/jwt.py (middleware), api/auth.py (refresh endpoint). Tests: 3 new tests (expired/invalid/valid tokens), all pass."

Описание из файла

Если в описании есть обратные кавычки (обычное дело — так пишут имена функций и полей), $ или $(...) — передавай текст файлом, а не аргументом: шелл выполняет такие фрагменты внутри двойных кавычек, и до Codex доходит искажённый текст либо вызов падает с command not found.

bash scripts/codex-review.sh code --description-file /path/to/description.md

Опция работает для init, plan и code; на plan она называет файл плана — то же, что --plan-file. Одновременно с --plan-file или с описанием в аргументе — ошибка. Файл читается до последнего байта: пустые строки в конце и отсутствие перевода строки в конце сохраняются.

Отправленный текст сохраняется рядом с логом попытки байт в байт: codex-<phase>-<N>.request.md для ревью, codex-init.request.md для сессии.

Название задачи для init

state.json хранит одну строку — название задачи, которое видно в STATUS.md и в сводке архива. Название даёшь ты сам:

bash scripts/codex-review.sh init --description-file task.md --task-label "JWT auth: middleware + refresh endpoint"

Правила: одна строка, без двойных кавычек, обратных слешей и управляющих символов, без пробелов в начале и в конце, до 200 символов. Название сохраняется ровно таким, каким передано: скрипт ничего не переписывает и не подчищает, а отклоняет с объяснением. Пустое значение в --task-label — ошибка. Если описание задачи занимает больше одной строки, а --task-label не передан — запуск завершается ошибкой, ничего не создаётся: назови задачу сам, а не рассчитывай, что скрипт угадает. При однострочном описании название берётся из него.

Полный текст задачи в state.json не попадает — он целиком уходит в Codex и лежит в codex-init.request.md.

5. Управление состоянием

bash scripts/codex-state.sh show              # Текущее состояние
bash scripts/codex-state.sh dir               # Путь к state-каталогу текущей ветки
bash scripts/codex-state.sh reset             # Сброс итераций (session сохраняется)
bash scripts/codex-state.sh reset --full      # Полный сброс
bash scripts/codex-state.sh get session_id    # Получить поле
bash scripts/codex-state.sh set session_id <val>  # Установить вручную
bash scripts/codex-state.sh set phase implementing  # Обновить фазу
bash scripts/codex-state.sh set iteration 2       # Откатить счётчик кругов

get возвращает значение поля как оно записано: пустое строковое поле — пустой строкой, счётчик — числом. Незнакомое имя поля — ошибка с кодом возврата 1. Особые имена: session_id (приоритет у config.env) и verdict (из verdict.txt).

set принимает поля session_id, phase, iteration, max_iterations, reviews_completed, last_review_status, last_review_timestamp, task_description. Неизвестное имя поля, нецелое значение счётчика и значение с кавычкой, обратным слэшем, переводом строки или табуляцией — ошибка с кодом возврата 1, состояние не меняется.

Для чтения файлов ревью (notes, STATUS.md и пр.) используй codex-state.sh dir — он вернёт абсолютный путь к каталогу текущей ветки.

Обработка exit-кодов

ExitStatusДействие
0APPROVEDОбработай ## Non-blocking и ## Pre-existing (см. «Разделы ответа ревьюера»), затем продолжай работу
0CHANGES_REQUESTEDСкорректируй и отправь снова (см. «Accept or Argue»)
1ERRORСообщи об ошибке, предложи проверить session_id
2ESCALATEОповести пользователя, выведи краткое резюме, предложи варианты (см. «Обработка ESCALATE»)
3NO_SESSIONСпроси: создать сессию через init?

При ERROR круг не состоялся: итерация не израсходована, тот же запрос можно отправить повторно. Итерацию расходует прогон, который вернул вердикт, — даже если сам запуск завершился ошибкой после этого.

Обработка ESCALATE (exit 2)

Когда лимит итераций исчерпан:

  1. Получи путь: STATE_DIR=$(bash scripts/codex-state.sh dir). Прочитай заметки ревью из $STATE_DIR/notes/ (файлы {phase}-review-{N}.md)
  2. Выведи пользователю краткое резюме:
    • Какой этап (plan/code), сколько итераций прошло
    • Ключевые замечания и статусы по каждой итерации (1-2 строки на итерацию)
  3. Используй AskUserQuestion с тремя вариантами:
    • Ещё одна итерация — разово расширить лимит на 1
    • Снять лимит — убрать ограничение для этой сессии
    • Прекратить ревью — вывести финальное резюме и остановиться (Вариант «Свой вариант» добавляется автоматически)

Обработка ответа:

  • «Ещё одна итерация» → повтори вызов codex-review.sh {phase} "..." --max-iter $((текущий_лимит + 1))
  • «Снять лимит» → повтори вызов codex-review.sh {phase} "..." --max-iter 999
  • «Прекратить ревью» → выведи финальное резюме и заверши процесс ревью
  • Свой вариант → следуй инструкции пользователя

STATUS.md

Файл STATUS.md в state-каталоге ветки (путь: codex-state.sh dir) создаётся и обновляется автоматически скриптами. Не редактируй его вручную.

  • Файл появляется при init и обновляется при каждом plan/code и codex-state.sh set
  • Файл удаляется при финальном APPROVED на этапе code и при reset --full
  • Наличие файла = активное ревью, отсутствие = ревью не идёт

Verdict

Codex пишет свой вердикт в verdict.txt внутри state-каталога ветки (одно слово: APPROVED или CHANGES_REQUESTED). Для чтения вердикта используй bash scripts/codex-state.sh get verdict — helper возвращает APPROVED, CHANGES_REQUESTED или пустую строку (нет/невалидно). Файл очищается перед каждым запросом ревью, поэтому слово в нём написано текущим кругом. Вердикт берётся только отсюда: текст ответа на решение не влияет. Если после прогона в файле нет APPROVED или CHANGES_REQUESTED — круг не состоялся: скрипт возвращает ERROR (exit 1), итерация не расходуется, ответ ревьюера сохраняется рядом с логом попытки как codex-<фаза>-<N>.reply.md. Рядом с вердиктом лежит verdict.phase — одно слово, plan или code: фаза, которая его получила. Оба файла удаляются вместе.

Плагинный хук ExitPlanMode связывает вердикт с текущей Claude-сессией через current_session.txt в том же каталоге — verdict, пришедший из другой сессии, удаляется. Хук пропускает ExitPlanMode только при APPROVED с пометкой plan. Вердикт с пометкой code или без пометки хук удаляет и отвечает отказом с указанием запустить ревью плана.

Завершённый цикл

APPROVED на фазе code закрывает цикл: STATUS.md удаляется, а следующий plan или code завершается с exit 1 и ничего не меняет. Дальше — один из двух путей:

  • Новая задача — codex-review.sh init "<задача>": прежний цикл уходит в архив, открывается новая сессия Codex.
  • Доработки той же задачи — codex-state.sh reset, затем обычный круг: счёт кругов с первого, название задачи и session_id сохраняются.

Каждый круг печатает в stderr, к какой задаче он относится: Task: <название> в первом круге и Continuing task: <название> (previous round <время>), если по этой ветке уже были круги. Если название не совпадает с текущей задачей — цикл принадлежит другой работе: выбери один из двух путей выше до отправки круга.

Разделы ответа ревьюера

Ответ ревьюера разложен на три раздела. Что делать с каждым:

РазделДействие
## Blockingисправь или оспорь каждый пункт — см. «Accept or Argue»
## Non-blockingне исправляй по своей инициативе; вынеси список пользователю через AskUserQuestion (взять в работу / отдельной задачей / не делать)
## Pre-existingвынеси каждый пункт уровня critical пользователю через AskUserQuestion (чинить сейчас / отдельной задачей / не чинить) до того, как объявишь ревью законченным; остальные пункты — вместе с ## Non-blocking

При APPROVED с непустым ## Non-blocking работа считается принятой: отправлять новый круг ревью из-за этих пунктов не нужно.

Правила

  • НИКОГДА не вызывай codex exec напрямую — только через скрипты codex-review.sh и codex-state.sh. Скрипты сами знают модель, конфиг и session_id
  • Описывай ЧТО ты сделал и ПОЧЕМУ, какие решения принимал — используй шаблоны описания
  • НЕ передавай git diff — Codex сам посмотрит, он в той же директории
  • APPROVED → обработай ## Non-blocking и ## Pre-existing, затем продолжай работу
  • Перед реализацией вызови codex-state.sh set phase implementing
  • Есть заказчик (пользователь) — уточняй у него неоднозначные вопросы
  • Опция --max-iter N позволяет изменить лимит итераций

Worktree & Branch Isolation

Состояние ревью изолировано по ветке. Скрипты автоматически определяют основной репозиторий и текущую ветку. Параллельная работа на нескольких ветках/worktrees безопасна. config.env — общий (в корне .codex-review/). Для получения пути к state-каталогу текущей ветки используй codex-state.sh dir.

Один запуск на ветку

init, plan, code, codex-state.sh set и codex-state.sh reset занимают ветку на всё время работы: каталог .lock внутри state-каталога. Второй запуск по той же ветке завершается с exit 1, ничего не меняя, и печатает, какая команда держит ветку, её pid, машину и время начала.

Если в тексте ошибки сказано, что процесс работает, — дождись его конца и повтори команду.

Если сказано, что процесс не работает или что это нельзя определить (замок с другой машины, от другого системного пользователя, без записи о владельце), — убедись, что по этой ветке ничего не выполняется, удали названный в ошибке каталог .lock и повтори команду. Замок снимает только тот запуск, который его взял, или человек.

Чтение состояния замок не берёт: show, get и dir отвечают всегда.

Auto-Workflow (AUTO_REVIEW=true)

When AUTO_REVIEW=true in .codex-review/config.env, the entire review cycle runs automatically. A plugin hook blocks ExitPlanMode until Codex approves the plan.

Plan phase

  1. Write the plan in plan mode as usual
  2. Before calling ExitPlanMode, run review:
    bash scripts/codex-review.sh init "task description"   # ALWAYS init for a new plan — archives previous session
    bash scripts/codex-review.sh plan --plan-file ~/.claude/plans/<slug>.md
    
    IMPORTANT: Always run init before the first plan review in a conversation. Even if codex-state.sh show reports an existing session, it may be stale (from a previous conversation). The init command safely archives the old session and creates a fresh one. Only skip init when re-submitting after CHANGES_REQUESTED within the same review cycle.
  3. Formal verdict check — run bash scripts/codex-state.sh get verdict. Proceed ONLY if it outputs the exact string APPROVED. Do NOT interpret review text — only the helper output matters.
  4. CHANGES_REQUESTED → fix the plan, resubmit (follow «Accept or Argue» rules). Iterate automatically up to the iteration limit.
  5. APPROVED → handle ## Non-blocking and ## Pre-existing first (see «Разделы ответа ревьюера»), then call ExitPlanMode (the hook auto-approves it)

Implementation phase

  1. Implement as usual. Set phase: bash scripts/codex-state.sh set phase implementing

Code phase

  1. After implementation, run code review:
    bash scripts/codex-review.sh code "code description"
    # or, when the description contains backticks / `
    
      
        
        
        codex-review · Skills-SI 市场
        
        
        
        
        
        
        
        
      
      
        
    / `$(...)`: bash scripts/codex-review.sh code --description-file /path/to/description.md
  2. Formal verdict check — same as step 3: run bash scripts/codex-state.sh get verdict and check for exact string APPROVED.
  3. CHANGES_REQUESTED → fix code, resubmit automatically.
  4. APPROVED → handle ## Non-blocking and ## Pre-existing (see «Разделы ответа ревьюера»), then report to user.

ESCALATE handling in auto mode

Same as standard ESCALATE handling — present summary and ask user via AskUserQuestion.

Accept or Argue

При получении CHANGES_REQUESTED:

  1. Прочитай предыдущую review note из $(bash scripts/codex-state.sh dir)/notes/{phase}-review-{N}.md
  2. Критически оцени каждый пункт раздела ## Blocking. В описании к повторной отправке адресуй каждый из них поточечно:
    • Исправлено: [что именно исправил и как]
    • Не согласен: [контраргумент с обоснованием — Codex видит историю и может принять или настоять]
    • Отложено: [причина — только с согласия пользователя через AskUserQuestion]
  3. Запиши в то же описание решение пользователя по пунктам ## Non-blocking и ## Pre-existing
  4. Если один и тот же пункт ## Blocking повторяется 2+ раза без нового содержания (Codex настаивает, ты уже аргументировал) — эскалируй пользователю через AskUserQuestion: покажи замечание, свои аргументы, и спроси решение
  5. Если два круга подряд весь ## Blocking состоит из дефектов в коде, который породили правки прошлых кругов, — останови круги и спроси пользователя через AskUserQuestion: ещё круг правок или откат механизма к состоянию до ревью
  6. При исчерпании лимита итераций — следуй процедуре «Обработка ESCALATE»
我的收藏