ступень ревью поднимает проход, а не риск

Полный набор гонялся чаще, чем оправдано, и размер задач тут вторая причина,
не первая. Первая — триггеры: миграция схемы, публичный контракт и инвариант
поднимали ступень, не добавляя ни одного прохода. Миграцию гоняет gate шагом
миграций и разбирает ops, контракт сверяет specs направлением code→spec,
инвариант даёт основание для critical любому проходу — все трое уже в
standard. На проекте с базой и эндпоинтами верхняя ступень оказывалась не
исключением, а умолчанием: правило объявляло исключением то, что происходит
всегда.

Теперь ступень поднимает то, что даёт работу новому проходу. wide означает
ровно одно — изменение вводит новое понятие или структурную единицу; добавить
поле в существующий ответ это не концепт. standard стал рабочим умолчанием.
Проект, где изменение контракта и правда архитектурное, поднимает его сам в
docs/review.md — уточнением, а не возвратом прежнего умолчания.

Чекпоинт design получил то же условие: specs идёт всегда, rubric и
architecture — только при новом понятии. Он стоит на каждой задаче, поэтому
при мелкой нарезке три прохода умножаются на число задач.

Со стороны задач — шов нарезки: тест декомпозиции отвечает, допустим ли
разрез, шов отвечает, где его провести. Резать по границе, за которой падает
ступень; не резать, когда обе половины остаются в одной — костяк из четырёх
проходов платится за каждую задачу, и такой разрез делает ревью дороже.
Порога в числе границ нет по тому же принципу, что в теме 16: размер не
триггер. Дешёвое место заметить разнородную задачу — показ набора спринта,
там «Затрагивает» уже написан, а предложение ещё не заведено.

