добавлены плагины av-dev-tasks и av-dev-pipeline
Пара плагинов с намеренно проведённой границей: av-dev-tasks отвечает за то, что делаем и в каком порядке, av-dev-pipeline — за то, как ведём одну задачу. Зависимости между ними нет: управление задачами работает и с ручным исполнением, пайплайн — на проекте с любым учётом задач. - av-dev-tasks — преемник av-dev-backlog: цели вместо приоритетов, спринт под одну цель с заморозкой набора, различение вопроса и блокера, каденция «вопросы — разбор — переоценка — набор». Раскладка docs/tasks с items/, PLAN.md, BACKLOG.md, SPRINT.md, REJECTED.md; проверенное из av-dev-backlog перенесено, не переписано. - av-dev-pipeline — вынос того, что лежало копиями в healthlog и jellybit (3628 строк) и уже разошлось: цикл SDD, конвейер ревью с обязательным триажем, прогон нескольких задач разом. Проектная специфика вынесена в файл-бриф, charter'ы несут метод. Коммит фиксирует состояние на момент ревью: три прохода нашли блокирующие дефекты (нет шага, заводящего бриф; git rebase на занятой worktree ветке; sprint drop пишет наполовину) — они чинятся следующими коммитами. Сохранено как база, от которой видно правки.
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
---
|
||||
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 <path> -b task/<slug> <основная ветка>`. Путь — во временном
|
||||
каталоге проекта (`./tmp`), не в системном `/tmp`.
|
||||
2. Запусти **по одному сабагенту на задачу, все в одном сообщении**,
|
||||
`subagent_type: general-purpose`. Charter сабагента:
|
||||
- работай **строго в своём worktree** `<path>`; в другие каталоги и в основную
|
||||
ветку не лезь;
|
||||
- прогони Skill **`task-pipeline`** ровно на этой задаче, полный цикл SDD с
|
||||
обоими чекпоинтами ревью;
|
||||
- если задаче назначен **номер артефакта** — используй строго его;
|
||||
- **профиль ревью выбирается по факту изменения.** Батч не повод понижать
|
||||
профиль: «нас много и мы спешим» — это ровно тот стимул, из-за которого
|
||||
проходы пропускают;
|
||||
- **режим прогона проходов — последовательный.** Твой worktree не один на
|
||||
машине;
|
||||
- **вернуть отчёт**, в котором обязательно: исход задачи одним из трёх слов;
|
||||
что сделано; какие вопросы записаны и куда; изменённые файлы; добавлялся ли
|
||||
нумерованный артефакт и с каким номером; затронутые capability; состояние
|
||||
гейта; **перечень запущенных проходов ревью поимённо с исходом каждого** и
|
||||
границы покрытия.
|
||||
|
||||
Сабагент, упершийся в вопрос, **не останавливает батч**: он записывает вопрос,
|
||||
режет задачу до остатка и доводит остаток — либо, если остатка нет, возвращает
|
||||
исход «не доведена». Оркестратор собирает такие вопросы и выносит их в финальный
|
||||
доклад пачкой.
|
||||
|
||||
### 5. Проверить полноту ревью — до интеграции
|
||||
|
||||
**Ветка, чей отчёт не называет проходы поимённо, не вливается.** Пропуск прохода
|
||||
не отличим от прохода без находок, и на уровне батча это ещё опаснее: отчётов
|
||||
много, каждый выглядит полным, а сверять их некому, кроме тебя.
|
||||
|
||||
По каждой готовой ветке сверь перечень проходов с таблицей профилей скилла
|
||||
`review-pipeline` для объявленного профиля. Расхождение — не повод отменять
|
||||
задачу: дозапусти недостающие проходы **на ветке**, в её worktree, через
|
||||
`review-pipeline`, и только потом интегрируй. Отчёт дозапуска приложи к отчёту
|
||||
задачи.
|
||||
|
||||
### 6. Интегрировать — rebase + fast-forward, по одной ветке
|
||||
|
||||
Сводим ветки **строго последовательно** (линейная история), в порядке
|
||||
зависимостей. Вливаем **только зелёные**.
|
||||
|
||||
Для каждой готовой ветки `task/<slug>`:
|
||||
|
||||
- `git rebase <основная> task/<slug>` — перенос на текущую вершину;
|
||||
- резолв конфликтов (их почти нет — конфликтоопасное сериализовано, номера
|
||||
розданы заранее). Неавтоматический конфликт — **не форсируй**: прерви
|
||||
(`git rebase --abort`), оставь ветку и worktree как есть, вынеси это в доклад
|
||||
как нераспознанное пересечение;
|
||||
- `git checkout <основная> && git merge --ff-only task/<slug>`;
|
||||
- после каждой интеграции — **гейт на основной ветке**. Красное — **откати эту
|
||||
интеграцию** (`git reset --hard` на прошлую вершину), ветку с worktree сохрани,
|
||||
задачу перечисли в докладе. Основная ветка **никогда** не остаётся
|
||||
полузелёной;
|
||||
- только после зелёного: `git worktree remove <path>` и
|
||||
`git branch -d task/<slug>`.
|
||||
|
||||
**Политика частичного провала.** Упавшая задача (исход «не доведена», красные
|
||||
тесты в её 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` — не пропускай его
|
||||
своими правками на интеграции.
|
||||
- Крупная переработка, предложенная ревью внутри задачи, — развилка: не вливай
|
||||
молча, вынеси в доклад.
|
||||
- Держи вызывающего в цикле короткими репликами на переходах фаз (план → волны →
|
||||
интеграция → финальная сверка), но не проси подтверждать механику.
|
||||
Reference in New Issue
Block a user