Claude Code и Codex как подчинённые: эпик → карточки → воркеры в worktrees → ревью

Как раздать большую задачу по коду нескольким исполнителям так, чтобы они не мешали друг другу, а «готово» решал человек.

· 18 мин чтения

Коротко

  • Эпик раскладывается на карточки Workboard (встроенной канбан-доски OpenClaw) со связями. Проход раздачи, dispatch, запускает по готовым карточкам воркеров: по умолчанию до трёх за раз и не больше одной карточки на агента-владельца. Чтобы воркеры шли параллельно, карточки назначают разным агентам.
  • Каждый воркер получает свою рабочую копию репозитория (managed worktree) на отдельной ветке. Код в ней пишет Claude Code или Codex, вызванные через ACP.
  • Честная граница: proof, запись о проверке, пишет сам воркер, и это не независимая проверка. ACP работает на хосте вне песочницы OpenClaw. С правами по умолчанию запись или команда, на которую оболочка запросит разрешение, может оборвать сессию.

Кому и когда

У вас есть репозиторий и задача на несколько дней: переезд модуля, серия однотипных правок, пачка багов из одного отчёта. Одному агенту её не дать: контекст распухнет, а правки в одной ветке начнут наступать друг на друга. Хочется по-человечески: разбить на куски, раздать исполнителям, собрать результат и посмотреть его перед слиянием.

Сборка подходит, если куски независимы и у каждого есть критерий готовности: тест проходит, линтер молчит, в diff нет лишнего. Если задача не режется, подчинённые не помогут. Об этом в конце.

Всё ниже собрано по документации OpenClaw 2026.9.6 и выводу --help. Команды и конфиги взяты оттуда и собраны в одну схему. В живой инсталляции эту схему мы не прогоняли. Пути вида /srv/repo и тексты задач придуманы для иллюстрации.

Общая картина механизмов есть во флагманской статье, расписание — в статье про редакцию по расписанию.

Схема потока

  1. Эпик. Карточка в Workboard с описанием большой задачи.
  2. Нарезка. Агент-оркестратор уточняет карточку (workboard_specify) и раскладывает её на дочерние (workboard_decompose). Порядок задаётся связями (workboard_link): ребёнок ждёт в todo, пока все его родители не перейдут в done.
  3. Раздача. Dispatch продвигает готовые карточки в ready и запускает по ним воркеров.
  4. Изоляция. Карточка с рабочим пространством вида worktree получает свою рабочую копию wb-<card-id> на отдельной ветке.
  5. Код. Воркер — обычный субагент OpenClaw. Сам код он поручает Claude Code или Codex через ACP (Agent Client Protocol, протокол для внешних оболочек), указав рабочую копию как рабочую папку.
  6. Отчёт. Воркер прикладывает proof («какую команду или проверку запускал и чем кончилось») и закрывает карточку. Карточка уходит в review.
  7. Приёмка. Вы или ваш CI смотрите diff и тесты, сливаете ветку. В done карточку переводит человек.

Шаги 1–4 и 6–7 описаны в документации. Шаг 5 — наша сборка: dispatch по docs запускает обычных субагентов, а не ACP-оболочки. У вызова ACP изнутри воркера есть ограничение, о нём ниже.

Из чего собрано

Workboard. Встроенный плагин, по умолчанию выключен, карточки хранит в SQLite. Статусы: triage, backlog, todo, scheduled, ready, running, review, blocked, done.

Dispatch. Один проход делает четыре вещи. Продвигает карточки, у которых закрылись зависимости. Блокирует просроченные claim’ы (захваты карточки) и зависшие запуски. Отмечает triage-карточки, если так настроена доска. Берёт в работу небольшую партию через рантайм субагентов. Выполнением владеют обычные субагентские сессии OpenClaw.

Managed worktrees. OpenClaw создаёт git worktree (вторую рабочую папку того же репозитория) в своём каталоге состояния, на ветке openclaw/<name>. Перед удалением он снимает снапшот в refs/openclaw/snapshots/<id> и хранит его 30 дней. Для карточек Workboard рабочая копия называется wb-<card-id>.