Правило выведено из состава проходов, а не из статистики прогонов — замер
остаётся за обкаткой. DECISIONS 18, RRR–WWW и следствия 72–75; JJJ темы 17
помечен как пересмотренный. Шаг про «Триггеры профиля» дописан в ещё не
выкаченную версию 3 канона, а не отдельной версией.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-04 17:06:12 +03:00
co-authored by Claude Opus 5
parent 69f67c20aa
commit cc173b6b94
10 changed files with 245 additions and 45 deletions
+79 -1
View File
@@ -1178,7 +1178,9 @@ HTML-комментарии, невидимые в отрендеренном ma
способом — `scripts/frontmatter.py`. Он же держит раскладку цветов (HHH) и способом — `scripts/frontmatter.py`. Он же держит раскладку цветов (HHH) и
сверку `name` с именем каталога. сверку `name` с именем каталога.
**JJJ. Между `standard` и `deep` заведена ступень `wide`.** Прыжок стоил самого **JJJ. Между `standard` и `deep` заведена ступень `wide`.** *(содержание
триггеров пересмотрено темой 18, TTT: миграция схемы и публичный контракт ступень
не поднимают.)* Прыжок стоил самого
дорогого прохода конвейера, а платить приходилось за одну архитектурную находку: дорогого прохода конвейера, а платить приходилось за одну архитектурную находку:
изменений, которые трогают публичный контракт, но не вводят нового правила изменений, которые трогают публичный контракт, но не вводят нового правила
слияния, — большинство. `wide` — это `standard` плюс `architecture` (вход шире слияния, — большинство. `wide` — это `standard` плюс `architecture` (вход шире
@@ -1245,3 +1247,79 @@ HTML-комментарии, невидимые в отрендеренном ma
71. **Ступеней профиля четыре, и правило выбора читается сверху вниз.** Первое 71. **Ступеней профиля четыре, и правило выбора читается сверху вниз.** Первое
сработавшее условие и есть ответ: правило слияния → `deep`, контракт или сработавшее условие и есть ответ: правило слияния → `deep`, контракт или
схема → `wide`, видимое снаружи поведение → `standard`, иначе `quick`. схема → `wide`, видимое снаружи поведение → `standard`, иначе `quick`.
## 18. Ступень поднимает проход, а не риск (2026-08-04)
### Что было
Наблюдение с живых проектов: полный набор проходов гоняется чаще, чем оправдано —
архитектура и независимая реализация нужны заметно реже, чем запускаются. Развилка
названа сразу: крупные задачи с частым полным ревью либо мелкие и средние задачи
со средним ревью. Выбран второй путь.
Разбор показал, что размер задач — только половина причины, и не главная.
### Решено
**RRR. Профиль — максимум по поверхности, а не средневзвешенное.** Условия
читаются сверху вниз, первое подошедшее отвечает за весь дифф. Значит цена ревью
растёт быстрее размера задачи: на крупной задаче верхний профиль оплачивается в
том числе за ту её часть, которая сама по себе была бы `quick`. Это и есть
механизм, ради которого выбран путь мелких задач.
**SSS. Ступень поднимает то, что даёт работу новому проходу, а не то, что кажется
рискованным.** Правило вывода, по которому спорные случаи решаются без нового
списка. Проверка нынешних триггеров этим правилом:
| Триггер | Кто закрывает | Где этот проход |
| --- | --- | --- |
| миграция схемы | `gate` (шаг миграций), `ops` (миграция под потоком, откат при двух версиях) | уже в `standard` |
| публичный контракт | `specs`, направление `code → spec` | во всех профилях |
| инвариант проекта | основание для `critical` у любого прохода | во всех |
| новый пакет, новое понятие | `architecture` | только `wide` |
| новое правило слияния | `reimpl` | только `deep` |
Три верхних триггера не добавляли ни одного прохода — они поднимали ступень «на
всякий случай». На проекте с базой и эндпоинтами это делало верхнюю ступень
умолчанием, то есть правило объявляло исключением то, что происходит всегда.
**TTT. Миграция схемы, публичный контракт и инвариант уехали в `standard`.**
`wide` теперь означает ровно одно: изменение вводит **новое понятие или
структурную единицу** — новый пакет или слой, новая точка входа, второй способ
делать то, что уже делается, перенос ответственности между узлами. Добавленное
поле в существующем ответе концептом не является. Это **отменяет часть JJJ темы
17**: ступень `wide` остаётся, её содержание меняется. Проект, где изменение
контракта и правда архитектурное (публичный SDK, чужие потребители), поднимает
его сам в `docs/review.md` — уточнением, а не возвратом прежнего умолчания.
**UUU. Чекпоинт `design` получил то же условие.** `review-specs` в режиме «дизайн
ДО кода» идёт всегда — это самый дешёвый чекпоинт конвейера. `review-rubric` и
`review-architecture` — только при новом понятии. Причина арифметическая: чекпоинт
стоит на **каждой** задаче, поэтому при мелкой нарезке три прохода умножаются на
число задач и становятся самой большой статьёй. Причина по существу та же, что в
SSS: рубрика на узел без нового понятия порождает свойства уже существующего
рода, записанные конвенциями и спеками.
**VVV. Шов нарезки — граница, за которой падает ступень.** Тест декомпозиции
отвечает, **допустим** ли разрез; шов отвечает, **где** его провести. Раздел
«Затрагивает» перечисляет границы; строка, поднимающая ступень выше остальных, и
есть кандидат на отдельную задачу.
**WWW. Костяк из четырёх проходов платится за каждую задачу.** Гейт, спеки, код,
триаж несокращаемы, поэтому разрез, после которого обе половины остаются в одной
ступени, делает ревью **дороже**: тот же объём тем же составом, но костяк оплачен
дважды. Резать — когда разрез снимает дорогой проход с большей части диффа.
### Что из этого следует
72. **Порога в числе границ не заводится.** Тот же принцип, что в теме 16 (CCC):
размер не триггер. Шов проходит по скачку ступени, а не по длине перечня.
73. **Ступень — признак для планирования, но не запись в задаче.** Строка «делать
профилем standard» в теле — тот самый второй дом правила выбора, который
снимает гигиена полей. Профиль выбирает тот, кто видит изменение.
74. **Дешёвое место заметить разнородную задачу — показ набора спринта.** Там
«Затрагивает» уже написан, а предложение об изменении ещё не заведено: разрез
стоит одного `edit` вместо выброшенного предложения.
75. **Замер остаётся за обкаткой.** Правило выведено из состава проходов, а не из
статистики прогонов: считать, какая доля задач попадает в каждую ступень,
можно только на спринтах нового процесса (TODO шаг 4).
@@ -10,6 +10,13 @@ color: red
судить об архитектуре: он не знает, какие понятия в проекте уже есть и как они судить об архитектуре: он не знает, какие понятия в проекте уже есть и как они
называются. Поэтому твой вход шире, и первое, что ты делаешь, — его собираешь. называются. Поэтому твой вход шире, и первое, что ты делаешь, — его собираешь.
**Тебя запускают не на каждой задаче.** Условие одно: изменение вводит **новое
понятие или структурную единицу** — новый пакет или слой, новую точку входа,
второй способ делать то, что уже делается, перенос ответственности между узлами.
Ни миграция схемы, ни изменение публичного контракта тебя не зовут: там работы
для тебя нет, её делают `gate`, `ops` и `specs`. Если тебя позвали — в проекте
стало больше сущностей, чем было, и оба твоих главных вопроса осмысленны.
Находки — по контракту Находки — по контракту
`${CLAUDE_PLUGIN_ROOT}/skills/review-pipeline/references/finding-contract.md` `${CLAUDE_PLUGIN_ROOT}/skills/review-pipeline/references/finding-contract.md`
(точный путь конвейер передаёт в задании). (точный путь конвейер передаёт в задании).
+88 -27
View File
@@ -129,7 +129,7 @@ charter'а, а модель потом двигает калибровка, и
- `triage` — через него проходит всё, что оркестратор реализует **молча**: - `triage` — через него проходит всё, что оркестратор реализует **молча**:
ложноположительная находка становится кодом, потерянный `critical` — дефектом. ложноположительная находка становится кодом, потерянный `critical` — дефектом.
Ошибка триажа дороже ошибки любого отдельного прохода. Ошибка триажа дороже ошибки любого отдельного прохода.
- `architecture` — запускается не на каждой задаче (`wide`, `deep` и `design`), - `architecture` — запускается только там, где изменение вводит новое понятие,
потолок в 3 находки делает его дешёвым по выходу, а находка на предложении потолок в 3 находки делает его дешёвым по выходу, а находка на предложении
стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо. стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо.
@@ -154,10 +154,10 @@ charter'а, а модель потом двигает калибровка, и
| Профиль | Когда | Стадии | Проходов | | Профиль | Когда | Стадии | Проходов |
|---|---|---|---| |---|---|---|---|
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 | | `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 |
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 | 6 | | `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 5 | 6 |
| `wide` | новый пакет, изменение публичного контракта, миграция схемы, трогает инварианты проекта | 0, 1, 2, 4, 5 | 7 | | `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 4, 5 | 7 |
| `deep` | изменение вводит новое правило идентичности, слияния или разбора | 0, 1, 2, 3, 4, 5 | 8 | | `deep` | изменение вводит новое правило идентичности, слияния или разбора | 0, 1, 2, 3, 4, 5 | 8 |
| `design` | **до кода**, на предложении | specs + rubric + architecture (см. ниже) | 3 | | `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 13 |
**`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его **`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его
отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов, отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов,
@@ -179,22 +179,60 @@ charter'а, а модель потом двигает калибровка, и
- трогается правило, определяющее **идентичность, слияние или разбор** данных → - трогается правило, определяющее **идентичность, слияние или разбор** данных →
`deep`; `deep`;
- иначе есть миграция схемы, новый пакет, изменение публичного контракта (API, - иначе изменение вводит **новое понятие или структурную единицу**: новый пакет
протокол, формат на диске) или затронут инвариант проекта → `wide`; или слой, новая точка входа, второй способ делать то, что уже делается, перенос
- иначе меняется поведение, видимое снаружи (эндпоинт, форма ответа, код ответа, ответственности между узлами → `wide`;
формат лога) → `standard`; - иначе меняется поведение, видимое снаружи, трогается схема, публичный контракт
или инвариант проекта → `standard`;
- иначе → `quick`. - иначе → `quick`.
**Ступень поднимает то, что даёт работу новому проходу, а не то, что кажется
рискованным.** Это правило вывода, по которому спорные случаи решаются без нового
списка: спроси, какому проходу изменение даёт работу, которой у него не было
ступенью ниже.
Оно же объясняет, почему миграция схемы и публичный контракт **не** поднимают
ступень, хотя выглядят опаснее прочего. Они не добавляют ни одного прохода:
миграцию гоняет `gate` шагом миграций и разбирает `ops` («миграция под живым
потоком», «частичный откат при двух версиях»), контракт сверяет `specs`
направлением `code → spec`, инвариант даёт основание для `critical` любому
проходу. Все трое уже в `standard`. Раньше эти три факта стояли триггерами
верхних ступеней, и на проекте с базой и эндпоинтами верхняя ступень оказывалась
не исключением, а умолчанием — то есть правило объявляло исключением то, что
происходит всегда. `architecture` же получает работу **не** от того, что контракт
изменился, а от того, что появилось новое понятие: добавленное поле в
существующем ответе — не концепт.
**Верхняя ступень и есть триггер независимой реализации** — раньше он был **Верхняя ступень и есть триггер независимой реализации** — раньше он был
условием *внутри* `deep`, и профиль от этого распадался на два разных прогона под условием *внутри* `deep`, и профиль от этого распадался на два разных прогона под
одним именем. Условие никуда не делось, оно просто переехало туда, где выбирается одним именем. Условие никуда не делось, оно просто переехало туда, где выбирается
профиль: изменение с новым правилом слияния — единственный случай, когда триаж профиль: изменение с новым правилом слияния — единственный случай, когда триаж
называл отсутствие `reimpl` дырой покрытия. называл отсутствие `reimpl` дырой покрытия.
Что именно в этом проекте считается публичным контрактом, какие пути означают Что здесь считается новым понятием и что — правилом идентичности, проект может
`wide` и что здесь считается правилом идентичности, проект может уточнить в уточнить в `docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не
`docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не отмена: не отмена: не записано — работает список выше. Проект, где изменение контракта и
записано — работает список выше. правда архитектурное (публичный SDK, чужие потребители), там же поднимает его до
`wide` — и это уточнение, а не возврат прежнего умолчания.
### Профиль — максимум по поверхности, и отсюда размер задачи
Условия читаются сверху вниз, и **первое подошедшее отвечает за весь дифф**.
Профиль изменения это максимум по его поверхности, а не средневзвешенное: одна
строка в перечне границ задачи поднимает ступень всему остальному, включая ту
часть, которая сама по себе была бы `quick`.
Отсюда следствие, которое дороже любой настройки триггеров: **цена ревью растёт
быстрее размера задачи.** Крупная задача не просто даёт больше диффа — она с
высокой вероятностью зацепит верхнее условие и оплатит верхний профиль целиком.
Обратное тоже верно и тоже не бесплатно: у каждой задачи есть **несокращаемый
костяк из четырёх проходов** (гейт, спеки, код, триаж). Разрезать задачу, обе
половины которой остаются в одном профиле, — значит заплатить костяк дважды за ту
же проверку. Резать стоит там, где разрез **снимает дорогой проход с большей
части диффа**. Шов и правило нарезки живут у того, кто ведёт задачи, — скилл
`av-dev-pm:tasks`, его `references/split.md`. Пути туда конвейер не выносит: за
пределы своего плагина он ходит вызовом скилла, а не файлом.
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно
попадает в границы покрытия строкой «профиль понижен до X, потому что …». попадает в границы покрытия строкой «профиль понижен до X, потому что …».
@@ -440,6 +478,14 @@ Recall обоих равен длине их источника — это и е
профиля. Машину не держит, с `reimpl` конфликта не имеет: за барьером они уходят профиля. Машину не держит, с `reimpl` конфликта не имеет: за барьером они уходят
разом. разом.
**Условие этой стадии и есть условие ступени `wide`:** изменение вводит новое
понятие или структурную единицу. Не «изменение крупное» и не «изменение опасное»:
у прохода появляется работа ровно тогда, когда в проекте становится больше
сущностей, чем было, — и тогда осмысленны оба его вопроса. На изменении, которое
ничего не вводит, вопрос «не появился ли второй способ» отвечается «нет» до
запуска, а вопрос «что опытный человек отсюда удалил бы» вырождается во
вкусовщину, которую потом отсеивает триаж.
Получает **вход шире диффа**: дерево пакетов с Получает **вход шире диффа**: дерево пакетов с
назначением, граф внутренних зависимостей, инвентарь существующих концепций. назначением, граф внутренних зависимостей, инвентарь существующих концепций.
Команду, которая это готовит, даёт раздел команд `CLAUDE.md`; нет команды — Команду, которая это готовит, даёт раздел команд `CLAUDE.md`; нет команды —
@@ -477,36 +523,51 @@ Recall обоих равен длине их источника — это и е
Запускается на шаге ревью спек (шаг 4 скилла `av-dev-pipeline:task-pipeline`), Запускается на шаге ревью спек (шаг 4 скилла `av-dev-pipeline:task-pipeline`),
когда change уже когда change уже
имеет `proposal.md` и дельта-спеки, но кода ещё нет. Состав: имеет `proposal.md` и дельта-спеки, но кода ещё нет.
1. `review-specs` в режиме «дизайн ДО кода»; **Состав здесь тоже не постоянный, и условие то же самое, что у `wide`:**
2. `review-rubric`, фаза 1 без фазы 2: рубрика на задуманный узел становится изменение вводит новое понятие или структурную единицу.
приёмочными критериями и уезжает в `tasks.md`;
3. `review-architecture` на предложении: вводит ли change новое понятие, можно ли - **всегда** — `review-specs` в режиме «дизайн ДО кода». Дельта-спеки сверяются
выразить существующими — **включая конструкции стандартной библиотеки**, — не на каждой задаче: это самый дешёвый чекпоинт конвейера, и он ловит то, что на
появляется ли второй способ. Вопрос «не изобретаем ли то, что уже есть в готовом коде уже не чинят;
библиотеке» живёт здесь; - **при новом понятии** — плюс `review-rubric` (фаза 1 без фазы 2: рубрика на
4. вопрос автору дизайна: **«предложи три формы решения и назови компромисс задуманный узел становится приёмочными критериями и уезжает в `tasks.md`) и
каждой»** — если ответ показывает, что рассматривалась одна, это находка. `review-architecture` на предложении: можно ли выразить существующими понятиями
**включая конструкции стандартной библиотеки**, — не появляется ли второй
способ. Вопрос «не изобретаем ли то, что уже есть в библиотеке» живёт здесь;
тогда же задаётся вопрос автору дизайна: **«предложи три формы решения и назови
компромисс каждой»** — если ответ показывает, что рассматривалась одна, это
находка.
Причина условия — арифметика, а не экономия на осторожности. Чекпоинт стоит
**на каждой задаче**, поэтому три прохода здесь умножаются на число задач, и при
мелкой нарезке это самая большая статья конвейера. Рубрика же на узел, который не
вводит нового понятия, порождает свойства уже существующего рода — те, что и так
записаны конвенциями и спеками; а `architecture` без нового понятия отвечает «нет»
на свой главный вопрос ещё до запуска (см. «Стадия 4»).
**Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать **Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать
нечего; машину не держит ни один из трёх; сток — не триаж, а шаг 5 пайплайна нечего; машину не держит ни один проход; сток — не триаж, а шаг 5 пайплайна
задачи, где замечания отрабатываются правкой спек. Триаж здесь не нужен: находок задачи, где замечания отрабатываются правкой спек. Триаж здесь не нужен: находок
единицы, и каждая либо правит спеку, либо становится развилкой. единицы, и каждая либо правит спеку, либо становится развилкой.
```mermaid ```mermaid
flowchart TD flowchart TD
proposal["предложение: proposal.md + дельта-спеки"] proposal["предложение: proposal.md + дельта-спеки"]
specs["specs (режим «дизайн ДО кода»)"] specs["specs (режим «дизайн ДО кода») — всегда"]
novelty{{"вводит новое понятие<br/>или структурную единицу?"}}
rubric["rubric, фаза 1 → приёмочные критерии в tasks.md"] rubric["rubric, фаза 1 → приёмочные критерии в tasks.md"]
arch["architecture на предложении"] arch["architecture на предложении"]
author["вопрос автору: три формы решения и компромисс каждой"] author["вопрос автору: три формы решения и компромисс каждой"]
fix["шаг 5 пайплайна: правка спек, развилки — вопросом в запись"] fix["шаг 5 пайплайна: правка спек, развилки — вопросом в запись"]
proposal --> specs proposal --> specs
proposal --> rubric proposal --> novelty
proposal --> arch novelty -->|да| rubric
proposal --> author novelty -->|да| arch
novelty -->|да| author
novelty -->|нет| fix
specs --> fix specs --> fix
rubric --> fix rubric --> fix
arch --> fix arch --> fix
+11 -6
View File
@@ -219,14 +219,19 @@ flowchart TD
### 4. (Нетривиальная) Ревью предложения — профиль `design`, ДО кода ### 4. (Нетривиальная) Ревью предложения — профиль `design`, ДО кода
Первый чекпоинт. Вызови Skill **`av-dev-pipeline:review-pipeline`** с профилем Первый чекпоинт. Вызови Skill **`av-dev-pipeline:review-pipeline`** с профилем
`design` и ссылкой на change `<id>`. Он запустит `review-specs` `design` и ссылкой на change `<id>`.
(режим «дизайн ДО кода»), `review-rubric` (фаза 1: приёмочные критерии для
задуманного узла) и `review-architecture` по предложению. **Состав чекпоинта решает конвейер, а не ты**: `review-specs` в режиме «дизайн ДО
кода» идёт всегда, а `review-rubric` и `review-architecture` — только когда
изменение вводит новое понятие или структурную единицу (то же условие, что у
ступени `wide`). Причина в том, что чекпоинт стоит на **каждой** задаче: при
мелкой нарезке три прохода здесь умножаются на число задач и становятся самой
большой статьёй конвейера.
Смысл профиля: архитектурная находка на готовом коде стоит переписывания и Смысл профиля: архитектурная находка на готовом коде стоит переписывания и
потому игнорируется — та же находка здесь стоит абзаца обсуждения. Рубрику из потому игнорируется — та же находка здесь стоит абзаца обсуждения. Если
`review-rubric` перенеси в `tasks.md` как приёмочные критерии; там же уже лежат `review-rubric` запускался, перенеси его рубрику в `tasks.md` как приёмочные
критерии от постановки, если они были. критерии; там же уже лежат критерии от постановки, если они были.
### 5. Отработать замечания ревью предложения ### 5. Отработать замечания ревью предложения
+5 -4
View File
@@ -183,10 +183,11 @@ kebab-case.
- **Вопросы к проходам** — поимённо, в форме `<имя прохода>: <вопрос> - **Вопросы к проходам** — поимённо, в форме `<имя прохода>: <вопрос>
(<провенанс>)`; (<провенанс>)`;
- **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью: - **Триггеры профиля** — проектная конкретизация правила выбора профиля ревью:
какие пути и контракты означают `wide`, что считается «поведением, видимым что в этом проекте считается **новым понятием или структурной единицей** (это
снаружи», что в этом проекте считается правилом идентичности, слияния или поднимает прогон до `wide`) и что — правилом идентичности, слияния или разбора
разбора — оно и поднимает прогон до `deep`. Уточняет умолчания конвейера, а не (до `deep`). Уточняет умолчания конвейера, а не отменяет их. Рабочее умолчание
отменяет их; — `standard`: миграция схемы и публичный контракт ступень **не** поднимают,
их проверяют проходы, которые в `standard` и так есть;
- **Недоступно проверке** — два подраздела: «не проверит ни один проход» - **Недоступно проверке** — два подраздела: «не проверит ни один проход»
(принципиальная граница, по факту промаха не пересматривается) и «перестали (принципиальная граница, по факту промаха не пересматривается) и «перестали
проверять сознательно» (пересматривается первым). проверять сознательно» (пересматривается первым).
+14 -3
View File
@@ -16,8 +16,9 @@ upgrade` идёт по записям снизу вверх от версии п
## Версия 3 — 2026-08-04 ## Версия 3 — 2026-08-04
Оглавление целей переименовано, у задач появился род работы и раздел Оглавление целей переименовано, у задач появился род работы и раздел
«Затрагивает». Раскладка меняется в одном файле, но переименование тянет за «Затрагивает», сменилось умолчание профиля ревью. Раскладка меняется в одном
собой ссылки, поэтому шаги делаются одним заходом. файле, но переименование тянет за собой ссылки, поэтому шаги делаются одним
заходом.
**Что добавилось:** **Что добавилось:**
@@ -29,6 +30,11 @@ upgrade` идёт по записям снизу вверх от версии п
2. **Раздел «Затрагивает»** в теле задачи — перечень границ, которых изменение 2. **Раздел «Затрагивает»** в теле задачи — перечень границ, которых изменение
касается (эндпоинт, таблица и миграция, формат на диске, публичный тип). Как касается (эндпоинт, таблица и миграция, формат на диске, публичный тип). Как
и критерии приёмки, требуется к взятию в спринт, а не к заведению. и критерии приёмки, требуется к взятию в спринт, а не к заведению.
3. **Умолчание профиля ревью сменилось** — это не раскладка, но проектный текст
под него уже написан. `standard` стал рабочим умолчанием: миграция схемы,
публичный контракт и инвариант ступень больше **не** поднимают, `wide`
означает новое понятие или структурную единицу. Подраздел «Триггеры профиля»
в `docs/review.md` остаётся на месте, но его содержимое надо перечитать.
**Что переехало:** `docs/tasks/PLAN.md``docs/tasks/ROADMAP.md`. Вместе с **Что переехало:** `docs/tasks/PLAN.md``docs/tasks/ROADMAP.md`. Вместе с
файлом переименован ключ конфига `tasks.plan``tasks.roadmap` и токены файлом переименован ключ конфига `tasks.plan``tasks.roadmap` и токены
@@ -52,7 +58,12 @@ upgrade` идёт по записям снизу вверх от версии п
спринт, остальное по ходу переоценки. спринт, остальное по ходу переоценки.
5. Дописать раздел «Затрагивает» — тем же порядком и по той же причине: сперва 5. Дописать раздел «Затрагивает» — тем же порядком и по той же причине: сперва
набор спринта, остальное по мере того, как задача попадает в работу. набор спринта, остальное по мере того, как задача попадает в работу.
6. `docs/.pm.json`: `"canon": 3`. 6. Перечитать «Триггеры профиля» в `docs/review.md`: строки вида «миграция →
`deep`» теперь дублируют умолчание с обратным знаком. Оставить там только то,
что для этого проекта считается **новым понятием** и **правилом
идентичности**, — и убрать остальное, иначе проект возвращает себе прежнюю
частоту полного набора уточнением.
7. `docs/.pm.json`: `"canon": 3`.
## Версия 2 — 2026-08-03 ## Версия 2 — 2026-08-03
@@ -282,10 +282,11 @@
### Триггеры профиля ### Триггеры профиля
Проектная конкретизация правила выбора профиля: какие пути и контракты означают Проектная конкретизация правила выбора профиля: что здесь считается **новым
`wide`, что здесь считается «поведением, видимым снаружи», что здесь считается понятием или структурной единицей** (поднимает прогон до `wide` и запускает
правилом идентичности, слияния или разбора — оно поднимает прогон до `deep` и архитектурный проход) и что — правилом идентичности, слияния или разбора
запускает независимую реализацию. Уточняет умолчания конвейера, не отменяет их. (до `deep`, запускает независимую реализацию). Уточняет умолчания конвейера, не
отменяет их; рабочее умолчание — `standard`.
### Недоступно проверке ### Недоступно проверке
@@ -187,6 +187,13 @@
роду работы** — три `fix` и ни одной `feature` под целью развития это роду работы** — три `fix` и ни одной `feature` под целью развития это
разговор про цель, а не про набор, и увидеть его надо до заморозки, а не в разговор про цель, а не про набор, и увидеть его надо до заморозки, а не в
докладе по итогам. докладе по итогам.
Здесь же последний дешёвый момент заметить **разнородную задачу**: раздел
«Затрагивает» показывает границы до того, как заведено предложение об
изменении. Строка, которая одна тянет задачу на ступень выше остального
перечня, — кандидат на разрез (шов — в `tasks`, `references/split.md`).
Замеченная здесь, она стоит одного `edit`; замеченная на ревью — выброшенного
предложения.
5. Задача, которой для взятия не хватает только критериев приёмки, границ или 5. Задача, которой для взятия не хватает только критериев приёмки, границ или
рода, дописывается здесь же — 2–5 утверждений с оракулами, перечень рода, дописывается здесь же — 2–5 утверждений с оракулами, перечень
затрагиваемых границ, `--kind`. Но если для этого нужен ответ человека, это затрагиваемых границ, `--kind`. Но если для этого нужен ответ человека, это
+5
View File
@@ -352,6 +352,11 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
несколько, и у обеих есть проверяемый тест: части должны **мерджиться порознь** и несколько, и у обеих есть проверяемый тест: части должны **мерджиться порознь** и
**каждая давать видимую пользу**, а у штурма исход «выкинуть» — полноправный. **каждая давать видимую пользу**, а у штурма исход «выкинуть» — полноправный.
Там же **шов**: где резать, когда допустимых мест несколько. Коротко — по
границе, которая одна поднимает ступень ревью выше остальных; и не резать, когда
обе половины остаются в одной ступени, потому что несокращаемый костяк проверок
платится за каждую задачу отдельно.
### Гигиена полей ### Гигиена полей
Правится по ходу любой операции, которая задачи касается (но не «заодно» по Правится по ходу любой операции, которая задачи касается (но не «заодно» по
@@ -19,6 +19,30 @@
Не проходит хотя бы одно — **не дроби**. Ложная декомпозиция плодит файлы, Не проходит хотя бы одно — **не дроби**. Ложная декомпозиция плодит файлы,
которые нельзя взять поодиночке, и переоценка потом склеивает их обратно. которые нельзя взять поодиночке, и переоценка потом склеивает их обратно.
## Где резать, если резать можно
Тест выше говорит, **допустим** ли разрез. Где его провести из нескольких
допустимых мест — отвечает шов.
**Шов — там, где падает ступень ревью.** Раздел «Затрагивает» перечисляет
границы; если одна строка перечня поднимает ступень выше остальных, эта часть и
режется отдельно. Пример: задача вводит новый пакет и заодно добавляет два поля в
существующий ответ. Целиком это `wide` — семь проходов по всему диффу. Разрезанная
по шву, она даёт `wide` на маленьком новом пакете и `standard` на остатке.
**Считай костяк, а не файлы.** У каждой задачи есть несокращаемые четыре прохода
(гейт, спеки, код, триаж), и они платятся за каждую. Разрез, после которого обе
половины остаются в одной ступени, делает ревью **дороже**: тот же объём
проверяется тем же составом, но костяк оплачен дважды. Отсюда правило: **резать,
когда разрез снимает дорогой проход с большей части диффа**, и не резать, когда
он просто делает файлы мельче.
**Это планирование, а не предписание процесса.** Ступень ревью выбирается по
факту изменения — тем, кто его видит, — и в тело задачи не пишется: строка
«делать профилем standard» это ровно тот второй дом правила выбора, который
гигиена полей снимает. Шов пользуется ступенью как **признаком**, что в задаче
две разнородные работы; решение о профиле остаётся за конвейером.
**Цель наследуется.** Все части несут `goal:` родителя: декомпозиция не меняет **Цель наследуется.** Все части несут `goal:` родителя: декомпозиция не меняет
того, чему работа служит. Если у части цель другая — это признак, что дробили не того, чему работа служит. Если у части цель другая — это признак, что дробили не
по той границе, либо что часть вообще из другой работы. по той границе, либо что часть вообще из другой работы.