Files
dev-skills/av-dev-pipeline/skills/task-batch/SKILL.md
T
avandClaude Opus 5 cbfae90f3f словарь: пять слов сняты, девять закрыты списком вместо оговорки «прижилось»
Проход упрощения уткнулся в один класс у всех пяти агентов: слово, живущее в
трёх-шести файлах разом. Правка в одном месте развела бы словарь, правка во
всех — уже не упрощение текста скилла. Каждый честно остановился и записал слово
в отчёт, и одни и те же слова всплыли в разных отчётах. Разобрано этим проходом.

Причина, по которой они вообще накопились, оказалась в самом уставе языка. Он
разрешал не переводить «термин, у которого нет точного русского эквивалента и
который в команде уже прижился». Проверить это нельзя: прижившимся выглядит
любое слово, встреченное трижды, — и ровно так рассудили пять агентов подряд,
каждый независимо. Оговорка заменена закрытым списком из девяти терминов с
колонкой «что называет»: интейк, триаж, провенанс, дедуп, чек-лист, дифф,
промпт, сущности OpenSpec, роды проходов ревью. Интейк оставлен потому, что
«заведение» называет создание файла, и слить их значит смешать две операции;
провенанс — потому что «источник» рядом называет саму запись, а не свойство
числа. Слово не из списка и не из таблицы имён вещей — находка, а не стиль.

Список заведён домом язык-словарь в language.md и копией в уставе doc-wording.
Копия обязательна: агент работает в репозитории проекта, где плагина может не
быть, и без списка предъявил бы интейк как англицизм.

Снято пять слов, 29 мест: конфляция → смешение, декорреляция → разведённость,
непоймание → почему не поймали, эвал-сет → проверочный набор, гайд →
руководство. Латинизм или калька при живом русском слове в каждом случае.

Разбор декорреляции показателен: проект уже владел нужным словом — «агенты
разведены по глубине», «разведены по охвату» — и держал рядом латинский синоним
того же понятия. Это не англицизм, а второй дом для слова.

Непоймание снято ещё и потому, что форма журнала дефектов, которую канон кладёт
в проекты, спрашивает «Почему не поймали», а проза рядом называла это «причиной
непоймания». Скелет и проза о скелете говорили разными словами.

Снятое записано вместе с оставленным, в одном списке и с заменой каждого. Иначе
слово возвращается: из текстов оно уходит, но ничто не мешает следующему проходу
завести его заново — оно ведь короткое и точное на вид.

Тема 32 в DECISIONS.md, следствия 124-126. Нумерация правил в уставе doc-wording
сдвинута: словарь встал шестым, жаргон и далее уехали на единицу.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 15:35:06 +03:00

41 KiB
Raw Blame History

name, description
name description
task-batch Проводит несколько задач разом — планирует порядок и пересечения, гонит каждую задачу отдельным сабагентом в своём git worktree через task-pipeline (по умолчанию по одной задаче за раз; параллельно по графу зависимостей — по явной просьбе), интегрирует по одной ветке через rebase + fast-forward (линейная история), проверяет полноту ревью каждой ветки и в конце сверяет стыки, возникшие от слияния. Набор задач приходит извне. Использовать, когда просят сделать несколько задач сразу.

Батч задач

Оркестратор набора задач. Планирует порядок, раскидывает задачи по изолированным worktree, каждую проводит через полный цикл av-dev-pipeline:task-pipeline, затем сводит в основную ветку линейной историей и делает финальную сверку. Тонкая обёртка над пайплайном задачи — не переизобретай её шаги, вызывай как есть.

По умолчанию задачи идут по одной, в порядке зависимостей. Параллельно — по явной просьбе, и тогда параллельность по графу зависимостей: одновременно гонится только то, между чем нет ни зависимости, ни пересечения. Правило и его цена — в шаге 4.

