Files
dev-skills/decisions/18-tier-raises-pass-not-risk.md
T
av bf6a173115 журнал решений: разложен по теме на файл, метки решений стали номерами
- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель;
- буквенные метки решений заменены сквозными Р1–Р234, следствия получили
  префикс С при прежних номерах: схема букв выродилась до пятибуквенных и
  сломалась — `АЕАКЛ` была занята и темой 53, и темой 65;
- 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер
  означал тему, а слово стояло «решение», формулировка исправлена.
2026-08-13 12:40:56 +03:00

108 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`. Одно слово в описании задачи попадает в разные ступени — это не
противоречие, смотрят не на слово.