ACP через плагин acpx. OpenClaw запускает внешнюю оболочку (Claude Code, Codex CLI, Gemini CLI и другие) как настоящий процесс на хосте. Маршрутизация, учёт задачи и доставка результата за OpenClaw; вход к вендору, модели, файлы и инструменты за оболочкой.

Отдельно про Codex. У него в OpenClaw два пути, и рекомендован нативный плагин Codex (через собственный сервер приложений Codex, app-server), а не ACP. ACP для Codex — явный выбор: runtime:"acp", agentId:"codex". В этой статье берём ACP, потому что тогда Claude Code и Codex подключаются одинаково.

Шаги

1. Включить ACP и выбрать оболочки

Плагин бэкенда ставится отдельно:

openclaw plugins install @openclaw/acpx
openclaw config set plugins.entries.acpx.enabled true

Базовый конфиг из документации. Список разрешённых оболочек сокращён до двух, defaultAgent мы поменяли с codex на claude, чтобы не путать с нативным путём Codex:

{
  acp: {
    enabled: true,
    dispatch: { enabled: true },
    backend: "acpx",
    defaultAgent: "claude",
    allowedAgents: ["claude", "codex"],
    stream: { deliveryMode: "live" },
  },
}

Грабли первого запуска, все из docs. Если задан plugins.allow, в нём обязан быть acpx. Вход к вендору должен уже быть на хосте: для claude нужен авторизованный Claude Code. У Codex через ACP свой изолированный CODEX_HOME: доверенные проекты и настройки модели копируются с хоста, вход и хуки остаются в конфиге хоста. Адаптеры, кроме Codex, при первом запуске качаются через npx, без сети это упадёт.

Проверка: /acp doctor в чате. Он должен показать включённый и здоровый бэкенд.

2. Решить вопрос с правами до первого запуска

Это самое важное место. У ACP-сессии нет терминала, и нажать «разрешить» в ней некому. По умолчанию стоят permissionMode=approve-reads (сами одобряются только чтения) и nonInteractivePermissions=fail (если нужен запрос, сессия обрывается). Документация предупреждает: любая запись или команда, на которую оболочка запросит разрешение, может упасть с PermissionPromptUnavailableError: Permission prompt unavailable in non-interactive mode.

Варианты:

Настройка Что будет с воркером
approve-reads + fail (по умолчанию) Падает, когда оболочке нужно разрешение на запись или команду. Для кода не годится.
approve-reads + deny Не падает, но такие записи и команды тихо отклоняются. Годится для ревью и разбора, писать код он не сможет.
deny-all Отклоняет все запросы разрешений. Для кода не годится.
approve-all Пишет файлы и выполняет команды без вопросов. Документация называет это аварийным рубильником.

Ставится через конфиг плагина:

openclaw config set plugins.entries.acpx.config.permissionMode approve-all
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail

Эти права живут отдельно от exec approvals OpenClaw (одобрений команд на хосте). По docs одни не ослабляют другие: слои независимы, и approve-all действует на уровне оболочки. Оболочка пишет по своим правам в выбранном cwd, а это рабочая папка, не изоляция.

3. Включить Workboard и завести эпик

openclaw plugins enable workboard
openclaw gateway restart
openclaw workboard create "Перевести модуль платежей на новый клиент" --priority high --labels epic

Учтите сразу: у workboard create в CLI нет поля для рабочего пространства (по --help флаги только --agent, --board, --json, --labels, --notes, --priority, --status). Как привязать карточки к репозиторию, расписано в шаге 4.

Дальше работа идёт инструментами агента. Оркестратор вызывает workboard_specify: черновая карточка превращается в уточнённую todo с записанным резюме. Затем workboard_decompose раскладывает её на связанные дочерние, а workboard_link задаёт порядок там, где он нужен.

