классификация задачи: три категории документов и метка вместо ступени
Канон 5 объявил «каждый документ docs/ — тема ревью». Правило верно ровно наполовину и потому вредно целиком. Паспорт и схему хранилища ревью читает, но темами они не являются: по ним нельзя сказать «в этом изменении сделано не так», они задают границу, по которой судит чужая тема. Журнал решений и журнал наблюдений ревью изменения не нужны вовсе — ADR объясняет прошлое, а не предъявляет требование. Разметчик, применявший правило буквально, обязан был либо завести фантомные темы passport, adr, database, research и продублировать ими работу architecture и operations, либо потерять четыре документа молча; случались обе ветки, и в собственном образце плана docs/passport.md не попадал ни строкой, а обязательная арифметика покрытия при этом не сходилась. Категорий теперь три, разрез проверяемый. Тема — да, прямо: conventions, security, architecture и любой свой документ проекта. Источник темы — нет, но он задаёт границу для чужой: passport, database, CLAUDE.md, openspec/specs. Процессный — нет, он про то, как мы работаем: tasks, review, adr, research, .pm.json. Открыта одна категория из трёх, две другие перечислены поимённо, так что документ вне раскладки — однозначно своя тема. adr и research прогон больше не открывает ни одним проходом; docs/review остаётся читаемым, но как настройка конвейера, а не критерий. Цена записана и стала обязательной строкой границ покрытия: расхождение с записанным решением ловит теперь только сверка документации, а число под находкой обязано быть снято на этом прогоне, с приложенной командой. Классификация выдаёт задаче метку — small, medium, large. Прежние quick, standard и wide назывались ступенью и описывали ревью: как глубоко смотрим. Классифицируется же задача, и пока величина называлась свойством прогона, её естественно было пересчитывать на каждом прогоне — что конвейер и делал. Слово «ступень» удалено, а не оставлено синонимом: два имени одной вещи расходятся. Выводится метка из двух разведённых осей — размер (малое, среднее, крупное) и сложность (знакомое, незнакомое), — и равна максимуму по ним. Метка не синоним размера: малое незнакомое изменение получает large, трогая один узел, поэтому план печатает три строки с обоснованием каждая и выводить одну из другой запрещено. Оси остались русскими словами — это суждение прозой; метка английская — это идентификатор, который проходы сравнивают. Разметка переехала из ревью кода в шаг 4 пайплайна, сразу после propose. Она шла первым проходом каждого ревью кода, а перед ревью дизайна ту же величину называл сам пайплайн — то есть оркестратор, который только что довёл предложение до propose. Одно и то же измерялось дважды, и один из двух раз без разведённости с автором, ровно в той точке, ради которой разметчик заведён. Теперь запуск один на задачу, диффа он не видит, план обслуживает обе стадии, и метка после кода не пересматривается: расхождение факта с разметкой ловит журнал дефектов постфактум, как и всякую другую ошибку выбора. На диск план не пишется — четвёртый артефакт рядом с proposal, tasks и design пережил бы задачу и разошёлся бы с ней молча. Ревью дизайна тоже растёт меткой: small — specs, medium — плюс rubric, large — плюс architecture и вопрос автору о трёх формах решения. Раньше rubric и architecture включались одним условием, и medium получал ровно один проход, то есть не отличался от quick ничем. Разведены они потому, что зарабатывают на разном: рубрика порождает свойства узла и окупается уже на среднем изменении, её выход уезжает приёмочными критериями в tasks.md; архитектура отвечает на вопрос про второй способ, а он на среднем знакомом изменении отвечается «нет» ещё до запуска. small подешевел тремя способами сразу. Составом: приёмник тем не запускается, три темы ядра переходят к code сверкой по записанным инвариантам CLAUDE.md с потолком в одну находку, и это не «глубина ниже», а другой дом темы. Входом: specs читает только дельта-спеку, code — только индекс конвенций. Потолком: он появился у каждого опиниативного прохода, а не у одного basics, и у половин code он раздельный, потому что конвенционных находок больше по построению и в общем списке они вытеснили бы техническую половину. Сработавший потолок обязан быть объявлен строкой — молчащий срез неотличим от «больше не нашлось». Отрицательный тест small от этого стал жёстче, а не мягче: вопросы про обратимость миграции задавал приёмник тем, и на этой метке их не задаст никто. Пайплайн задачи вырос до двенадцати шагов. Тривиальность перестала решать состав ревью — она влияет только на explore; глубину обеих стадий называет метка. Проверено прогоном ревьюверов по готовому результату: девять расхождений найдено и починено — контракт находок печатал старый перечень проходов вместо плана по темам, три ссылки в task-batch указывали на шаг коммита вместо закрытия, запись changelog не переводила вопросы, адресованные passport и database, ops и adversary утверждали, что на нижних метках их вопросы задаёт basics, шаблон покрытия в review-code зашивал потолки small намертво, триггеры метки рассыпались на два списка против трёх, тема из директивы CLAUDE.md могла остаться без запуска исполнителя. Гейт зелёный: фронтматтеры, копии, одиннадцать диаграмм, ruff, pyrefly; docs.py прогнан на живом фикстуре и печатает категорию в отказе. Канон повышен до версии 6 с записью, выполнимой upgrade. Решения — 40–44. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,7 @@ description: Проводит несколько задач разом — пл
|
||||
- **Батч не владеет спринтом и целями.** Он сообщает исход по каждой задаче в тех
|
||||
же трёх словах, что и `task-pipeline`: сделана / не доведена / оказалась крупнее
|
||||
задачи.
|
||||
- **Задачи закрывает пайплайн внутри каждого сабагента**, шагом 11 — после
|
||||
- **Задачи закрывает пайплайн внутри каждого сабагента**, шагом 12 — после
|
||||
коммита работы и **отдельным коммитом учёта**, вызовом Skill `av-dev-pm:tasks`.
|
||||
Батч сам записей учёта не трогает: он не знает, чем кончилась приёмка, и
|
||||
дублировать закрытие ему незачем. Но грязное дерево после сабагента — **его**
|
||||
@@ -104,21 +104,20 @@ description: Проводит несколько задач разом — пл
|
||||
параллельном она гонится в волне **одна** (обоснование — ниже, в шаге 4).
|
||||
Помечается здесь, на планировании, а не во время прогона, и **независимо от
|
||||
режима**: состав волны определяется сейчас, режим может смениться просьбой уже
|
||||
после плана, а ступень ревью выберет разметчик уже внутри прогона — ключевать
|
||||
волну на ещё не сделанный выбор нельзя. Триггеры — по фактам о задаче, каждый
|
||||
после плана, а метка ревью назовёт разметчик уже внутри пайплайна задачи,
|
||||
после `propose`, — ключевать волну на ещё не сделанный выбор нельзя. Триггеры — по фактам о задаче, каждый
|
||||
сам по себе достаточен:
|
||||
- трогает схему хранилища, миграцию, формат на диске или объём хранимого;
|
||||
- трогает конкурентность: транзакции, блокировки, фоновые циклы, общее
|
||||
состояние;
|
||||
- трогает размер тела, буфер, память, сжатие, ретеншен, темп потока;
|
||||
- её тема названа в `docs/research/` или в журнале `docs/review.md` как место,
|
||||
где уже мерили или уже ломалось.
|
||||
- её тема названа в журнале `docs/review.md` как место, где уже ломалось.
|
||||
|
||||
Ни один триггер не сработал — задача не замеряющая, даже если её ревью
|
||||
окажется `wide`. Ступень про глубину проверки, замеряющая — про соревнование за
|
||||
окажется `large`. Метка про глубину проверки, замеряющая — про соревнование за
|
||||
железо; это разные вопросы, и совпадают они не всегда. Обратное тоже бывает и
|
||||
тоже законно: помеченная задача, чьё ревью пошло профилем `quick` или
|
||||
`standard`, машину не займёт вовсе — меряющие проходы живут только в `wide`.
|
||||
тоже законно: помеченная задача, чьё ревью пошло меткой `small` или
|
||||
`medium`, машину не займёт вовсе — меряющие проходы живут только в `large`.
|
||||
Пометка от этого не снимается: она ставится **до** разметки, и перестраховка
|
||||
здесь стоит одной волны, а ошибка — испорченных чисел;
|
||||
- **нумерованные артефакты — номера раздаёт оркестратор заранее.** Если проект
|
||||
@@ -238,8 +237,10 @@ flowchart TD
|
||||
- прогони Skill **`av-dev-pipeline:task-pipeline`** ровно на этой задаче,
|
||||
полный цикл SDD с обоими чекпоинтами ревью;
|
||||
- если задаче назначен **номер артефакта** — используй строго его;
|
||||
- **ступень ревью выбирает разметчик конвейера, а не ты и не сабагент.**
|
||||
Профиль в вызов не передаётся вовсе. Батч не повод её понижать: «нас много и
|
||||
- **метка ревью выбирает разметчик конвейера, а не ты и не сабагент.** Он
|
||||
идёт внутри пайплайна задачи, шагом 4, сразу после `propose`, и его план
|
||||
обслуживает оба чекпоинта. Метка в вызов не передаётся вовсе. Батч не
|
||||
повод её понижать: «нас много и
|
||||
мы спешим» — ровно тот стимул, из-за которого проходы пропускают, и он снят
|
||||
тем, что регулятор не в руках у автора;
|
||||
- **режим прогона проходов ревью — от режима батча**, и его называет charter,
|
||||
@@ -249,15 +250,15 @@ flowchart TD
|
||||
Внутренние рёбра графа — цепочку проходов, держащих машину — конвейер
|
||||
соблюдает сам, в любом режиме;
|
||||
- **если вложенные сабагенты недоступны** (движок не даёт запускать агентов из
|
||||
агента) — не пропускай ревью и не понижай ступень: проведи его **инлайн** по
|
||||
агента) — не пропускай ревью и не понижай метка: проведи его **инлайн** по
|
||||
тем же charter'ам `av-dev-pipeline`, сохранив обязательное — разметку первой
|
||||
(план с темами и ступенью), гейт до опиниативных проходов, состав по плану,
|
||||
(план с темами и меткой), гейт до опиниативных проходов, состав по плану,
|
||||
триаж последним. И **скажи в отчёте прямым текстом, что ревью шло инлайн**:
|
||||
инлайновый проход видит контекст автора и потому разведён с ним слабее — а
|
||||
инлайновая разметка вдобавок означает, что ступень выбрал автор, и это
|
||||
инлайновая разметка вдобавок означает, что метка выбрал автор, и это
|
||||
отдельная строка;
|
||||
- **вернуть отчёт**, в котором обязательно: исход задачи одним из трёх слов;
|
||||
**план прогона: ступень с обоснованием, темы и их глубины**, и режим; что сделано; какие вопросы
|
||||
**план прогона: метка с обоснованием, темы и их глубины**, и режим; что сделано; какие вопросы
|
||||
записаны и куда; изменённые файлы; добавлялся ли нумерованный артефакт и с
|
||||
каким номером; затронутые capability; состояние гейта; **перечень
|
||||
тем с исходом по каждой**; **путь к
|
||||
@@ -284,9 +285,9 @@ flowchart TD
|
||||
Сверка идёт в три шага, и порядок важен:
|
||||
|
||||
1. **Возьми план прогона** из отчёта задачи — таблицу «тема → дом → глубина → кто
|
||||
закрывает» со ступенью и обоснованием; он затем и заказан в обязательных полях
|
||||
закрывает» с меткой и обоснованием; он затем и заказан в обязательных полях
|
||||
шага 4. Плана в отчёте нет — сверять не с чем; это само по себе основание не
|
||||
вливать, пока сабагент не покажет план разметчика.
|
||||
вливать, пока сабагент не покажет план разметки задачи.
|
||||
2. **Сверяй с независимым артефактом, а не с прозой отчёта.** Перечень проходов
|
||||
бери из **сохранённого отчёта триажа** (`openspec/changes/<id>/review/` или
|
||||
`openspec/changes/archive/<id>/review/` — задача доведена, change заархивирован) —
|
||||
@@ -294,13 +295,18 @@ flowchart TD
|
||||
проход и пропустить: она подтверждает сама себя. Отчёта триажа на месте нет —
|
||||
считай, что состав неизвестен, и дозапускай ревью целиком.
|
||||
3. **Сверь план с исходом**: против каждой темы плана обязан стоять отчёт либо
|
||||
названная причина его отсутствия. Раскладка «тема → кто закрывает на этой
|
||||
ступени» — в скилле `av-dev-pipeline:review-pipeline`.
|
||||
названная причина его отсутствия. Раскладка «тема → кто закрывает с этой меткой» — в скилле `av-dev-pipeline:review-pipeline`.
|
||||
|
||||
Расхождение — не повод отменять задачу: дозапусти недостающие проходы **на
|
||||
ветке**, в её worktree, через `av-dev-pipeline:review-pipeline`, и только потом
|
||||
интегрируй.
|
||||
|
||||
**Передай в дозапуск тот же план.** Триаж требует его обязательным входом — без
|
||||
плана он не может сверить, все ли размеченные темы вернули отчёт, а эта сверка и
|
||||
есть то, ради чего дозапуск затевается. Плана не осталось (сабагент не сохранил
|
||||
его в отчёте) — пусть повторит разметку задачи: это самый дешёвый проход
|
||||
конвейера, и он дешевле, чем прогон, который нечем сверить.
|
||||
|
||||
**Находки дозапуска — такие же находки, и зелёный гейт их не отменяет.** Правило
|
||||
интеграции «вливаем только зелёные» смотрит на гейт, а дозапущенный `critical`
|
||||
гейт не красит: он был бы пропущен молча, если это не сказать прямо. Поэтому:
|
||||
@@ -337,7 +343,7 @@ rebase делается **внутри worktree задачи**, а ff-слиян
|
||||
(`git -C <path> rebase --abort`), оставь ветку и worktree как есть, вынеси это
|
||||
в доклад как нераспознанное пересечение;
|
||||
- **дерево сабагента обязано быть чистым.** `git -C <path> status --porcelain`
|
||||
до `rebase`: непусто — значит сабагент не довёл шаг 11 до коммита учёта (или
|
||||
до `rebase`: непусто — значит сабагент не довёл шаг 12 до коммита учёта (или
|
||||
оставил мусор). Не форсируй и не коммить за него: назови задачу в докладе
|
||||
недоведённой и оставь ветку с worktree. Молчаливый `rebase` на грязном дереве
|
||||
всё равно откажет, но с сообщением про unstaged changes — а причина другая;
|
||||
@@ -395,7 +401,26 @@ rebase в файле X», а не «нераспознанное пересеч
|
||||
- **заверши триажем.** Он единственный, кто агрегирует, и без него у находок нет
|
||||
ни оракула, ни пометки `инлайн`/`развилка` — а следующий абзац на неё
|
||||
опирается. Прогон из двух проходов без триажа — это сырые находки, выданные за
|
||||
разобранные.
|
||||
разобранные;
|
||||
- **план триажу собери сам, здесь, — разметчика на этой сверке нет.** Триаж
|
||||
требует план обязательным входом: он сверяет размеченное с пришедшим, и без
|
||||
плана эта сверка не выполняется вовсе. Разметка задачи сюда не годится — она
|
||||
описывала одну задачу, а сверка идёт по интегрированной ветке. План здесь
|
||||
короткий и составляется по факту запуска:
|
||||
|
||||
```
|
||||
метка: не применяется — сверка стыка, а не ревью изменения
|
||||
тема дом глубина закрывает
|
||||
requirements openspec/specs/<capability-1>/ разбор specs (стык)
|
||||
requirements openspec/specs/<capability-2>/ разбор specs (стык)
|
||||
architecture docs/architecture.md разбор architecture
|
||||
+ источник docs/passport.md
|
||||
```
|
||||
|
||||
Темы, которых в этом списке нет (`autotests`, `conventions`, `security`,
|
||||
`operations`, свои темы проекта), назови строкой «не проверяется на сверке
|
||||
стыка: закрыто прогонами отдельных задач». Это не формальность — без такой
|
||||
строки отчёт сверки читается как полное ревью ветки.
|
||||
|
||||
Граф этой сверки — веер в один сток, и он такой же, как у обычного прогона:
|
||||
|
||||
@@ -421,7 +446,7 @@ flowchart TD
|
||||
`git worktree prune`. Worktree и ветки **провалившихся** не трогай — они нужны
|
||||
для ручного дожатия.
|
||||
- **Записей учёта батч не трогает** — их правит пайплайн внутри сабагента на
|
||||
шаге 11. Батч сообщает исход по каждой задаче; если какой-то сабагент дошёл до
|
||||
шаге 12. Батч сообщает исход по каждой задаче; если какой-то сабагент дошёл до
|
||||
коммита, но закрытия не сделал (плагина нет, вызов не разрешился), скажи это
|
||||
строкой — иначе задача останется открытой молча.
|
||||
- Доложи кратко:
|
||||
|
||||
Reference in New Issue
Block a user