SKILL.md конвейера дорос до 1168 строк, и двести с лишним из них отвечали на вопрос, который на обычной задаче не задаётся: как выбирается метка. Называет её review-scope один раз, до обеих стадий, а всем остальным нужна не процедура выбора, а состав по уже названной метке — три строки таблицы. В references/review-levels.md переехали правило двух осей, «спорное решается вниз», «максимум по поверхности», разбор того, чем small дешевле medium, и обе проверки долей. В скилле остались таблица состава, схема процесса и раздача тем: метка названа — состав читается. Форма выбрана одна на все метки, а не по документу на метку, как у типов задач в av-dev-pm:tasks. Аналогия не переносится дважды. Типы задач разъединены — общее лежит в task-format.md, в файле типа только своё; метки вложены: medium это small плюс два прохода, large — medium плюс доказательство, и три файла повторяли бы костяк трижды. Такое расхождение copies.py не ловит: он сверяет дословные копии по маркерам, а вышли бы почти-копии с намеренными мелкими отличиями, неотличимые от задуманного. Причина сильнее: ценность текста в сравнении. Вопрос читателя не «что делает small», а «чем small отличается от medium» — на него отвечают и выбор метки, и «спорное вниз», и корректор; сравнение, разложенное по трём файлам, не читается. Механика рычагов осталась в скилле. Непуск, вход и потолок общие для всех проходов и всех меток, их дом — «Модель по проходу»; в переехавшем тексте от них только то, что они делают с small, и ссылка на дом. Точные потолки не продублированы, чтобы не заводить второй источник чисел. Ссылку на дом правила получили review-scope, для которого он основная опора, и task-pipeline, где раньше стояло безадресное «правило живёт в скилле конвейера». Заодно вычищено последнее живое упоминание quick и standard: имена удалены каноном 6, но уцелели в объяснении, зачем нужна проверка доли. Решение — 46. SKILL.md: 1168 → 1026 строк. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
15 KiB
Метки задачи — выбор, цена, доли
Дом правила выбора метки. Состав проходов по каждой метке, схема процесса и раздача тем живут в SKILL.md — там диспетчер, и на готовой задаче его достаточно. Здесь то, что читают, когда метку выбирают, оспаривают или калибруют.
Применяет правило review-scope при разметке задачи — не автор изменения. Его
рабочая выжимка лежит в уставе агента; расходиться она с этим файлом не вправе, а
при расхождении прав этот.
Правило выбора — две оси, а не один вопрос
Оси две, они измеряют разное, и метка есть максимум по ним.
| знакомое — форму решения можно назвать до начала | незнакомое — форму предстоит нащупать по ходу | |
|---|---|---|
| малое — один узел | small |
large |
| среднее — несколько узлов одного слоя | medium |
large |
| крупное — несколько слоёв, перенос ответственности, большой рефакторинг | large |
large |
Метка — не синоним размера. Совпадают они только в левом верхнем углу: малое
незнакомое изменение получает large, трогая один узел. Поэтому в плане
стоят три строки, а не одна: размер, сложность и метка — каждая со своим
обоснованием. Проход, выведший объём диффа из метки, ошибётся ровно на этом
случае — а он и есть самый опасный: незнакомая форма в одном узле течёт там, где
её никто не ждёт.
Размер — про объём: сколько мест трогается. Сложность — про неизвестность: знаем ли мы форму решения заранее. Признак незнакомого простой и проверяемый: перед работой нельзя назвать, какие узлы будут тронуты.
Раньше обе оси были склеены в один вопрос «крупное или незнакомое?». Ответ получался тот же, но две вещи под одним именем не измеришь по отдельности, и потому разметка не могла сказать «изменение среднее, но совершенно знакомое» — а именно эта пара и есть рабочее умолчание. Теперь обе оси называются в плане поимённо, и обе — с обоснованием.
Оси называются и на стадии дизайна, и на стадии кода — но считаются один
раз. Это и есть причина, по которой разметка переехала к propose: состав
ревью дизайна выводится из той же пары, что и состав ревью кода, а считать её
дважды значит один раз посчитать без разведённости с автором.
Обратимость — не третья ось, а отрицательный тест. Она не уточняет размер и не уточняет сложность: она запрещает нижнюю метку независимо от обеих.
Отрицательный тест small, и он важнее положительного: изменение, которое
после мерджа не откатывается обратной правкой, — не small, каким бы
маленьким ни был дифф. Сюда попадают миграция схемы и данных, формат на диске,
публичный контракт, имя, которое разойдётся по кодовой базе. Три строки миграции
— это medium, а не small: размер диффа и цена ошибки здесь расходятся.
Что здесь считается крупным, что — незнакомым и что — мелким, проект уточняет в
docs/review.md, подразделе «Триггеры метки»: тремя списками — по одному на
каждую ось вверх и один вниз, поимённо, узлами или capability. Это уточнение,
а не отмена: не записано — работает таблица выше.
Спорный случай решается вниз, и у этого есть цена
Правило асимметрично, потому что асимметрична цена ошибки.
- Спорно между
mediumиlarge→ бериmedium. Ошибка в эту сторону стоит находки, которая всплывёт на следующей задаче или в журнале дефектов. Ошибка в обратную стоит трёх тяжёлых проходов, двое из которых держат машину и идут цепочкой, — и платится она на каждой задаче, выбранной неверно. - Спорно между
smallиmedium→ бериmedium. Раньше эта строка обосновывалась тем, что состав одинаков и ошибка почти бесплатна. Теперь состав разный, и обоснование стало прямо противоположным: наsmallтри темы ядра смотрятся только против записанных инвариантов, а спорный случай — ровно тот, где неизвестно, покрыт ли он инвариантом. Сомнение здесь стоит дороже, чем раньше, и потому решается вниз тем более твёрдо.
Выбор сделан в пользу пропускной способности, и это записано, а не подразумевается. Конвейер настроен на поток задач, а не на максимум находок с каждой: поправить в следующей задаче дешевле, чем держать одну два часа. Отсюда три обязанности, без которых сделка превращается в незаметную потерю качества:
- границы покрытия называют темы и их глубину, а не только запущенные
проходы — иначе
smallвыглядит так же, какlargeбез находок; - журнал дефектов в
docs/review.mdперестаёт быть хорошей практикой и становится единственной обратной связью: проскочивший дефект — единственный сигнал, что метка выбрана слишком низко; - возврат в код — повод пересмотреть метку. Задача, которая приходит в тот же узел третий раз, уже не мелкая, чем бы ни выглядел её дифф.
Метка — максимум по поверхности
Обе оси меряются по всему диффу разом, и максимум по каждой отвечает за весь
дифф. Метка изменения — не средневзвешенное: одна строка в перечне границ
задачи поднимает метку всему остальному, включая ту часть, которая сама по себе
была бы small.
Обратное тоже верно и тоже не бесплатно: у каждой задачи есть несокращаемый
костяк — гейт, спеки, код, триаж. Разрезать задачу, обе половины которой
остаются в одной метке, значит заплатить костяк дважды за ту же проверку.
Резать стоит там, где разрез снимает доказательство с большей части диффа.
Шов и правило нарезки живут у того, кто ведёт задачи, — скилл av-dev-pm:tasks,
его references/split.md. Пути туда конвейер не выносит: за пределы своего
плагина он ходит вызовом скилла, а не файлом.
Разметка в костяк не входит — она платится один раз на задачу, а не один раз на
прогон, и потому разрез задачи её не удваивает. Это единственное, что стало
дешевле от переезда разметки к propose, и это же снимает прежний довод против
нарезки.
Размер, сложность, метка и глубина объявляются в отчёте, и все четыре с
обоснованием. Метка выбирает review-scope; он вправе и поднять, и понизить
её — но не молча: строка «метка X, потому что размер Y и сложность Z»
обязательна на каждом прогоне, а не только когда метка отличается от ожидаемой.
Чем small дешевле medium и что это стоит
Экономят три рычага — непуск, вход, потолок, — и они общие для всех проходов и всех меток; их дом и точные числа в SKILL.md, раздел «Модель по проходу». Здесь только то, что рычаги делают с этой меткой:
- Составом.
basicsнаsmallне запускается — кроме случая, когда у проекта есть свои темы; тогда он идёт только с ними, ровно как вlarge. Три темы ядра, которые он держал бы, переходят кcodeсверкой по инвариантам. - Входом. На
smallspecsчитает только дельта-спеку, аcode— только индекс конвенций (перечень родов и что механизировано), не весь их дом. Наmediumоба читают дома целиком. - Потолком. На
smallпотолки самые жёсткие из трёх меток, и каждый напечатан в границах покрытия своего прохода.
Что small за это не проверяет, названо поимённо и обязано идти строкой в
границы покрытия: темы security, operations и architecture смотрятся
только против записанных инвариантов CLAUDE.md. Свойство, которого в
инвариантах нет, с этой меткой не спросит никто — ни сценарием, ни чтением
дома темы. Это и есть цена метки, и она заметно больше прежней: раньше small
отличался от medium одним проходом на один вопрос, то есть не экономил
ничего и назывался отдельной меткой зря.
large назван по тому, что он добавляет: вход шире диффа. Он единственный, где
живут тяжёлые проходы, и единственный, где что-то запускается. basics в нём
берёт только проектные темы; своих тем у проекта нет — он не запускается вовсе, и
план говорит об этом строкой. На small действует то же правило и по той же
причине — приёмник запускается только тогда, когда ему есть что принимать.
Совпадение неслучайное: basics держит темы ядра ровно при одной метке из трёх,
а приёмником проектных тем работает на всех.
Доли — не пожелание, а проверка правила, и проверок две
Сверху: large — 5–10%. Если туда уходит каждая третья задача, метку
выбирают по ощущению важности. Обратный перекос виден по журналу проскочивших
дефектов: класс, который ловят только меряющие проходы, начинает всплывать после
мерджа.
Снизу: small не должен обгонять medium. Ориентир — до трети задач, но
сравнение важнее числа: перевес small над medium значит, что рабочее
умолчание сместилось, а решения об этом никто не принимал. Проверка нужна
именно теперь: пока две нижние метки совпадали составом, дрейф между ними не
стоил ничего, и проверки не было. Сейчас он стоит трёх тем ядра, которые на
small смотрятся только против инвариантов, — то есть ровно того, чем small и
дёшев.
Считается это по журналу дефектов и по отчётам, а не по ощущению: метка напечатана в каждом отчёте, и посчитать её за спринт — работа на минуту.
У дрейфа вниз есть свой стимул, и его стоит назвать. small дешевле по
времени и по деньгам, а выбирает метку хоть и не автор, но проход, читающий
описание, написанное автором. Занижённое описание даёт занижённую метку без
чьего-либо злого умысла — потому корректор и вынесен в code, который смотрит
уже на код, а не на описание.