ревью двумя проходами: 20 находок, все починены
Два независимых сабагента на av-dev-pm и av-dev-pipeline. Две находки нашли оба. Главная — моя же перестановка закрытия за коммит сломала reopen и батч. close печатал «дорога назад из git», а reopen искал коммит удаления, которого в новом порядке ещё нет: шаг 11 последний, учёт остаётся незакоммиченным. Проверено прогоном — отказ кодом 2 на свежезакрытой задаче. Тем же грязным деревом ломались rebase и worktree remove в батче: каждая закрывшая задачу ветка уехала бы в провалившиеся. Починено с обеих сторон: reopen берёт текст из HEAD, если коммита удаления нет, а шаг 11 коммитит учёт вторым коммитом. Вторая — канонический пример docs/.pm.json убивал tasks.py. Четыре документа показывали ключ tasks.sections, которого скрипт не знает: неизвестный ключ это код 3 на любой команде. Проект, заведённый по канону дословно, остался бы без работы с задачами, а docs.py при этом печатал «канон соблюдён». Секции живут в заголовках индекса и второго дома не получают. Остальные восемнадцать: init писал конфиг в упразднённый .tasks.json; looks_like_tasks не видел переименованный индекс; урожай спринта терял автотег после sprint close; ответ на вопрос по инструкции оставлял задачу незабираемой; adopt требовал недостижимого зелёного; путь отчёта триажа не переживал archive; review-specs не имел режима для стыка после слияния; три остатка «шаг 9а» несли предкоммитную позицию закрытия; sprint.md отрицал сам себя в пункте «Сделана». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,9 +46,11 @@ description: Проводит несколько задач разом — пл
|
||||
- **Батч не владеет спринтом и целями.** Он сообщает исход по каждой задаче в тех
|
||||
же трёх словах, что и `task-pipeline`: сделана / не доведена / оказалась крупнее
|
||||
задачи.
|
||||
- **Задачи закрывает пайплайн внутри каждого сабагента**, шагом 9а, вызовом
|
||||
Skill `av-dev-pm:tasks`. Батч сам записей учёта не трогает: он не знает, чем
|
||||
кончилась приёмка, и дублировать закрытие ему незачем. Урожай ревью батч
|
||||
- **Задачи закрывает пайплайн внутри каждого сабагента**, шагом 11 — после
|
||||
коммита работы и **отдельным коммитом учёта**, вызовом Skill `av-dev-pm:tasks`.
|
||||
Батч сам записей учёта не трогает: он не знает, чем кончилась приёмка, и
|
||||
дублировать закрытие ему незачем. Но грязное дерево после сабагента — **его**
|
||||
проблема: на нём откажут и `rebase`, и `worktree remove` (см. шаг 6). Урожай ревью батч
|
||||
отдаёт списком, а задачи из него заводит тот, кто ведёт задачи проекта.
|
||||
|
||||
## Ключевое отличие от одиночного пайплайна
|
||||
@@ -183,7 +185,8 @@ fast-forward. Ветки после вливания удаляются.
|
||||
записаны и куда; изменённые файлы; добавлялся ли нумерованный артефакт и с
|
||||
каким номером; затронутые capability; состояние гейта; **перечень
|
||||
запущенных проходов ревью поимённо с исходом каждого**; **путь к
|
||||
сохранённому отчёту триажа** (`openspec/changes/<id>/review/`); шло ли ревью
|
||||
сохранённому отчёту триажа** (`openspec/changes/<id>/review/`, после
|
||||
архивации — `openspec/changes/archive/<id>/review/`); шло ли ревью
|
||||
инлайн; границы покрытия.
|
||||
|
||||
Сабагент, упершийся в вопрос, **не останавливает батч**: он записывает вопрос,
|
||||
@@ -204,7 +207,8 @@ fast-forward. Ветки после вливания удаляются.
|
||||
не с чем; это само по себе основание не вливать, пока сабагент не назовёт
|
||||
профиль и не обоснует его по факту изменения.
|
||||
2. **Сверяй с независимым артефактом, а не с прозой отчёта.** Перечень проходов
|
||||
бери из **сохранённого отчёта триажа** (`openspec/changes/<id>/review/`) —
|
||||
бери из **сохранённого отчёта триажа** (`openspec/changes/<id>/review/` или
|
||||
`openspec/changes/archive/<id>/review/` — задача доведена, change заархивирован) —
|
||||
пайплайн обязан его туда положить. Проза сабагента написана тем же, кто мог
|
||||
проход и пропустить: она подтверждает сама себя. Отчёта триажа на месте нет —
|
||||
считай, что состав неизвестен, и дозапускай ревью целиком.
|
||||
@@ -250,6 +254,11 @@ rebase делается **внутри worktree задачи**, а ff-слиян
|
||||
розданы заранее). Неавтоматический конфликт — **не форсируй**: прерви
|
||||
(`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` — обе чистые. Уводить весь батч
|
||||
@@ -286,17 +295,25 @@ rebase в файле X», а не «нераспознанное пересеч
|
||||
находки и удорожат триаж. Здесь проверяется **только то, что появилось от
|
||||
слияния**:
|
||||
|
||||
- запусти **по одному `review-specs` на каждую затронутую capability**. Набор
|
||||
назван поимённо и замеров эти проходы не делают, поэтому их допустимо гнать
|
||||
одним сообщением — это то самое отступление от последовательного режима,
|
||||
которое правило разрешает. Задание сузь до стыков: не сверять capability
|
||||
целиком заново, а искать **рассинхрон код↔спека, возникший от слияния** —
|
||||
- запусти **по одному `review-specs` на каждую затронутую capability**,
|
||||
последовательно. Параллельно — только если человек попросил явно и назвал
|
||||
набор: правило и оба его условия живут в
|
||||
`av-dev-pipeline:review-pipeline`, раздел «Режим запуска», и здесь не
|
||||
ослабляются. «Замеров не делают» основанием не является;
|
||||
- **режим у этих проходов особый, и его надо назвать в задании.** Живого change
|
||||
здесь нет — все заархивированы, дельта-спек не существует. Источник требований
|
||||
— **актуальные** `openspec/specs/<capability>/spec.md`, а предмет — стык:
|
||||
требование, которое одна задача выполнила, а соседняя незаметно отменила; два
|
||||
change, по-разному описавшие одно поведение;
|
||||
архивных change, по-разному описавшие одно поведение. Скажи проходу это прямо,
|
||||
иначе он пойдёт искать дельты и не найдёт ничего;
|
||||
- если задачи пересекались по файлам, добавь один `review-architecture` на
|
||||
интегрированный дифф с вопросом «не появился ли второй способ делать то, что
|
||||
уже делается» — именно он возникает, когда две задачи независимо решали
|
||||
похожее.
|
||||
похожее;
|
||||
- **заверши триажем.** Он единственный, кто агрегирует, и без него у находок нет
|
||||
ни оракула, ни пометки `инлайн`/`развилка` — а следующий абзац на неё
|
||||
опирается. Прогон из двух проходов без триажа — это сырые находки, выданные за
|
||||
разобранные.
|
||||
|
||||
Замечания отрабатывай как одиночный пайплайн: `инлайн` чини сам, `развилка` —
|
||||
вопросом в запись; после правок — снова гейт.
|
||||
@@ -307,7 +324,7 @@ rebase в файле X», а не «нераспознанное пересеч
|
||||
`git worktree prune`. Worktree и ветки **провалившихся** не трогай — они нужны
|
||||
для ручного дожатия.
|
||||
- **Записей учёта батч не трогает** — их правит пайплайн внутри сабагента на
|
||||
шаге 9а. Батч сообщает исход по каждой задаче; если какой-то сабагент дошёл до
|
||||
шаге 11. Батч сообщает исход по каждой задаче; если какой-то сабагент дошёл до
|
||||
коммита, но закрытия не сделал (плагина нет, вызов не разрешился), скажи это
|
||||
строкой — иначе задача останется открытой молча.
|
||||
- Доложи кратко:
|
||||
|
||||
Reference in New Issue
Block a user