Наш совет, запуском не проверенный: в каждой дочерней карточке пишите, чем проверяется готовность. Например: «тесты payments/ зелёные, публичный API не изменился». Логика простая: proof — то, что воркер сам сообщает о своей проверке. Если в карточке не сказано, что проверять, воркер выберет проверку сам.

4. Привязать карточки к рабочим копиям

Рабочее пространство карточки в docs выглядит так:

{
  "kind": "worktree",
  "path": "/absolute/path/to/source-checkout",
  "branch": "main"
}

path — исходный git-репозиторий, branch — базовая ветка, необязательная. По документации задать его можно в двух местах:

  • инструментом агента workboard_create: он принимает метаданные рабочего пространства, а заодно лимит времени запуска и бюджет повторов;
  • на уровне доски: workboard_board_create хранит рабочее пространство по умолчанию.

Значит, карточки с рабочим пространством создаёт оркестратор, а не CLI. Проще всего попросить его завести доску с рабочим пространством по умолчанию и работать на ней (--board <id> в CLI). workboard_decompose переносит на детей доску; про наследование рабочего пространства docs не пишут, поэтому проверяйте:

openclaw workboard show <id> --json

Если рабочего пространства в карточке нет, копии wb-<card-id> не будет: её создаёт именно workspace вида worktree.

Дальше путь раздваивается, и это главная развилка всей схемы.

Полный доступ к хосту (клиент Gateway, центрального процесса OpenClaw, с правом operator.admin; в CLI это dispatch --admin). Workboard создаёт или переиспользует копию wb-<card-id>, запускает субагента с ней как рабочей папкой и записывает путь и ветку обратно в карточку. В конце запуска копия удаляется, только если это без потерь.

Доступ, привязанный к workspace агента. Путь должен точно совпадать с workspace целевого агента, отдельная копия не создаётся. Обязательное условие: писабельная, не общая Docker-песочница без выхода на хост.

5. Дать воркеру Claude Code или Codex

Внутри воркера код пишет внешняя оболочка. Запуск по образцу из docs, с рабочей копией в cwd:

{
  "task": "Карточка 7f4a2c10: перевести payments/client.py на новый клиент, прогнать тесты payments/",
  "runtime": "acp",
  "agentId": "claude",
  "mode": "run",
  "cwd": "/путь/к/wb-<card-id>"
}

mode:"run" означает разовый запуск: фоновая задача на той же полосе, что и субагенты, результат возвращается родителю объявлением о завершении. Для Codex: "agentId": "codex".

Не забудьте cwd. Если его не передать, ACP-сессия наследует workspace целевого агента, если он настроен, иначе берёт папку по умолчанию оболочки. Claude Code тогда будет править не рабочую копию, и схема сломается молча. Воркер уже запущен в рабочей копии, путь к ней записан в карточке. В инструкции воркеру прямо напишите: «в cwd передавай путь рабочей копии из карточки». После первого запуска проверьте обычным git, что изменения появились там, где надо:

git -C <путь-к-wb-копии> status
git -C <workspace-агента> status

Здесь ловушка, которая убивает половину схемы. Сессия в песочнице не может запускать ACP. Ни через sessions_spawn, ни через /acp spawn. Значит, второй путь из шага 4 (воркер в Docker-песочнице) с ACP несовместим. Остаются два честных варианта:

  • полный доступ к хосту: рабочая копия wb-<card-id>, агент-воркер без песочницы, внутри него ACP;
  • песочница: код пишет сам воркер-субагент, без Claude Code и Codex.

Важно: --admin даёт доступ к чужим checkout’ам (рабочим папкам репозиториев) и создание копий, но песочницу с воркера не снимает. Песочница задаётся конфигом агента-воркера. Проверить её можно так:

openclaw sandbox explain --agent <id>

Связку «dispatch → воркер → ACP» docs как готовый сценарий не описывают, мы собрали её из двух частей. Глубину вложенности воркера от dispatch docs не называют. По умолчанию дети разрешены до глубины 5 (maxSpawnDepth); если вы снизили предел, воркер может оказаться «листом» без права запуска.

Ловушка с worktree: true

