# 18. Ступень поднимает проход, а не риск (2026-08-04) ## Что было Наблюдение с живых проектов: полный набор проходов гоняется чаще, чем оправдано — архитектура и независимая реализация нужны заметно реже, чем запускаются. Развилка названа сразу: крупные задачи с частым полным ревью либо мелкие и средние задачи со средним ревью. Выбран второй путь. Разбор показал, что размер задач — только половина причины, и не главная. ## Решено **Р70. Профиль — максимум по поверхности, а не средневзвешенное.** Условия читаются сверху вниз, первое подошедшее отвечает за весь дифф. Значит цена ревью растёт быстрее размера задачи: на крупной задаче верхний профиль оплачивается в том числе за ту её часть, которая сама по себе была бы `quick`. Это и есть механизм, ради которого выбран путь мелких задач. **Р71. Ступень поднимает то, что даёт работу новому проходу, а не то, что кажется рискованным.** Правило вывода, по которому спорные случаи решаются без нового списка. Проверка нынешних триггеров этим правилом: | Триггер | Кто закрывает | Где этот проход | | --- | --- | --- | | миграция схемы | `gate` (шаг миграций), `ops` (миграция под потоком, откат при двух версиях) | уже в `standard` | | публичный контракт | `specs`, направление `code → spec` | во всех профилях | | инвариант проекта | основание для `critical` у любого прохода | во всех | | новый пакет, новое понятие | `architecture` | только `wide` | | новое правило слияния | `reimpl` | только `deep` | Три верхних триггера не добавляли ни одного прохода — они поднимали ступень «на всякий случай». На проекте с базой и эндпоинтами это делало верхнюю ступень умолчанием, то есть правило объявляло исключением то, что происходит всегда. **Р72. Миграция схемы, публичный контракт и инвариант уехали в `standard`.** `wide` теперь означает ровно одно: изменение вводит **новое понятие или структурную единицу** — новый пакет или слой, новая точка входа, второй способ делать то, что уже делается, перенос ответственности между узлами. Добавленное поле в существующем ответе концептом не является. Это **отменяет часть JJJ темы 17**: ступень `wide` остаётся, её содержание меняется. Проект, где изменение контракта и правда архитектурное (публичный SDK, чужие потребители), поднимает его сам в `docs/review.md` — уточнением, а не возвратом прежнего умолчания. **Р73. Чекпоинт `design` получил то же условие.** `review-specs` в режиме «дизайн ДО кода» идёт всегда — это самый дешёвый чекпоинт конвейера. `review-rubric` и `review-architecture` — только при новом понятии. Причина арифметическая: чекпоинт стоит на **каждой** задаче, поэтому при мелкой нарезке три прохода умножаются на число задач и становятся самой большой статьёй. Причина по существу та же, что в SSS: рубрика на узел без нового понятия порождает свойства уже существующего рода, записанные конвенциями и спеками. **Р74. Шов нарезки — граница, за которой падает ступень.** Тест декомпозиции отвечает, **допустим** ли разрез; шов отвечает, **где** его провести. Раздел «Затрагивает» перечисляет границы; строка, поднимающая ступень выше остальных, и есть кандидат на отдельную задачу. **Р75. Костяк из четырёх проходов платится за каждую задачу.** Гейт, спеки, код, триаж несокращаемы, поэтому разрез, после которого обе половины остаются в одной ступени, делает ревью **дороже**: тот же объём тем же составом, но костяк оплачен дважды. Резать — когда разрез снимает дорогой проход с большей части диффа. **Р76. Верхняя ступень задана тестом, а не списком.** «Идентичность, слияние, разбор» — формулировка, пришедшая из одного проекта, и в общем виде она не читалась: вопрос «как это применить к моему проекту» не имел ответа в тексте. Теперь класс задан тремя условиями, независимыми от домена и языка: вариантов несколько и оба защитимы; спека между ними не выбирает; неверный выбор не падает, а молча меняет смысл данных. Отрицательный тест сильнее положительных — то, что красит гейт или роняет запрос, в класс не входит. Три слова остались как **три места**, где такие правила водятся (граница входа данных и место их встречи), а проект перечисляет свои места в `docs/review.md` — перечень производен от теста и не расширяет класс. Оговорка, без которой правило вырождается: триггер — **новое или изменённое по существу правило**, а не код рядом с ним. Проект, чей домен и состоит из таких правил, иначе оказывался бы в `deep` всегда — та же болезнь, от которой лечилась ступень `wide`. ## Что из этого следует **С72. Порога в числе границ не заводится.** Тот же принцип, что в теме 16 ([Р55](16-directory-instead-of-file.md)): размер не триггер. Шов проходит по скачку ступени, а не по длине перечня. **С73. Ступень — признак для планирования, но не запись в задаче.** Строка «делать профилем standard» в теле — тот самый второй дом правила выбора, который снимает гигиена полей. Профиль выбирает тот, кто видит изменение. **С74. Дешёвое место заметить разнородную задачу — показ набора спринта.** Там «Затрагивает» уже написан, а предложение об изменении ещё не заведено: разрез стоит одного `edit` вместо выброшенного предложения. **С75. Замер остаётся за обкаткой.** Правило выведено из состава проходов, а не из статистики прогонов: считать, какая доля задач попадает в каждую ступень, можно только на спринтах нового процесса (TODO шаг 4). **С76. Отсутствие верхней ступени — законное состояние проекта.** Бывают проекты, где данные приходят нормализованными, ничего ни с чем не сливается, а внешних форматов нет: `deep` там не срабатывает никогда, и придумывать ему повод не надо. Раньше это читалось как недонастройка. **С77. Ступень определяет класс правила, а не вид работы.** Миграция схемы — `standard`, но миграция, переносящая данные по правилу («сложить дубли», «привести к одному виду перед сравнением»), несёт правило идентичности и потому `deep`. Одно слово в описании задачи попадает в разные ступени — это не противоречие, смотрят не на слово.