Работай максимально автономно, по тому же принципу, что и одиночный пайплайн: вопрос, который решать не тебе, записывается и не останавливает поток; спрашиваем только про необратимое (деплой, выкладка наружу, удаление или перезапись рабочих данных). Механику — планирование, worktree, rebase, интеграцию, чистку — делаем без спроса.

Предпосылки

  • OpenSpec и скиллы opsx:* — на них стоит цикл внутри каждого сабагента и проход review-specs финальной сверки. Проекта без OpenSpec это касается так же, как одиночного пайплайна (см. его раздел «Предпосылки»).
  • Скиллы зовутся с пространством имён: av-dev-pipeline:task-pipeline, av-dev-pipeline:review-pipeline, av-dev-pm:tasks. Короткое имя может разрешиться в устаревшую проектную копию, и это произойдёт молча — в charter'е сабагента пиши полное имя, он твоего контекста не видит.
  • Проектные копии этих скиллов и агентов при установке плагина удаляются.

Перед стартом прочитай CLAUDE.md проекта: оттуда берутся имя основной ветки (оно подставляется в каждую команду git ниже), команда и семантика гейта, инварианты и что запускать запрещено. Раскладка нумерованных артефактов — docs/database.md и docs/.pm.json (ключ migrations).

Документов канона нет — проект к нему не приведён. Скажи это строкой и предложи av-dev-pm:canon до первой задачи: иначе каждая задача батча заплатит поразрядной деградацией ревью, а имя основной ветки придётся угадывать.

Границы

  • Набор задач приходит извне. Батч его не формирует: не выбирает из беклога, не приоритизирует, не решает, что важнее. Набор не задан — попроси его у вызывающего и остановись.
  • Батч не владеет спринтом и целями. Он сообщает исход по каждой задаче в тех же трёх словах, что и task-pipeline: сделана / не доведена / оказалась крупнее задачи.
  • Задачи закрывает пайплайн внутри каждого сабагента, шагом 11 — после коммита работы и отдельным коммитом учёта, вызовом Skill av-dev-pm:tasks. Батч сам записей учёта не трогает: он не знает, чем кончилась приёмка, и дублировать закрытие ему незачем. Но грязное дерево после сабагента — его проблема: на нём откажут и rebase, и worktree remove (см. шаг 6). Урожай ревью батч отдаёт списком, а задачи из него заводит тот, кто ведёт задачи проекта.

Ключевое отличие от одиночного пайплайна

task-pipeline коммитит в текущую ветку, и при ручном запуске это основная ветка. Здесь так нельзя, поэтому батч — осознанное исключение: временные ветки и worktree заводятся лишь как средство изоляции, а конечное состояние — та же линейная история основной ветки через rebase + fast-forward. Ветки после вливания удаляются.

Изоляция нужна в обоих режимах, а не только в параллельном: батч не вливает ветку, пока не проверил полноту её ревью (шаг 5), и упавшая задача обязана остаться в своём worktree для ручного дожатия (шаг 6), не оставив следа в основной ветке. В параллельном режиме к этому добавляется вторая причина — задачи не должны видеть недоделанную работу друг друга.

Модель исполнения

  • Каждая задача = один автономный сабагент (general-purpose, чтобы иметь доступ к Skill и Agent для вложенных чекпоинтов ревью), работающий только в своём worktree и прогоняющий task-pipeline целиком на этой задаче.
  • Оркестратор кода задач не пишет: он планирует, заводит worktree, запускает сабагентов, проверяет полноту их ревью, интегрирует ветки и делает финальную сверку.
  • Стиль правок внутри — заточка под проект и конвенции, right-size, без золочения.

Шаги

1. Прочитать набор

Набор задан списком (слаги, файлы, описания) — прочитай файл каждой задачи и связанные спеки и черновики. Сырьё (в терминах av-dev-pm — запись типа research с пустым разделом «Вопрос») включается, но помни: сабагент проведёт его сперва через opsx:explore, это тяжелее и чаще упирается в вопрос.

2. Спланировать порядок и пересечения (автономно)