У sessions_spawn есть параметр worktree: true, и хочется передать его прямо в ACP-вызов. Не выйдет. По справочнику инструмента worktree, worktreeName и worktreeBaseRef требуют visible: true, то есть постоянной сессии в боковой панели, а visible поддерживает только runtime:"subagent". Документация отдельно пишет, что visible: true ACP-вызов совместимым не делает, а внутренние воркеры для кода остаются обычными субагентами.

Для ACP рабочая копия делается заранее и передаётся через cwd. Без Workboard это выглядит так:

openclaw worktrees create /srv/repo --name payments-client --base-ref main

Флаги сверены с openclaw worktrees create --help. Имя — от 1 до 64 символов: строчные латинские буквы, цифры и дефис, первый символ не дефис. Ветка будет openclaw/payments-client. С явным --base-ref OpenClaw берёт ровно этот ref и не делает fetch, так что локальный main может отставать от удалённого. Созданные вручную рабочие копии автоматически не удаляются никогда, их чистите сами.

Игнорируемые git файлы вроде .env.local перечисляют в .worktreeinclude. Подготовку (установку зависимостей) кладут в .openclaw/worktree-setup.sh: ненулевой код выхода прерывает создание, запускается скрипт только у вызывающего с operator.admin, git-хуки репозитория при создании отключены.

6. Раздать

openclaw workboard dispatch --admin

Правила раздачи консервативные. По умолчанию не больше трёх новых воркеров за проход, предел меняется флагом --max-starts. Карточки идут по приоритету, затем по позиции, затем по времени создания. Если воркер не стартовал, карточка уходит в blocked с записью о причине, а не возвращается в очередь молча.

Главное ограничение для параллели: за проход стартует одна карточка на владельца или агента, а владельцы, у которых уже есть работа в running или review, пропускаются. Неназначенные карточки уходят к агенту по умолчанию, то есть к одному владельцу. Отсюда два вывода:

  • карточки одного агента идут строго по очереди;
  • пока карточка лежит в review и ждёт вас, следующая карточка того же агента не стартует.

Чтобы воркеры шли параллельно, назначайте карточки разным агентам: --agent <id> в CLI или поле агента карточки. Каждый такой агент должен быть настроен и, для ACP, работать без песочницы.

Без живого Gateway CLI откатывается в режим «только данные»: продвигает зависимости, чистит claim’ы, блокирует просроченные запуски, но воркеров не запускает. В выводе: gateway unavailable; data dispatch only. Так бывает, только если не заданы --url/--token и не настроен удалённый Gateway; иначе будет обычная ошибка команды.

Инструмент агента workboard_dispatch воркеров не запускает, только подталкивает продвижение и чистку. Запуск идёт из Control UI, CLI или /workboard dispatch в чате.

7. Забрать результат

Карточка в review значит, что сессия воркера завершилась. Дальше работает обычный git, а не OpenClaw.

По docs в конце запуска чистая копия без незапушенных коммитов удаляется, остальные остаются. Как воркер публикует ветку, docs не описывают. Это решение сборки, пропишите его в карточке: «закоммить в ветку рабочей копии» или «запушь ветку».

Если копия осталась, найдите путь и ветку в openclaw workboard show <id> --json или openclaw worktrees list --json и смотрите изменения обычным git:

git -C <путь-к-копии> status
git -C <путь-к-копии> diff main...HEAD
git -C /srv/repo merge <ветка-копии>

Если воркер пушил, ревьюйте ветку в своём репозитории или через PR, как любую другую. Сливайте до удаления копии: при удалении OpenClaw удаляет ветку через git branch -d по снапшоту.

Как проверить, что сработало

  • openclaw workboard list --status running: карточки, по которым идут воркеры.
  • openclaw workboard show <id> --json: рабочее пространство, запуск, попытки, proof, журнал воркера, диагностика.
  • openclaw worktrees list --json: живые и восстановимые рабочие копии и итог очистки.
  • /acp status: состояние ACP-сессии.
  • git -C <путь-к-копии> status: изменения легли в рабочую копию, а не в workspace агента.

