режимы прогона: ревью параллельно, батч — по одной задаче
Умолчания разошлись по цене шага. Проход ревью читает и рассуждает: он ничего не поднимает, ни за что не дерётся и по построению не видит выводов соседа — очередь между проходами добавляет только ожидание. Задача батча тянет полный цикл пайплайна с гейтом, поднятием сервиса и вложенным ревью — две такие дерутся за порты, каталоги и железо. 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:
@@ -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. **Цена параллельного батча проверяется до первой волны.** Тесты, делящие
|
||||
фиксированный порт или файл БД, и проект, умеющий поднимать один экземпляр, —
|
||||
основание гнать по одной даже после просьбы, сказанное строкой: просьба была
|
||||
про параллельность, а не про сломанные тесты.
|
||||
|
||||
@@ -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 @@
|
||||
- **готовые оракулы** — выборка по пометке `пойман ревью`: находка того же
|
||||
класса подтверждается ссылкой на запись, а не рассуждением;
|
||||
- **основание для правил конвейера** — требование называть запущенные проходы
|
||||
поимённо, отказ от чисел, производных от размера корпуса, и правило
|
||||
последовательного прогона выведены из конкретных записей, а не из общих
|
||||
соображений;
|
||||
поимённо, отказ от чисел, производных от размера корпуса, и правило очереди для
|
||||
меряющих проходов выведены из конкретных записей, а не из общих соображений;
|
||||
- **счётчик обратимости решений** — сузили состав проходов и через месяц поймали
|
||||
дефект ровно того класса, который перестали проверять: решение пересматривается
|
||||
фактом, а не спором.
|
||||
|
||||
@@ -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` конвейер держит по очереди сам, без
|
||||
твоего участия: оба доказывают находки числами, а два меряющих прохода на одной
|
||||
машине портят числа друг другу — находка с испорченным оракулом хуже
|
||||
отсутствующей, потому что выглядит доказанной.
|
||||
|
||||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||||
|
||||
Reference in New Issue
Block a user