режимы прогона: ревью параллельно, батч — по одной задаче

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

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

task-batch: план собирается графом зависимостей и в умолчании
линеаризуется. Параллельно — по просьбе, и просьба разрешает ширину
графа, а не «всё разом»; потолок 2–3 и одиночная волна замеряющей задачи
сохранены как правила этого режима. Режим ревью внутри задачи выводится
из режима батча и называется в charter'е. Финальная сверка гонит
review-specs по capability параллельно.

DECISIONS 14 — с причиной; версия канона не меняется, канон этих скиллов
не описывает.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-03 20:04:54 +03:00
co-authored by Claude Opus 5
parent 67cfa45162
commit d5cffb2e08
5 changed files with 216 additions and 106 deletions
+53
View File
@@ -941,3 +941,56 @@ HTML-комментарии, невидимые в отрендеренном ma
индекса — переименование не трогает механику, только умолчание и тексты.
55. **Метафора — плохое имя для секции индекса.** Секция читается человеком без
контекста, часто из вывода `list`, и второго шанса объяснить себя у неё нет.
## 14. Умолчания режимов прогона перевёрнуты (2026-08-03)
### Что было
Оба скилла держали одно и то же умолчание — «по очереди», — хотя цена очереди у
них разная. `review-pipeline` гнал проходы последовательно и требовал для
параллельности **двух** условий (явная просьба **и** поимённо названный набор).
`task-batch`, наоборот, планировал волны параллельных задач с потолком 2–3 и
считал параллельность нормой прогона.
Перепутаны оказались уровни. Проход ревью — чтение и рассуждение: он ничего не
поднимает, ни за что не дерётся и по построению не видит выводов соседа. Задача
батча — полный цикл пайплайна: гейт, поднятие сервиса вживую, вложенное ревью,
общие порты и рабочие каталоги. Дешёвое стояло в очереди, дорогое гонялось разом.
### Решено
**UU. В ревью умолчание — параллельно.** Стадии по-прежнему идут по порядку,
параллельность касается только проходов внутри стадии. Последовательно гоняем по
трём особым причинам, и каждая называется в отчёте: сказал оператор; проходы
меряют; машина занята — причём занятость видит вызывающий, а не конвейер. Просьба
«гони последовательно» **набора не требует**: очередь ничего не портит, она
только дольше, и домысливать тут нечего — в отличие от прежнего правила, где
неназванный набор блокировал отступление.
**VV. Меряющая пара — правило стадии, а не решение прогона.** `adversary` и `ops`
идут по очереди всегда: оба доказывают находки числами и оба меряют одно железо, а
испорченный оракул хуже отсутствующего. Общее «гони параллельно» этого не
отменяет; отменяет только прямое слово оператора **про эту пару**, и тогда в
границы покрытия идёт строка про замеры под соседней нагрузкой.
**WW. В батче умолчание — по одной задаче, параллельность — по графу
зависимостей.** План собирается как граф (рёбра — жёсткие зависимости и
сериализуемые пересечения) и в умолчании линеаризуется в один порядок. Просьба
«гони параллельно» разрешает использовать **ширину графа**, а не гнать всё разом:
потолок 2–3, замеряющая задача — волной по одной. Прежние правила волн сохранены
целиком, они просто перестали быть умолчанием.
### Что из этого следует
56. **Режим батча задаёт режим ревью внутри задачи, и его называет charter.**
Батч идёт по одной — машина свободна, сабагент гонит проходы параллельно;
батч идёт волнами — сабагенту предписан последовательный режим с этой самой
причиной. Сабагент своего соседа не видит, поэтому решать это ему нельзя.
57. **Ранний выход из ревью переехал на границу стадии.** Стадии идут по порядку
в любом режиме, так что остановиться между ними можно всегда; остановка
**внутри** стадии осталась побочной выгодой последовательного режима — но не
поводом его выбирать.
58. **Цена параллельного батча проверяется до первой волны.** Тесты, делящие
фиксированный порт или файл БД, и проект, умеющий поднимать один экземпляр, —
основание гнать по одной даже после просьбы, сказанное строкой: просьба была
про параллельность, а не про сломанные тесты.
+50 -47
View File
@@ -1,6 +1,6 @@
---
name: review-pipeline
description: Конвейер ревью изменения — детерминированный гейт, сверка с дельта-спеками в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Проходы гонятся последовательно; параллельно — только по явной просьбе и с явно названным набором. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода.
description: Конвейер ревью изменения — детерминированный гейт, сверка с дельта-спеками в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Проходы внутри стадии гонятся параллельно; последовательно — по особой причине (меряющая пара, занятая машина) или по слову оператора. Проектная специфика приходит из документов канона av-dev-pm. Вызывается из task-pipeline (чекпоинты ревью), из task-batch (финальная сверка) и отдельно — профилем design на предложении ДО кода.
---
# Конвейер ревью
@@ -183,44 +183,42 @@ description: Конвейер ревью изменения — детермин
| Режим | Как | Когда |
|---|---|---|
| **последовательно** (умолчание) | по одному, следующий стартует после отчёта предыдущего | всегда, пока не попросили иначе |
| **параллельно** | названные проходы — одним сообщением | только по явной просьбе **и** с явно названным набором |
| **параллельно** (умолчание) | проходы стадии — одним сообщением | всегда, пока не сработала особая причина |
| **последовательно** | по одному, следующий стартует после отчёта предыдущего | по слову оператора **или** по одной из особых причин ниже |
**Умолчание — последовательно, и его не надо обосновывать.** Обосновывается
отступление.
**Умолчание — параллельно, и его не надо обосновывать.** Обосновывается
отступление. Проходы независимы по построению: ни один не видит выводов другого
(см. ниже), у всех общий вход и разные критерии. Очередь между ними не добавляет
ничего, кроме ожидания, — а ожидание на каждом чекпоинте ревью платится каждой
задачей.
**Параллельный режим включается при двух условиях сразу**, и второе так же
обязательно, как первое:
**Последовательно гоним в трёх случаях, и каждый называется в отчёте:**
1. **о нём попросили явно** — «гони параллельно», а не «сделай побыстрее»;
2. **названо, что именно гнать параллельно** — поимённый набор проходов
`specs` и `code` параллельно») или стадия целиком («стадию 1 параллельно»).
1. **сказал оператор** — «гони последовательно». Набор при этом называть не
обязательно: последовательный прогон ничего не портит, он только дольше, и
домысливать тут нечего;
2. **проходы меряют.** `adversary` и `ops` доказывают находки числами: время
удержания блокировки против её таймаута, пик кучи против размера тела, темп
роста файлов журнала, длительность транзакции. Два меряющих прохода на одной
машине соревнуются за диск, CPU и за саму СУБД и выдают числа, которые не
воспроизведутся. Это не гипотеза: правило выведено из находок, целиком
державшихся на таких замерах, — у каждого проекта они свои и лежат в журнале
`docs/review.md`. Число, снятое под конкурентную нагрузку от соседнего
прохода, — это находка с испорченным оракулом, а её опровержение стоит дороже
всего выигрыша от параллельности. **Эта пара идёт по очереди всегда** — это
правило стадии 2, а не решение прогона (см. её раздел);
3. **машина занята, и знает об этом вызывающий.** Рядом идёт другая задача,
поднят сервис, гоняется гейт или дорогая проверка проекта. Сам конвейер
занятости машины не видит — её обязан назвать тот, кто запускает; так и
делает `av-dev-pipeline:task-batch`, когда ведёт задачи параллельно.
Просьба без набора — **не основание**: гоним последовательно и одной строкой
говорим, что набор не был назван. Это не придирка к формулировке. Параллелить
можно ровно то, что не мешает друг другу, а знание об этом лежит у того, кто
просит: он видит, занята ли машина, и ждёт ли он от прогона замеров. Домысливать
набор за него — значит принять решение, которое он оставил себе.
Отдельная причина, не связанная со стоимостью, — **разбор самого конвейера**:
когда выясняется, почему проход чего-то не нашёл, порядок и изоляция важнее
скорости.
Почему умолчание именно такое:
- **Замеры.** Проходы `adversary` и `ops` доказывают находки числами: время
удержания блокировки против её таймаута, пик кучи против размера тела, темп
роста файлов журнала, длительность транзакции. Два меряющих прохода на одной
машине соревнуются за диск, CPU и за саму СУБД и выдают числа, которые не
воспроизведутся. Это не гипотеза: правило выведено из находок, целиком
державшихся на таких замерах, — у каждого проекта они свои и лежат в журнале
`docs/review.md`. Число, снятое под конкурентную нагрузку от соседнего
прохода, — это находка с испорченным оракулом, а её опровержение стоит дороже
всего выигрыша от параллельности.
- **Машина одна.** Рядом идёт задача, поднят сервис, гоняется гейт или дорогая
проверка проекта.
- **Ранний выход** возможен только при последовательном прогоне (см. ниже).
- **Разбор самого конвейера.** Когда выясняется, почему проход чего-то не нашёл,
порядок и изоляция важнее скорости.
Если параллельный режим всё же включён, в границы покрытия идёт строка: какие
проходы шли разом и что замеры, снятые в этом прогоне, как оракул слабее.
Если меряющие проходы всё же пошли разом — а это бывает только по прямому слову
оператора, — в границы покрытия идёт строка: какие проходы шли одновременно и
что замеры этого прогона как оракул слабее.
**Чего режим не меняет — и это не подлежит обсуждению.** Проход **не видит**
находок других проходов ни в каком режиме. «Последовательно» значит «по
@@ -231,15 +229,17 @@ description: Конвейер ревью изменения — детермин
маскируется под независимое подтверждение. Единственный, кто видит всё, — триаж,
и это его работа.
**Ранний выход** (последовательный режим делает его возможным — это его побочная
выгода, а не повод его выбирать). Допустимо остановить прогон, не докатив
остаток, ровно в одном случае: находка требует **переделки формы** изменения, и
**Ранний выход — по границе стадии.** Стадии идут по порядку в любом режиме,
поэтому остановиться между ними можно всегда; последовательный режим добавляет к
этому возможность остановиться **внутри** стадии — это его побочная выгода, а не
повод его выбирать. Допустимо остановить прогон, не докатив остаток, ровно в
одном случае: находка требует **переделки формы** изменения, и
остальные проходы будут смотреть на код, которого через час не станет. Тогда:
- прогон останавливается, находка чинится, конвейер запускается **заново с
нулевой стадии** — а не «доезжает» остатком по старому коду;
- незапущенные проходы идут в границы покрытия строкой «не запускался: прогон
остановлен на <проход> из-за <находка>», поимённо;
остановлен на <проход или стадия> из-за <находка>», поимённо;
- триаж запускается только на полном прогоне. Отчёт триажа по половине проходов
выглядит полным, потому что агрегирует всё, что ему подали, — это тот же
молчащий пропуск, что и в разделе «Профили».
@@ -248,8 +248,9 @@ description: Конвейер ревью изменения — детермин
(`Действие: инлайн`), **не делается**: дешевле дособрать все находки и починить
пачкой, чем гонять конвейер дважды.
Режим объявляется в отчёте наравне с профилем, и если он **параллельный**с
причиной и составом. Последовательный объявляется одним словом.
Режим объявляется в отчёте наравне с профилем. Параллельный — одним словом.
**Последовательный — с причиной** (какой именно из трёх) и с составом, если по
очереди шла только часть проходов.
## Стадия 0 — Gate (обязательна во всех профилях)
@@ -275,8 +276,8 @@ description: Конвейер ревью изменения — детермин
## Стадия 1 — Conformance (обязательна во всех профилях)
Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые.
Замеров они не делают и потому безобиднее прочих, если параллельный режим
попросят с их именами; сами по себе идут по очереди, как и все.
Замеров они не делают и не мешают друг другу ничем — это канонический случай
умолчания: оба уходят одним сообщением.
- `review-specs` — критерий взят из **дельта-спек предлагаемого изменения**, а не
из proposal, сообщения коммита или описания задачи. Сверка двунаправленная;
@@ -296,11 +297,13 @@ Recall обоих равен длине их источника — это и е
- `review-adversary` — находка есть **построенный путь**, а не свойство;
- `review-ops` — постмортем от симптома у владельца сервиса к строке кода.
**Эту пару параллелить не стоит даже по просьбе — переспроси.** Оба доказывают
находки замером, и оба меряют одно и то же железо. Запущенные разом, они портят
числа друг другу, а испорченный оракул хуже отсутствующего: находка выглядит
доказанной. Если их всё же назвали в параллельном наборе — выполняй, но скажи в
границах покрытия, что числа этого прогона сняты под соседней нагрузкой.
**Эта пара — именованное исключение из умолчания: она идёт по очереди всегда.**
Оба доказывают находки замером, и оба меряют одно и то же железо. Запущенные
разом, они портят числа друг другу, а испорченный оракул хуже отсутствующего:
находка выглядит доказанной. Очередь здесь не обосновывается — она правило
стадии, и на общее «гони параллельно» не отменяется. Если оператор прямо велел
гнать разом **и эту пару** — выполняй, но скажи в границах покрытия, что числа
этого прогона сняты под соседней нагрузкой.
**Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в
`standard`, а не только в `deep`.** Измерено на пяти задачах подряд: враждебный
@@ -98,9 +98,8 @@
- **готовые оракулы** — выборка по пометке `пойман ревью`: находка того же
класса подтверждается ссылкой на запись, а не рассуждением;
- **основание для правил конвейера** — требование называть запущенные проходы
поимённо, отказ от чисел, производных от размера корпуса, и правило
последовательного прогона выведены из конкретных записей, а не из общих
соображений;
поимённо, отказ от чисел, производных от размера корпуса, и правило очереди для
меряющих проходов выведены из конкретных записей, а не из общих соображений;
- **счётчик обратимости решений** — сузили состав проходов и через месяц поймали
дефект ровно того класса, который перестали проверять: решение пересматривается
фактом, а не спором.
+105 -50
View File
@@ -1,6 +1,6 @@
---
name: task-batch
description: Проводит несколько задач разом — планирует порядок и пересечения, гонит каждую задачу отдельным сабагентом в своём git worktree через task-pipeline, интегрирует по одной ветке через rebase + fast-forward (линейная история), проверяет полноту ревью каждой ветки и в конце сверяет стыки, возникшие от слияния. Набор задач приходит извне. Использовать, когда просят сделать несколько задач сразу.
description: Проводит несколько задач разом — планирует порядок и пересечения, гонит каждую задачу отдельным сабагентом в своём git worktree через task-pipeline (по умолчанию по одной задаче за раз; параллельно по графу зависимостей — по явной просьбе), интегрирует по одной ветке через rebase + fast-forward (линейная история), проверяет полноту ревью каждой ветки и в конце сверяет стыки, возникшие от слияния. Набор задач приходит извне. Использовать, когда просят сделать несколько задач сразу.
---
# Батч задач
@@ -11,6 +11,11 @@ description: Проводит несколько задач разом — пл
и делает финальную сверку. Тонкая обёртка над пайплайном задачи — не
переизобретай её шаги, вызывай как есть.
**По умолчанию задачи идут по одной**, в порядке зависимостей. Параллельно — по
явной просьбе, и тогда параллельность **по графу зависимостей**: одновременно
гонится только то, между чем нет ни зависимости, ни пересечения. Правило и его
цена — в шаге 4.
Работай **максимально автономно**, по тому же принципу, что и одиночный пайплайн:
вопрос, который решать не тебе, записывается и не останавливает поток; спрашиваем
только про **необратимое** (деплой, выкладка наружу, удаление или перезапись
@@ -34,7 +39,7 @@ description: Проводит несколько задач разом — пл
`docs/database.md` и `docs/.pm.json` (ключ `migrations`).
**Документов канона нет — проект к нему не приведён.** Скажи это строкой и
предложи `av-dev-pm:canon` **до первой волны**: иначе каждая задача батча
предложи `av-dev-pm:canon` **до первой задачи**: иначе каждая задача батча
заплатит поразрядной деградацией ревью, а имя основной ветки придётся
угадывать.
@@ -56,10 +61,16 @@ description: Проводит несколько задач разом — пл
## Ключевое отличие от одиночного пайплайна
`task-pipeline` коммитит **в текущую ветку**, и при ручном запуске это основная
ветка. Здесь так нельзя для параллельных задач, поэтому батч — **осознанное
исключение**: временные ветки и worktree заводятся лишь как средство изоляции, а
конечное состояние — та же линейная история основной ветки через rebase +
fast-forward. Ветки после вливания удаляются.
ветка. Здесь так нельзя, поэтому батч — **осознанное исключение**: временные
ветки и worktree заводятся лишь как средство изоляции, а конечное состояние — та
же линейная история основной ветки через rebase + fast-forward. Ветки после
вливания удаляются.
Изоляция нужна **в обоих режимах, а не только в параллельном**: батч не вливает
ветку, пока не проверил полноту её ревью (шаг 5), и упавшая задача обязана
остаться в своём worktree для ручного дожатия (шаг 6), не оставив следа в
основной ветке. В параллельном режиме к этому добавляется вторая причина —
задачи не должны видеть недоделанную работу друг друга.
## Модель исполнения
@@ -87,10 +98,12 @@ fast-forward. Ветки после вливания удаляются.
- **затронутые capability** — по её описанию и по каталогу актуальных спек
(`openspec/specs/`);
- **жёсткие зависимости**: задача B строится на результате A → A строго раньше B;
- **замеряющая задача** — та, чьё ревью будет доказывать находки **числами**, и
потому она гонится в волне **одна** (обоснование — ниже, в шаге 4). Решается
здесь, на планировании, а не во время прогона: состав волны определяется
сейчас, а профиль ревью сабагент выберет только внутри задачи, и ключевать
- **замеряющая задача** — та, чьё ревью будет доказывать находки **числами**. В
последовательном прогоне это ничего не меняет: она и так идёт одна. В
параллельном она гонится в волне **одна** (обоснование — ниже, в шаге 4).
Помечается здесь, на планировании, а не во время прогона, и **независимо от
режима**: состав волны определяется сейчас, режим может смениться просьбой уже
после плана, а профиль ревью сабагент выберет только внутри задачи — ключевать
волну на ещё не сделанный выбор нельзя. Триггеры — по фактам о задаче, каждый
сам по себе достаточен:
- трогает схему хранилища, миграцию, формат на диске или объём хранимого;
@@ -120,7 +133,9 @@ fast-forward. Ветки после вливания удаляются.
**всем** задачам с таким артефактом, независимо от того, в какой волне они
окажутся: раздача ничего не стоит, а её отсутствие ловится только конфликтом на
интеграции. Между волнами проблемы нет — ветка следующей волны берётся от
вершины, уже включающей предыдущие;
вершины, уже включающей предыдущие; в последовательном прогоне проблемы нет по
той же причине, но номера всё равно раздай: режим может смениться просьбой, а
раздача бесплатна;
- **жёстко сериализуем** (не гоняем одновременно) настоящие пересечения:
- **одна capability на несколько задач** — две задачи, правящие одну спеку (тем
более одно и то же `### Requirement`), дают не текстовый, а **семантический**
@@ -130,39 +145,65 @@ fast-forward. Ветки после вливания удаляются.
правит **свою** строку (индексы, оглавления, списки записей), и спеки разных
capability — разные строки и файлы, сливаются сами.
Собери план: **волны** параллельно-безопасных задач плюс сериализованный хвост
конфликтоопасных, с учётом зависимостей; замеряющие задачи стоят в плане
отдельными волнами по одной. Покажи план короткой репликой — назвав, какие
задачи признаны замеряющими и по какому триггеру, — и иди дальше.
Собери план как **граф зависимостей**, а не как плоский список: рёбра — жёсткие
зависимости и сериализуемые пересечения. Дальше по режиму:
- **последовательно (умолчание)** — линеаризуй граф в один порядок:
топологический, а там, где он оставляет свободу, — раньше то, от чего зависит
больше задач, и раньше то, что правит общие для набора места. Волн нет,
замеряющие задачи ничем не отличаются от прочих;
- **параллельно (по просьбе)** — нарежь граф на **волны**: в одну волну попадают
только задачи, между которыми нет ребра; замеряющие стоят отдельными волнами по
одной.
Покажи план короткой репликой — режим, порядок или состав волн, какие задачи
признаны замеряющими и по какому триггеру, — и иди дальше.
### 3. Свежая база
Убедись, что рабочее дерево чистое и основная ветка свежая. Зафиксируй базовый
коммит. Новые ветки бери от свежей вершины; ветки следующей волны — от вершины,
уже включающей результат предыдущих волн.
коммит. Новые ветки бери от свежей вершины; ветку следующей задачи (в
параллельном режиме — ветки следующей волны) — от вершины, уже включающей
результат предыдущих.
### 4. Прогнать волны
### 4. Провести задачи
**Потолок параллелизма — 2–3 задачи одновременно.** Каждая задача тянет полный
цикл пайплайна с вложенным ревью и гейтом, поэтому больше трёх разом душат
машину и провоцируют гонки. Волну шире трёх бей на под-пачки по ≤3 и **гони
под-пачки последовательно**: следующая стартует, когда предыдущая вернула отчёты.
Иначе потолок обходится тривиально — шесть задач, запущенных «двумя под-пачками»
в одном сообщении, это шесть задач разом.
**Умолчание — по одной задаче за раз, в порядке из шага 2.** Следующая стартует,
когда предыдущая вернула отчёт и (если она зелёная) влилась. Обосновывать это не
надо — обосновывается отступление. Причина умолчания в том, что задача батча
дороже прохода ревью: каждая тянет полный цикл пайплайна с гейтом, поднятием
сервиса и вложенным ревью, и две такие на одной машине дерутся за порты, рабочие
каталоги, СУБД и само железо. Последовательный прогон к тому же оставляет ревью
внутри задачи его собственное умолчание — **параллельные проходы**: машина
свободна, и выигрыш берётся там, где он ничего не стоит.
**Волна из одной задачи — не вырожденный случай, а обязательный.** Задача,
признанная на шаге 2 **замеряющей**, гонится в волне одна: соседний прогон на той
же машине портит числа, а находка с испорченным оракулом хуже отсутствующей — она
выглядит доказанной. Если замеряющая задача всё же пошла в общей волне, её отчёт
обязан нести строку в границах покрытия: замеры сняты под соседней нагрузкой.
**Параллельно — по явной просьбе, и параллельность идёт по графу зависимостей.**
Одновременно гонится только то, между чем на шаге 2 не нашлось ребра: ни жёсткой
зависимости, ни общей capability, ни общих исходников. «Гони параллельно» не
означает «гони всё разом» — граф остаётся в силе, просьба лишь разрешает
использовать его ширину.
Для каждой задачи в под-пачке:
В параллельном режиме действуют два ограничения:
- **потолок — 2–3 задачи одновременно.** Больше трёх разом душат машину и
провоцируют гонки. Волну шире трёх бей на под-пачки по ≤3 и **гони под-пачки
последовательно**: следующая стартует, когда предыдущая вернула отчёты. Иначе
потолок обходится тривиально — шесть задач, запущенных «двумя под-пачками» в
одном сообщении, это шесть задач разом;
- **волна из одной задачи обязательна для замеряющей.** Задача, признанная на
шаге 2 **замеряющей**, гонится одна: соседний прогон на той же машине портит
числа, а находка с испорченным оракулом хуже отсутствующей — она выглядит
доказанной. Если замеряющая задача всё же пошла в общей волне, её отчёт обязан
нести строку в границах покрытия: замеры сняты под соседней нагрузкой.
Для каждой задачи (в параллельном режиме — для каждой задачи под-пачки):
1. Заведи worktree и ветку от текущей вершины:
`git worktree add <path> -b task/<slug> <основная ветка>`. Путь — во временном
каталоге проекта (`./tmp`), не в системном `/tmp`.
2. Запусти **по одному сабагенту на задачу, все в одном сообщении**,
`subagent_type: general-purpose`. Charter сабагента:
2. Запусти сабагента, `subagent_type: general-purpose`: в последовательном режиме
— одного и дождись отчёта; в параллельном — **по одному на задачу под-пачки,
всех в одном сообщении**. Charter сабагента:
- работай **строго в своём worktree** `<path>`; в другие каталоги и в основную
ветку не лезь;
- прогони Skill **`av-dev-pipeline:task-pipeline`** ровно на этой задаче,
@@ -171,8 +212,12 @@ fast-forward. Ветки после вливания удаляются.
- **профиль ревью выбирается по факту изменения.** Батч не повод понижать
профиль: «нас много и мы спешим» — это ровно тот стимул, из-за которого
проходы пропускают;
- **режим прогона проходов — последовательный.** Твой worktree не один на
машине;
- **режим прогона проходов ревью — от режима батча**, и его называет charter,
а не сабагент: батч идёт по одной задаче → режим умолчательный,
**параллельный** (машина свободна); батч идёт волнами → **последовательный**,
твой worktree не один на машине, и этой причиной ты обязан объяснить режим в
отчёте. Меряющую пару `adversary` и `ops` конвейер держит по очереди сам, в
любом режиме;
- **если вложенные сабагенты недоступны** (движок не даёт запускать агентов из
агента) — не пропускай ревью и не понижай профиль: проведи его **инлайн** по
тем же charter'ам `av-dev-pipeline`, сохранив обязательное — гейт до
@@ -189,6 +234,11 @@ fast-forward. Ветки после вливания удаляются.
архивации — `openspec/changes/archive/<id>/review/`); шло ли ревью
инлайн; границы покрытия.
**Шаги 5 и 6 отрабатываются на вернувшейся задаче до старта следующей** — в
параллельном режиме на вернувшейся волне до старта следующей. Иначе ветка
следующей возьмётся от вершины, не видевшей предыдущую работу, и весь смысл
порядка из шага 2 теряется.
Сабагент, упершийся в вопрос, **не останавливает батч**: он записывает вопрос,
режет задачу до остатка и доводит остаток — либо, если остатка нет, возвращает
исход «не доведена». Оркестратор собирает такие вопросы и выносит их в финальный
@@ -296,11 +346,11 @@ rebase в файле X», а не «нераспознанное пересеч
слияния**:
- запусти **по одному `review-specs` на каждую затронутую capability**,
последовательно. Параллельно — только если человек попросил явно и назвал
набор: правило и оба его условия живут в
`av-dev-pipeline:review-pipeline`, раздел «Режим запуска», и здесь не
ослабляются. «Замеров не делают» основанием не является;
- **режим у этих проходов особый, и его надо назвать в задании.** Живого change
параллельно — как велит умолчание конвейера: замеров эти проходы не делают,
друг другу не мешают, а машина к этому моменту свободна (все сабагенты
вернулись). По очереди — только по особой причине из раздела «Режим запуска»
`av-dev-pipeline:review-pipeline`, и причину назови;
- **задание у этих проходов особое, и это надо сказать прямо.** Живого change
здесь нет — все заархивированы, дельта-спек не существует. Источник требований
**актуальные** `openspec/specs/<capability>/spec.md`, а предмет — стык:
требование, которое одна задача выполнила, а соседняя незаметно отменила; два
@@ -329,8 +379,9 @@ rebase в файле X», а не «нераспознанное пересеч
строкой — иначе задача останется открытой молча.
- Доложи кратко:
- **исход по каждой задаче** одним из трёх слов, с хешем коммита;
- план волн и порядок интеграции, с пометкой, какие задачи шли по одной как
замеряющие;
- **режим прогона** — по одной или волнами, и если волнами, то по чьей просьбе;
порядок задач или состав волн, порядок интеграции, с пометкой, какие задачи
шли по одной как замеряющие;
- вопросы, записанные сабагентами, пачкой;
- что дозапускалось на шаге 5 и почему; шло ли где-то ревью инлайн;
- итог финальной сверки и ссылки на архивные change;
@@ -343,18 +394,22 @@ rebase в файле X», а не «нераспознанное пересеч
## Тонкости
- **Изоляция параллельных тестов.** Прежде чем гнать несколько прогонов разом,
убедись, что тесты не делят фиксированный порт или файл БД (обычно берут
временный каталог и эфемерный порт — тогда ок). Делят — гони такие задачи
последовательно.
- Поведенческая верификация внутри сабагента поднимает изменение вживую: следи,
чтобы соседние worktree не дрались за порты и рабочие каталоги. Если проект
умеет поднимать только один экземпляр — такие задачи в одну волну не ставь.
- **Изоляция параллельных тестов — цена параллельного режима, и проверяется она
до первой волны.** Прежде чем гнать несколько прогонов разом, убедись, что
тесты не делят фиксированный порт или файл БД (обычно берут временный каталог и
эфемерный порт — тогда ок). Делят — такие задачи гони по одной, даже если
просили параллельно, и скажи об этом строкой: просьба про параллельность, а не
про сломанные тесты. В умолчательном режиме вопрос не встаёт вовсе — это одна
из причин, по которым умолчание такое.
- Поведенческая верификация внутри сабагента поднимает изменение вживую: в
параллельном режиме следи, чтобы соседние worktree не дрались за порты и
рабочие каталоги. Если проект умеет поднимать только один экземпляр — такие
задачи в одну волну не ставь.
- Ревью выполненного — **до** интеграции; это забота
`av-dev-pipeline:task-pipeline` внутри каждого сабагента, дублировать не надо.
- `openspec validate --strict` тоже внутри пайплайна задачи — не пропускай его
своими правками на интеграции.
- Крупная переработка, предложенная ревью внутри задачи, — развилка: не вливай
молча, вынеси в доклад.
- Держи вызывающего в цикле короткими репликами на переходах фаз (план → волны →
интеграция → финальная сверка), но не проси подтверждать механику.
- Держи вызывающего в цикле короткими репликами на переходах фаз (план → прогон
задач → интеграция → финальная сверка), но не проси подтверждать механику.
@@ -229,12 +229,12 @@ description: Автономно проводит одну задачу чере
последней. Помни ровно одно — **профиль выбирается по факту изменения, а не по
ощущению важности**, и посмотри таблицу перед вызовом.
**Режим по умолчанию последовательный, и обосновывать его не надо.** Параллельно
гоняем только тогда, когда об этом попросили явно **и назвали набор** — какие
именно проходы или какую стадию. Просьба без набора основанием не считается:
гони последовательно и скажи строкой, что набор не был назван. Причина умолчания
— замеры: `adversary` и `ops` доказывают находки числами, а два меряющих прохода
на одной машине портят числа друг другу; находка с испорченным оракулом хуже
**Режим по умолчанию параллельный, и обосновывать его не надо.** По очереди гоняем
только по особой причине, и она называется строкой: об этом попросил оператор;
машина занята чем-то ещё (в том числе соседней задачей батча); идёт разбор самого
конвейера. Меряющую пару `adversary` и `ops` конвейер держит по очереди сам, без
твоего участия: оба доказывают находки числами, а два меряющих прохода на одной
машине портят числа друг другу находка с испорченным оракулом хуже
отсутствующей, потому что выглядит доказанной.
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с