--- name: task-batch description: Проводит несколько задач разом — планирует порядок и пересечения, гонит каждую задачу отдельным сабагентом в своём git worktree через task-pipeline, интегрирует по одной ветке через rebase + fast-forward (линейная история), проверяет полноту ревью каждой ветки и в конце сверяет стыки, возникшие от слияния. Набор задач приходит извне. Использовать, когда просят сделать несколько задач сразу. --- # Батч задач Оркестратор **набора** задач. Планирует порядок, раскидывает задачи по изолированным worktree, каждую проводит через полный цикл `task-pipeline`, затем сводит в основную ветку линейной историей и делает финальную сверку. Тонкая обёртка над `task-pipeline` — не переизобретай её шаги, вызывай как есть. Работай **максимально автономно**, по тому же принципу, что и одиночный пайплайн: вопрос, который решать не тебе, записывается и не останавливает поток; спрашиваем только про **необратимое** (деплой, выкладка наружу, удаление или перезапись рабочих данных). Механику — планирование, worktree, rebase, интеграцию, чистку — делаем без спроса. Перед стартом прочитай `CLAUDE.md` проекта и бриф ревью (`docs/review-brief.md`): из него берутся команда гейта, инварианты и раскладка нумерованных артефактов. ## Границы - **Набор задач приходит извне.** Батч его не формирует: не выбирает из беклога, не приоритизирует, не решает, что важнее. Набор не задан — попроси его у вызывающего и остановись. - **Батч не владеет спринтом и целями.** Он сообщает исход по каждой задаче в тех же трёх словах, что и `task-pipeline`: сделана / не доведена / оказалась крупнее задачи. ## Ключевое отличие от одиночного пайплайна `task-pipeline` коммитит **в текущую ветку**, и при ручном запуске это основная ветка. Здесь так нельзя для параллельных задач, поэтому батч — **осознанное исключение**: временные ветки и worktree заводятся лишь как средство изоляции, а конечное состояние — та же линейная история основной ветки через rebase + fast-forward. Ветки после вливания удаляются. ## Модель исполнения - Каждая задача = **один автономный сабагент** (`general-purpose`, чтобы иметь доступ к Skill и Agent для вложенных чекпоинтов ревью), работающий **только в своём worktree** и прогоняющий `task-pipeline` целиком на этой задаче. - Оркестратор кода задач не пишет: он планирует, заводит worktree, запускает сабагентов, проверяет полноту их ревью, интегрирует ветки и делает финальную сверку. - Стиль правок внутри — заточка под проект и конвенции, right-size, без золочения. ## Шаги ### 1. Прочитать набор Набор задан списком (слаги, файлы, описания) — прочитай файл каждой задачи и связанные спеки и черновики. Задачи-идеи включаются, но помни: сабагент проведёт их сперва через `opsx:explore`, это тяжелее и чаще упирается в вопрос. ### 2. Спланировать порядок и пересечения (автономно) Для каждой задачи определи: - **затронутые capability** — по её описанию и по каталогу актуальных спек (`openspec/specs/`); - **жёсткие зависимости**: задача B строится на результате A → A строго раньше B; - **нумерованные артефакты — номера раздаёт оркестратор заранее.** Если проект нумерует миграции или подобные файлы (путь — из брифа), посмотри последний номер и **раздай номера тем задачам, которые, вероятно, их добавят**, до запуска. Номер уходит в charter сабагента, и он берёт назначенный, а не «следующий свободный». Так такие задачи можно гнать одновременно: файлы не столкнутся, а описание схемы правят разные строки — конфликт мелкий и решается на интеграции; - **жёстко сериализуем** (не гоняем одновременно) настоящие пересечения: - **одна capability на несколько задач** — две задачи, правящие одну спеку (тем более одно и то же `### Requirement`), дают не текстовый, а **семантический** конфликт при архивации; сериализуем по смыслу, а не только по файлам; - пересечение по одним и тем же исходникам; - **мягкие конфликты** сериализовать не надо: индекс беклога (каждая задача убирает свою строку) и спеки разных capability — разные строки и файлы, сливаются сами. Собери план: **волны** параллельно-безопасных задач плюс сериализованный хвост конфликтоопасных, с учётом зависимостей. Покажи план короткой репликой и иди дальше. ### 3. Свежая база Убедись, что рабочее дерево чистое и основная ветка свежая. Зафиксируй базовый коммит. Новые ветки бери от свежей вершины; ветки следующей волны — от вершины, уже включающей результат предыдущих волн. ### 4. Прогнать волны **Потолок параллелизма — 2–3 задачи одновременно.** Каждая задача тянет полный `task-pipeline` с вложенным ревью и гейтом, поэтому больше трёх разом душат машину и провоцируют гонки. Волну шире трёх бей на под-пачки по ≤3. **Волна из одной задачи — не вырожденный случай, а обязательный.** Задача, ревью которой будет доказывать находки **числами** (профиль `deep`, где работают `adversary` и `ops`: удержание блокировки, пик памяти, рост файлов, длительность операции), гонится в волне одна. Соседний прогон на той же машине портит эти числа, а находка с испорченным оракулом хуже отсутствующей — она выглядит доказанной. Если задача всё же пошла в общей волне, её отчёт обязан нести строку в границах покрытия: замеры сняты под соседней нагрузкой. Для каждой задачи в под-пачке: 1. Заведи worktree и ветку от текущей вершины: `git worktree add -b task/ <основная ветка>`. Путь — во временном каталоге проекта (`./tmp`), не в системном `/tmp`. 2. Запусти **по одному сабагенту на задачу, все в одном сообщении**, `subagent_type: general-purpose`. Charter сабагента: - работай **строго в своём worktree** ``; в другие каталоги и в основную ветку не лезь; - прогони Skill **`task-pipeline`** ровно на этой задаче, полный цикл SDD с обоими чекпоинтами ревью; - если задаче назначен **номер артефакта** — используй строго его; - **профиль ревью выбирается по факту изменения.** Батч не повод понижать профиль: «нас много и мы спешим» — это ровно тот стимул, из-за которого проходы пропускают; - **режим прогона проходов — последовательный.** Твой worktree не один на машине; - **вернуть отчёт**, в котором обязательно: исход задачи одним из трёх слов; что сделано; какие вопросы записаны и куда; изменённые файлы; добавлялся ли нумерованный артефакт и с каким номером; затронутые capability; состояние гейта; **перечень запущенных проходов ревью поимённо с исходом каждого** и границы покрытия. Сабагент, упершийся в вопрос, **не останавливает батч**: он записывает вопрос, режет задачу до остатка и доводит остаток — либо, если остатка нет, возвращает исход «не доведена». Оркестратор собирает такие вопросы и выносит их в финальный доклад пачкой. ### 5. Проверить полноту ревью — до интеграции **Ветка, чей отчёт не называет проходы поимённо, не вливается.** Пропуск прохода не отличим от прохода без находок, и на уровне батча это ещё опаснее: отчётов много, каждый выглядит полным, а сверять их некому, кроме тебя. По каждой готовой ветке сверь перечень проходов с таблицей профилей скилла `review-pipeline` для объявленного профиля. Расхождение — не повод отменять задачу: дозапусти недостающие проходы **на ветке**, в её worktree, через `review-pipeline`, и только потом интегрируй. Отчёт дозапуска приложи к отчёту задачи. ### 6. Интегрировать — rebase + fast-forward, по одной ветке Сводим ветки **строго последовательно** (линейная история), в порядке зависимостей. Вливаем **только зелёные**. Для каждой готовой ветки `task/`: - `git rebase <основная> task/` — перенос на текущую вершину; - резолв конфликтов (их почти нет — конфликтоопасное сериализовано, номера розданы заранее). Неавтоматический конфликт — **не форсируй**: прерви (`git rebase --abort`), оставь ветку и worktree как есть, вынеси это в доклад как нераспознанное пересечение; - `git checkout <основная> && git merge --ff-only task/`; - после каждой интеграции — **гейт на основной ветке**. Красное — **откати эту интеграцию** (`git reset --hard` на прошлую вершину), ветку с worktree сохрани, задачу перечисли в докладе. Основная ветка **никогда** не остаётся полузелёной; - только после зелёного: `git worktree remove ` и `git branch -d task/`. **Политика частичного провала.** Упавшая задача (исход «не доведена», красные тесты в её worktree, конфликт при rebase) **не блокирует остальные**: интегрируем все зелёные, упавшую оставляем в её worktree и ветке нетронутой — ничего не удаляем, — и перечисляем в докладе с причиной, отчётом и путём к worktree. ### 7. Финальный гейт На основной ветке после всех интеграций — гейт целиком. Зелёное обязательно; пока красное, шаг 8 не начинается. ### 8. Финальная сверка — только то, чего не видел никто Каждая задача уже прошла полный конвейер в своём worktree. Повторять его на интегрированном диффе бессмысленно: те же проходы на тех же файлах дадут те же находки и удорожат триаж. Здесь проверяется **только то, что появилось от слияния**: - запусти **по одному `review-specs` на каждую затронутую capability**. Набор назван поимённо и замеров эти проходы не делают, поэтому их допустимо гнать одним сообщением — это то самое отступление от последовательного режима, которое правило разрешает. Задание сузь до стыков: не сверять capability целиком заново, а искать **рассинхрон код↔спека, возникший от слияния** — требование, которое одна задача выполнила, а соседняя незаметно отменила; два change, по-разному описавшие одно поведение; - если задачи пересекались по файлам, добавь один `review-architecture` на интегрированный дифф с вопросом «не появился ли второй способ делать то, что уже делается» — именно он возникает, когда две задачи независимо решали похожее. Замечания отрабатывай как в `task-pipeline`: `инлайн` чини сам, `развилка` — вопросом в запись; после правок — снова гейт. ### 9. Прибраться и доложить - Убери worktree и ветки **только успешно влитых** задач, в конце `git worktree prune`. Worktree и ветки **провалившихся** не трогай — они нужны для ручного дожатия. - Доложи кратко: - **исход по каждой задаче** одним из трёх слов, с хешем коммита; - план волн и порядок интеграции; - вопросы, записанные сабагентами, пачкой; - что дозапускалось на шаге 5 и почему; - итог финальной сверки и ссылки на архивные change; - **отдельно — провалившиеся** задачи с причиной и путём к оставленному worktree; - **границы покрытия сводной строкой**, включая задачи, чьи замеры снимались в общей волне. ## Тонкости - **Изоляция параллельных тестов.** Прежде чем гнать несколько прогонов разом, убедись, что тесты не делят фиксированный порт или файл БД (обычно берут временный каталог и эфемерный порт — тогда ок). Делят — гони такие задачи последовательно. - Поведенческая верификация внутри сабагента поднимает изменение вживую: следи, чтобы соседние worktree не дрались за порты и рабочие каталоги. Если проект умеет поднимать только один экземпляр — такие задачи в одну волну не ставь. - Ревью выполненного — **до** закрытия задачи; это забота `task-pipeline` внутри каждого сабагента, дублировать не надо. - `openspec validate --strict` тоже внутри `task-pipeline` — не пропускай его своими правками на интеграции. - Крупная переработка, предложенная ревью внутри задачи, — развилка: не вливай молча, вынеси в доклад. - Держи вызывающего в цикле короткими репликами на переходах фаз (план → волны → интеграция → финальная сверка), но не проси подтверждать механику.