Пока карточка в работе, её статус следует за связанной сессией: активна — running, завершилась — review, упала, убита, вышла по таймауту или прервана — blocked.

Три диагностики Workboard стоит смотреть каждый раз:

  • running_without_heartbeat: карточка в работе без heartbeat (периодического сигнала «жив») и без обновлений запуска больше 20 минут;
  • repeated_failures: два и больше провала;
  • missing_proof: карточка в done без proof, артефактов и вложений.

Если ACP-сессия падает почти без вывода, ищите в логах Gateway AcpRuntimeError. Docs называют вероятной причиной заблокированные запросы разрешений, так что первым делом проверьте права из шага 2.

Как откатить

Остановить один запуск. Кнопка Stop на карточке прерывает запуск и ставит карточку в blocked. Для ACP-сессии есть /acp cancel (текущий ход) и /acp close (вся сессия).

Пауза всей схемы. Не запускайте dispatch: сам он ничего не делает, пока его не вызовут. acp.dispatch.enabled=false останавливает только автоматическую маршрутизацию ACP из тредов. Явные вызовы sessions_spawn({ runtime: "acp" }) продолжат работать.

Убрать копию, ничего не теряя. Код живёт в отдельной ветке рабочей копии, основная ветка не тронута.

openclaw worktrees remove <id> --if-lossless --json

Удаляет копию, только если она чистая и всё опубликовано. Грязную или с незапушенными коммитами оставляет и отвечает removed: false. Это не успешное удаление.

Выбросить работу воркера, оставив снапшот на 30 дней.

openclaw worktrees remove <id>
openclaw worktrees restore <id>   # если передумали

Обычное удаление архивное: сначала снапшот, потом копия удаляется вместе с грязными файлами. Ветка openclaw/<name> удаляется только через git branch -d по снапшоту. Если её вершина ушла дальше снапшота, ветка остаётся. --force удаляет, даже если снапшот не удался, и это уже потеря.

Вернуть права оболочки.

openclaw config set plugins.entries.acpx.config.permissionMode approve-reads
openclaw config get plugins.entries.acpx.config.permissionMode

По docs изменение подхватывается без рестарта в режиме перезагрузки по умолчанию. Workboard выключается командой openclaw plugins disable workboard, рестарт Gateway — по аналогии с включением.

Если состояние разошлось, документация советует смотреть сам git: git -C <repo-root> worktree list и git -C <repo-root> branch --list 'openclaw/*'.

Где человек

В трёх местах, и все три не автоматизируются.

Перед стартом. Человек решает, какой режим прав дать оболочке. approve-all — осознанный выбор, а не настройка по умолчанию.

На ревью. Proof в Workboard — это то, что воркер сам о себе сообщил. Документация пишет прямо: статус passed означает, что воркер сообщает об успехе своей команды или проверки, а не что кто-то независимо это проверил. Если нужен настоящий гейт, смотрите приложенную команду, ссылку или артефакт и гоняйте собственный верификатор: тесты в CI, сборку, линтер.

На done. Сессия завершилась, и карточка сама переходит в review, но не дальше. В done её переводит человек после приёмки. Ручной перевод в review, blocked или done выключает автосинхронизацию для этой карточки.

Сколько стоит

Цифр не даём: они зависят от тарифов и размера задач. Стоимость складывается из двух независимых счётчиков:

  1. Сторона OpenClaw. Оркестратор и воркеры-субагенты тратят токены вашей модели. Их видно в openclaw gateway usage-cost: сводка по логам сессий, по умолчанию за 30 дней, есть --days и --agent. Пока кэш учёта обновляется, итоги могут быть неполными, команда об этом предупреждает.
  2. Сторона оболочки. Claude Code и Codex ходят к вендору под своим входом на хосте; для Copilot docs прямо говорят, что запуски тратят лимит тарифа аккаунта. Попадают ли токены оболочек в usage-cost, документация не говорит. Считайте их в кабинете вендора.