Для каждой задачи определи:

  • затронутые capability — по её описанию и по каталогу актуальных спек (openspec/specs/);

  • жёсткие зависимости: задача B строится на результате A → A строго раньше B;

  • замеряющая задача — та, чьё ревью будет доказывать находки числами. В последовательном прогоне это ничего не меняет: она и так идёт одна. В параллельном она гонится в волне одна (обоснование — ниже, в шаге 4). Помечается здесь, на планировании, а не во время прогона, и независимо от режима: состав волны определяется сейчас, режим может смениться просьбой уже после плана, а профиль ревью сабагент выберет только внутри задачи — ключевать волну на ещё не сделанный выбор нельзя. Триггеры — по фактам о задаче, каждый сам по себе достаточен:

    • трогает схему хранилища, миграцию, формат на диске или объём хранимого;
    • трогает конкурентность: транзакции, блокировки, фоновые циклы, общее состояние;
    • трогает размер тела, буфер, память, сжатие, ретеншен, темп потока;
    • её тема названа в docs/research/ или в журнале docs/review.md как место, где уже мерили или уже ломалось.

    Ни один триггер не сработал — задача не замеряющая, даже если её ревью окажется deep. Профиль про глубину проверки, замеряющая — про соревнование за железо; это разные вопросы, и совпадают они не всегда;

  • нумерованные артефакты — номера раздаёт оркестратор заранее. Если проект нумерует миграции (путь — docs/.pm.json, ключ migrations), посмотри последний номер и раздай номера всем задачам, которые, вероятно, их добавят, до запуска. Номер уходит в charter сабагента, и он берёт назначенный, а не «следующий свободный».

    Это отдельная механика от правила волны, и она ему не служит — их раньше путали, и они тянули в разные стороны. Правило волны отвечает на вопрос «кто с кем гонится одновременно», предраздача — на вопрос «какой номер берёт задача». Раздача нужна там, где две задачи одной под-пачки добавляют нумерованный артефакт: каждая считает «следующий свободный» по основной ветке, которая ещё не видела соседку, и обе берут один номер. Миграции под это почти не попадают — миграция и так триггер замеряющей задачи, а замеряющая идёт одна; но нумерованные артефакты бывают не только миграциями. Поэтому номера раздаются всем задачам с таким артефактом, независимо от того, в какой волне они окажутся: раздача ничего не стоит, а её отсутствие ловится только конфликтом на интеграции. Между волнами проблемы нет — ветка следующей волны берётся от вершины, уже включающей предыдущие; в последовательном прогоне проблемы нет по той же причине, но номера всё равно раздай: режим может смениться просьбой, а раздача бесплатна;

  • жёстко сериализуем (не гоняем одновременно) настоящие пересечения:

    • одна capability на несколько задач — две задачи, правящие одну спеку (тем более одно и то же ### Requirement), дают не текстовый, а семантический конфликт при архивации; сериализуем по смыслу, а не только по файлам;
    • пересечение по одним и тем же исходникам;
  • мягкие конфликты сериализовать не надо: файлы-перечни, где каждая задача правит свою строку (индексы, оглавления, списки записей), и спеки разных capability — разные строки и файлы, сливаются сами.

Собери план как граф зависимостей, а не как плоский список: рёбра — жёсткие зависимости и сериализуемые пересечения. Дальше по режиму:

  • последовательно (умолчание) — линеаризуй граф в один порядок: топологический, а там, где он оставляет свободу, — раньше то, от чего зависит больше задач, и раньше то, что правит общие для набора места. Волн нет, замеряющие задачи ничем не отличаются от прочих;
  • параллельно (по просьбе) — нарежь граф на волны: в одну волну попадают только задачи, между которыми нет ребра; замеряющие стоят отдельными волнами по одной.

Рёбра у графа двух видов, и путать их не надо: зависимость направлена (B без результата A не делается), пересечение — нет (кто первый, неважно, лишь бы не разом). Тот же словарь у графа проходов ревью — см. «Порядок прогона» в av-dev-pipeline:review-pipeline.

flowchart TD
    A["A: схема хранилища<br/>(замеряющая)"]
    B["B: эндпоинт поверх A"]
    C["C: формат лога"]
    D["D: правит ту же capability, что C"]

    A -->|зависимость| B
    C -. пересечение — одна capability .- D

Этот граф даёт: последовательноA → B → C → D (или A → C → B → D, обе линеаризации законны); параллельно — волна 1 A одна (замеряющая), волна 2 B и C, волна 3 D.

Схемы в этом скилле — пример и сводка, правила ставит текст: при расхождении прав он. (В av-dev-pipeline:review-pipeline наоборот — там граф прогона и есть алгоритм, и старший он.)

Покажи план короткой репликой — режим, порядок или состав волн, какие задачи признаны замеряющими и по какому триггеру, — и иди дальше.

3. Свежая база

Убедись, что рабочее дерево чистое и основная ветка свежая. Зафиксируй базовый коммит. Новые ветки бери от свежей вершины; ветку следующей задачи (в параллельном режиме — ветки следующей волны) — от вершины, уже включающей результат предыдущих.

4. Провести задачи

Умолчание — по одной задаче за раз, в порядке из шага 2. Следующая стартует, когда предыдущая вернула отчёт и (если она зелёная) влилась. Обосновывать это не надо — обосновывается отступление. Причина умолчания в том, что задача батча дороже прохода ревью: каждая тянет полный цикл пайплайна с гейтом, поднятием сервиса и вложенным ревью, и две такие на одной машине дерутся за порты, рабочие каталоги, СУБД и само железо. Последовательный прогон к тому же оставляет ревью внутри задачи его собственное умолчание — параллельные проходы: машина свободна, и выигрыш берётся там, где он ничего не стоит.

Параллельно — по явной просьбе, и параллельность идёт по графу зависимостей. Одновременно гонится только то, между чем на шаге 2 не нашлось ребра: ни жёсткой зависимости, ни общей capability, ни общих исходников. «Гони параллельно» не означает «гони всё разом» — граф остаётся в силе, просьба лишь разрешает использовать его ширину.

В параллельном режиме действуют два ограничения:

  • потолок — 2–3 задачи одновременно. Больше трёх разом душат машину и провоцируют гонки. Волну шире трёх бей на под-пачки по ≤3 и гони под-пачки последовательно: следующая стартует, когда предыдущая вернула отчёты. Иначе потолок обходится тривиально — шесть задач, запущенных «двумя под-пачками» в одном сообщении, это шесть задач разом;
  • волна из одной задачи обязательна для замеряющей. Задача, признанная на шаге 2 замеряющей, гонится одна: соседний прогон на той же машине портит числа, а находка с испорченным оракулом хуже отсутствующей — она выглядит доказанной. Если замеряющая задача всё же пошла в общей волне, её отчёт обязан нести строку в границах покрытия: замеры сняты под соседней нагрузкой.

Для каждой задачи (в параллельном режиме — для каждой задачи под-пачки):

  1. Заведи worktree и ветку от текущей вершины: git worktree add <path> -b task/<slug> <основная ветка>. Путь — во временном каталоге проекта (./tmp), не в системном /tmp.
  2. Запусти сабагента, subagent_type: general-purpose: в последовательном режиме — одного и дождись отчёта; в параллельном — по одному на задачу под-пачки, всех в одном сообщении. Charter сабагента:
    • работай строго в своём worktree <path>; в другие каталоги и в основную ветку не лезь;
    • прогони Skill av-dev-pipeline:task-pipeline ровно на этой задаче, полный цикл SDD с обоими чекпоинтами ревью;
    • если задаче назначен номер артефакта — используй строго его;
    • профиль ревью выбирается по факту изменения. Батч не повод понижать профиль: «нас много и мы спешим» — это ровно тот стимул, из-за которого проходы пропускают;
    • режим прогона проходов ревью — от режима батча, и его называет charter, а не сабагент: батч идёт по одной задаче → режим умолчательный, по графу (машина свободна); батч идёт волнами → линейно, твой worktree не один на машине, и этой причиной ты обязан объяснить режим в отчёте. Внутренние рёбра графа — цепочку проходов, держащих машину, и барьер стоимости — конвейер соблюдает сам, в любом режиме;
    • если вложенные сабагенты недоступны (движок не даёт запускать агентов из агента) — не пропускай ревью и не понижай профиль: проведи его инлайн по тем же charter'ам av-dev-pipeline, сохранив обязательное — гейт до опиниативных проходов, состав по профилю, триаж последним. И скажи в отчёте прямым текстом, что ревью шло инлайн: инлайновый проход видит контекст автора и потому разведён с ним слабее — это меняет доверие к результату, а не только способ запуска;
    • вернуть отчёт, в котором обязательно: исход задачи одним из трёх слов; объявленный профиль ревью и режим прогона; что сделано; какие вопросы записаны и куда; изменённые файлы; добавлялся ли нумерованный артефакт и с каким номером; затронутые capability; состояние гейта; перечень запущенных проходов ревью поимённо с исходом каждого; путь к сохранённому отчёту триажа (openspec/changes/<id>/review/, после архивации — openspec/changes/archive/<id>/review/); шло ли ревью инлайн; границы покрытия.

Шаги 5 и 6 отрабатываются на вернувшейся задаче до старта следующей — в параллельном режиме на вернувшейся волне до старта следующей. Иначе ветка следующей возьмётся от вершины, не видевшей предыдущую работу, и весь смысл порядка из шага 2 теряется.

Сабагент, упершийся в вопрос, не останавливает батч: он записывает вопрос, режет задачу до остатка и доводит остаток — либо, если остатка нет, возвращает исход «не доведена». Оркестратор собирает такие вопросы и выносит их в финальный доклад пачкой.

5. Проверить полноту ревью — до интеграции

Ветка, чей отчёт не называет профиль и проходы поимённо, не вливается. Пропуск прохода не отличим от прохода без находок, и на уровне батча это ещё опаснее: отчётов много, каждый выглядит полным, а сверять их некому, кроме тебя.

Сверка идёт в три шага, и порядок важен:

  1. Возьми объявленный профиль из отчёта задачи — он затем и заказан в обязательных полях шага 4. Профиля в отчёте нет — перечень проходов сверять не с чем; это само по себе основание не вливать, пока сабагент не назовёт профиль и не обоснует его по факту изменения.
  2. Сверяй с независимым артефактом, а не с прозой отчёта. Перечень проходов бери из сохранённого отчёта триажа (openspec/changes/<id>/review/ или openspec/changes/archive/<id>/review/ — задача доведена, change заархивирован) — пайплайн обязан его туда положить. Проза сабагента написана тем же, кто мог проход и пропустить: она подтверждает сама себя. Отчёта триажа на месте нет — считай, что состав неизвестен, и дозапускай ревью целиком.
  3. Сверь состав с таблицей профилей скилла av-dev-pipeline:review-pipeline для объявленного профиля.

Расхождение — не повод отменять задачу: дозапусти недостающие проходы на ветке, в её worktree, через av-dev-pipeline:review-pipeline, и только потом интегрируй.

Находки дозапуска — такие же находки, и зелёный гейт их не отменяет. Правило интеграции «вливаем только зелёные» смотрит на гейт, а дозапущенный critical гейт не красит: он был бы пропущен молча, если это не сказать прямо. Поэтому:

  • critical или major из дозапуска — вливание этой ветки останавливается. Помеченное инлайн чинится в её worktree, после починки — гейт, затем интеграция. Помеченное развилка — вопрос в запись, задача режется до остатка ровно так же, как это сделал бы пайплайн внутри;
  • остатка нет — ветка не вливается и уходит в доклад как провалившаяся, со своим worktree;
  • minor и nit из дозапуска — в урожай доклада, вливанию не мешают.

Отчёт дозапуска приложи к отчёту задачи и назови в докладе (шаг 9), почему он понадобился: систематический пропуск одного и того же прохода — находка о самом конвейере, а не о задаче.

6. Интегрировать — rebase + fast-forward, по одной ветке

Сводим ветки строго последовательно (линейная история), в порядке зависимостей. Вливаем только зелёные.

Ветка задачи занята её worktree, и это определяет форму команд. Пока worktree жив (а удаляется он последним, после зелёного гейта), ветка task/<slug> checkout'нута в нём, и git rebase <основная> task/<slug> из главного worktree падает: fatal: 'task/<slug>' is already used by worktree at …. Поэтому rebase делается внутри worktree задачи, а ff-слияние — из главного.

Для каждой готовой ветки task/<slug>:

  • git -C <path> rebase <основная> — перенос ветки задачи на текущую вершину, выполняется в её собственном worktree;
  • резолв конфликтов (их почти нет — конфликтоопасное сериализовано, номера розданы заранее). Неавтоматический конфликт — не форсируй: прерви (git -C <path> rebase --abort), оставь ветку и worktree как есть, вынеси это в доклад как нераспознанное пересечение;
  • дерево сабагента обязано быть чистым. git -C <path> status --porcelain до rebase: непусто — значит сабагент не довёл шаг 11 до коммита учёта (или оставил мусор). Не форсируй и не коммить за него: назови задачу в докладе недоведённой и оставь ветку с worktree. Молчаливый rebase на грязном дереве всё равно откажет, но с сообщением про unstaged changes — а причина другая;
  • ненулевой код rebase относится к этой ветке и только к ней. Прерванный rebase в чужом worktree не трогает ни главное дерево, ни остальные ветки: проверь git -C <path> status и git status — обе чистые. Уводить весь батч в провалившиеся из-за одного ненулевого кода запрещено: это ложная причина, из-за которой зелёные задачи не доедут до основной ветки. Провалилась одна — провалилась одна;
  • из главного worktree (он стоит на основной ветке — проверь git rev-parse --abbrev-ref HEAD): git merge --ff-only task/<slug>. Ветку в главном дереве не переключайgit checkout task/<slug> тоже упрётся в занятость;
  • после каждой интеграции — гейт на основной ветке. Красное — откати эту интеграцию (git reset --hard на прошлую вершину), ветку с worktree сохрани, задачу перечисли в докладе. Основная ветка никогда не остаётся полузелёной;
  • только после зелёного: git worktree remove <path> и git branch -d task/<slug> — в этом порядке, иначе ветка снова занята.

Политика частичного провала. Упавшая задача (исход «не доведена», красные тесты в её worktree, конфликт при rebase, невлитая из-за находок дозапуска) не блокирует остальные: интегрируем все зелёные, упавшую оставляем в её worktree и ветке нетронутой — ничего не удаляем, — и перечисляем в докладе с причиной, отчётом и путём к worktree. Причина называется настоящая: «конфликт rebase в файле X», а не «нераспознанное пересечение» на всякий случай.

7. Финальный гейт

На основной ветке после всех интеграций — гейт целиком. Зелёное обязательно; пока красное, шаг 8 не начинается.

8. Финальная сверка — только то, чего не видел никто

Каждая задача уже прошла полный конвейер в своём worktree. Повторять его на интегрированном диффе бессмысленно: те же проходы на тех же файлах дадут те же находки и удорожат триаж. Здесь проверяется только то, что появилось от слияния:

  • запусти по одному review-specs на каждую затронутую capability, все разом — граф здесь плоский: машину эти проходы не держат, ребра между ними нет, а сама машина к этому моменту свободна (все сабагенты вернулись). Линейно — только по причине из раздела «Порядок прогона» av-dev-pipeline:review-pipeline, и причину назови;
  • задание у этих проходов особое, и это надо сказать прямо. Живого change здесь нет — все заархивированы, дельта-спек не существует. Источник требований — актуальные openspec/specs/<capability>/spec.md, а предмет — стык: требование, которое одна задача выполнила, а соседняя незаметно отменила; два архивных change, по-разному описавшие одно поведение. Скажи проходу это прямо, иначе он пойдёт искать дельты и не найдёт ничего;
  • если задачи пересекались по файлам, добавь один review-architecture на интегрированный дифф с вопросом «не появился ли второй способ делать то, что уже делается» — именно он возникает, когда две задачи независимо решали похожее;
  • заверши триажем. Он единственный, кто агрегирует, и без него у находок нет ни оракула, ни пометки инлайн/развилка — а следующий абзац на неё опирается. Прогон из двух проходов без триажа — это сырые находки, выданные за разобранные.

Граф этой сверки — веер в один сток, и он такой же, как у обычного прогона:

flowchart TD
    merged["основная ветка после всех интеграций<br/>(финальный гейт зелёный)"]
    s1["review-specs: capability 1<br/>режим «стык после слияния»"]
    s2["review-specs: capability 2<br/>режим «стык после слияния»"]
    arch["review-architecture на интегрированном диффе<br/>(если задачи пересекались по файлам)"]
    tri["review-triage — сток"]

    merged --> s1 --> tri
    merged --> s2 --> tri
    merged --> arch --> tri

Замечания отрабатывай как одиночный пайплайн: инлайн чини сам, развилка — вопросом в запись; после правок — снова гейт.

9. Прибраться и доложить

  • Убери worktree и ветки только успешно влитых задач, в конце git worktree prune. Worktree и ветки провалившихся не трогай — они нужны для ручного дожатия.
  • Записей учёта батч не трогает — их правит пайплайн внутри сабагента на шаге 11. Батч сообщает исход по каждой задаче; если какой-то сабагент дошёл до коммита, но закрытия не сделал (плагина нет, вызов не разрешился), скажи это строкой — иначе задача останется открытой молча.
  • Доложи кратко:
    • исход по каждой задаче одним из трёх слов, с хешем коммита;
    • режим прогона — по одной или волнами, и если волнами, то по чьей просьбе; порядок задач или состав волн, порядок интеграции, с пометкой, какие задачи шли по одной как замеряющие;
    • вопросы, записанные сабагентами, пачкой;
    • что дозапускалось на шаге 5 и почему; шло ли где-то ревью инлайн;
    • итог финальной сверки и ссылки на архивные change;
    • Урожай — отложенные находки всех задач одним списком, с провенансом. Задачи из него заводит тот, кто ведёт задачи проекта, а не батч;
    • отдельно — провалившиеся задачи с настоящей причиной и путём к оставленному worktree;
    • границы покрытия сводной строкой, включая задачи, чьи замеры снимались в общей волне, и ветки, где ревью шло инлайн.

Тонкости

  • Изоляция параллельных тестов — цена параллельного режима, и проверяется она до первой волны. Прежде чем гнать несколько прогонов разом, убедись, что тесты не делят фиксированный порт или файл БД (обычно берут временный каталог и эфемерный порт — тогда ок). Делят — такие задачи гони по одной, даже если просили параллельно, и скажи об этом строкой: просьба про параллельность, а не про сломанные тесты. В умолчательном режиме вопрос не встаёт вовсе — это одна из причин, по которым умолчание такое.
  • Поведенческая верификация внутри сабагента поднимает изменение вживую: в параллельном режиме следи, чтобы соседние worktree не дрались за порты и рабочие каталоги. Если проект умеет поднимать только один экземпляр — такие задачи в одну волну не ставь.
  • Ревью выполненного — до интеграции; это забота av-dev-pipeline:task-pipeline внутри каждого сабагента, дублировать не надо.
  • openspec validate --strict тоже внутри пайплайна задачи — не пропускай его своими правками на интеграции.
  • Крупная переработка, предложенная ревью внутри задачи, — развилка: не вливай молча, вынеси в доклад.
  • Держи вызывающего в цикле короткими репликами на переходах фаз (план → прогон задач → интеграция → финальная сверка), но не проси подтверждать механику.