Грубая формула на эпик: число карточек × среднее число попыток × (ход воркера + запуск оболочки). Попытки видно в workboard show --json. Карточки с repeated_failures — главный источник перерасхода: каждый перезапуск платит обе стороны заново.

Что не сработает / где ломается

Параллель на одном агенте. Все карточки без --agent уходят к агенту по умолчанию и идут по одной, а непринятая карточка в review держит очередь. Нужны разные агенты-владельцы.

Песочница не оборачивает ACP. Оболочка работает на хосте по своим правам CLI и выбранному cwd, политика песочницы OpenClaw её не касается. OpenClaw по-прежнему проверяет, включён ли ACP, разрешён ли агент, кто владеет сессией и куда доставлять ответ. sandbox: "require" для ACP не поддерживается. Нужна изоляция от OpenClaw — берите runtime: "subagent".

Proof легко принять за проверку. Воркер, который написал «тесты прошли», мог прогнать не те тесты.

Таймауты. По умолчанию таймаута у запусков субагентов нет: без настройки действует 0. Задать общий можно так (900 секунд — пример из docs, а не рекомендация):

openclaw config set agents.defaults.subagents.runTimeoutSeconds 900

Дальше docs противоречат сами себе: справочник sessions_spawn разрешает runTimeoutSeconds в вызове и для ACP, страницы ACP говорят, что поштучный таймаут для ACP отклоняется. Задавайте общий. Вторая страховка — лимит времени запуска в карточке (workboard_create): просроченные запуски dispatch блокирует. timeoutSeconds плагина acpx (120 секунд) касается запуска и управления, длину хода он не ограничивает.

Сессия может зависнуть после работы. Оболочка закончила, а ACP-сессия не сообщила о завершении. Docs советуют обновиться: свежий acpx подчищает такие процессы. running_without_heartbeat поймает это через 20 минут.

Параллельность ограничена с трёх сторон. Dispatch: 3 за проход по умолчанию и одна карточка на владельца. Субагенты: по умолчанию не больше 5 активных детей на сессию (maxChildrenPerAgent) и 8 на всю полосу (maxConcurrent). Рабочие копии: каждая занимает место на диске. Перед созданием OpenClaw оставляет запас: 10% тома (от 4 до 16 GiB) плюс двойной размер checkout. Цель очистки — 100 живых копий. Это порог для уборки, а не жёсткий лимит.

Брошенные копии. Копии Workboard, которые простаивают больше 7 дней, удаляются со снапшотом, даже грязные. Вернулись через неделю — восстанавливайте из снапшота.

Что делает Run Claude, docs до конца не говорят. По docs кнопки Run Claude и Run OpenAI запускают агента с явным движком и моделью anthropic/claude-sonnet-4-6 или openai/gpt-6-astra; ACP там не упоминается. Считать это запуском Claude Code без проверки нельзя.

Когда брать другой инструмент

Задача одна и не режется. Один разговор с Claude Code или Codex в отдельной рабочей копии проще. Для Codex берите нативный плагин, он в OpenClaw рекомендован по умолчанию.

Нужна живая беседа с оболочкой, а не фоновая работа. /acp spawn claude --bind here привязывает текущий чат к сессии Claude Code, и дальше вы работаете с ней напрямую. Работает только в каналах, которые умеют привязку текущего разговора. Иначе будет ошибка Conversation bindings are unavailable for <channel>.

Нужна песочница. Обычные субагенты в Docker-песочнице, без ACP. Граница тогда держится на стороне OpenClaw.

Нужен трекер для команды. Workboard сам себя называет маленьким локальным инструментом и не заменяет GitHub Issues, Linear или Jira.

Нужен готовый цикл «план → одобрение → код → merge/PR». Есть сторонний плагин openclaw-code-agent. По README, он запускает Claude Code, Codex и OpenCode как фоновые сессии, с одобрением плана, изолированными worktrees и доведением до merge или PR. Это чужой код с собственной моделью прав. Версия 5.0.1, по README, требует OpenClaw не ниже 2026.9.7, то есть новее нашей.