ступень ревью поднимает проход, а не риск
Полный набор гонялся чаще, чем оправдано, и размер задач тут вторая причина, не первая. Первая — триггеры: миграция схемы, публичный контракт и инвариант поднимали ступень, не добавляя ни одного прохода. Миграцию гоняет 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:
@@ -129,7 +129,7 @@ charter'а, а модель потом двигает калибровка, и
|
||||
- `triage` — через него проходит всё, что оркестратор реализует **молча**:
|
||||
ложноположительная находка становится кодом, потерянный `critical` — дефектом.
|
||||
Ошибка триажа дороже ошибки любого отдельного прохода.
|
||||
- `architecture` — запускается не на каждой задаче (`wide`, `deep` и `design`),
|
||||
- `architecture` — запускается только там, где изменение вводит новое понятие,
|
||||
потолок в 3 находки делает его дешёвым по выходу, а находка на предложении
|
||||
стоит абзаца против переписывания на готовом коде. Дёшево × высокое плечо.
|
||||
|
||||
@@ -154,10 +154,10 @@ charter'а, а модель потом двигает калибровка, и
|
||||
| Профиль | Когда | Стадии | Проходов |
|
||||
|---|---|---|---|
|
||||
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 |
|
||||
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 | 6 |
|
||||
| `wide` | новый пакет, изменение публичного контракта, миграция схемы, трогает инварианты проекта | 0, 1, 2, 4, 5 | 7 |
|
||||
| `standard` | **рабочее умолчание**: поведение, миграция схемы, публичный контракт, инвариант | 0, 1, 2, 5 | 6 |
|
||||
| `wide` | изменение вводит новое понятие или структурную единицу | 0, 1, 2, 4, 5 | 7 |
|
||||
| `deep` | изменение вводит новое правило идентичности, слияния или разбора | 0, 1, 2, 3, 4, 5 | 8 |
|
||||
| `design` | **до кода**, на предложении | specs + rubric + architecture (см. ниже) | 3 |
|
||||
| `design` | **до кода**, на предложении | specs, плюс rubric и architecture по условию `wide` | 1–3 |
|
||||
|
||||
**`wide` назван по тому, что он добавляет: вход шире диффа.** Единственное его
|
||||
отличие от `standard` — архитектурный проход, а тот и получает дерево пакетов,
|
||||
@@ -179,22 +179,60 @@ charter'а, а модель потом двигает калибровка, и
|
||||
|
||||
- трогается правило, определяющее **идентичность, слияние или разбор** данных →
|
||||
`deep`;
|
||||
- иначе есть миграция схемы, новый пакет, изменение публичного контракта (API,
|
||||
протокол, формат на диске) или затронут инвариант проекта → `wide`;
|
||||
- иначе меняется поведение, видимое снаружи (эндпоинт, форма ответа, код ответа,
|
||||
формат лога) → `standard`;
|
||||
- иначе изменение вводит **новое понятие или структурную единицу**: новый пакет
|
||||
или слой, новая точка входа, второй способ делать то, что уже делается, перенос
|
||||
ответственности между узлами → `wide`;
|
||||
- иначе меняется поведение, видимое снаружи, трогается схема, публичный контракт
|
||||
или инвариант проекта → `standard`;
|
||||
- иначе → `quick`.
|
||||
|
||||
**Ступень поднимает то, что даёт работу новому проходу, а не то, что кажется
|
||||
рискованным.** Это правило вывода, по которому спорные случаи решаются без нового
|
||||
списка: спроси, какому проходу изменение даёт работу, которой у него не было
|
||||
ступенью ниже.
|
||||
|
||||
Оно же объясняет, почему миграция схемы и публичный контракт **не** поднимают
|
||||
ступень, хотя выглядят опаснее прочего. Они не добавляют ни одного прохода:
|
||||
миграцию гоняет `gate` шагом миграций и разбирает `ops` («миграция под живым
|
||||
потоком», «частичный откат при двух версиях»), контракт сверяет `specs`
|
||||
направлением `code → spec`, инвариант даёт основание для `critical` любому
|
||||
проходу. Все трое уже в `standard`. Раньше эти три факта стояли триггерами
|
||||
верхних ступеней, и на проекте с базой и эндпоинтами верхняя ступень оказывалась
|
||||
не исключением, а умолчанием — то есть правило объявляло исключением то, что
|
||||
происходит всегда. `architecture` же получает работу **не** от того, что контракт
|
||||
изменился, а от того, что появилось новое понятие: добавленное поле в
|
||||
существующем ответе — не концепт.
|
||||
|
||||
**Верхняя ступень и есть триггер независимой реализации** — раньше он был
|
||||
условием *внутри* `deep`, и профиль от этого распадался на два разных прогона под
|
||||
одним именем. Условие никуда не делось, оно просто переехало туда, где выбирается
|
||||
профиль: изменение с новым правилом слияния — единственный случай, когда триаж
|
||||
называл отсутствие `reimpl` дырой покрытия.
|
||||
|
||||
Что именно в этом проекте считается публичным контрактом, какие пути означают
|
||||
`wide` и что здесь считается правилом идентичности, проект может уточнить в
|
||||
`docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не отмена: не
|
||||
записано — работает список выше.
|
||||
Что здесь считается новым понятием и что — правилом идентичности, проект может
|
||||
уточнить в `docs/review.md`, разделе настройки конвейера. Это **уточнение**, а не
|
||||
отмена: не записано — работает список выше. Проект, где изменение контракта и
|
||||
правда архитектурное (публичный SDK, чужие потребители), там же поднимает его до
|
||||
`wide` — и это уточнение, а не возврат прежнего умолчания.
|
||||
|
||||
### Профиль — максимум по поверхности, и отсюда размер задачи
|
||||
|
||||
Условия читаются сверху вниз, и **первое подошедшее отвечает за весь дифф**.
|
||||
Профиль изменения это максимум по его поверхности, а не средневзвешенное: одна
|
||||
строка в перечне границ задачи поднимает ступень всему остальному, включая ту
|
||||
часть, которая сама по себе была бы `quick`.
|
||||
|
||||
Отсюда следствие, которое дороже любой настройки триггеров: **цена ревью растёт
|
||||
быстрее размера задачи.** Крупная задача не просто даёт больше диффа — она с
|
||||
высокой вероятностью зацепит верхнее условие и оплатит верхний профиль целиком.
|
||||
|
||||
Обратное тоже верно и тоже не бесплатно: у каждой задачи есть **несокращаемый
|
||||
костяк из четырёх проходов** (гейт, спеки, код, триаж). Разрезать задачу, обе
|
||||
половины которой остаются в одном профиле, — значит заплатить костяк дважды за ту
|
||||
же проверку. Резать стоит там, где разрез **снимает дорогой проход с большей
|
||||
части диффа**. Шов и правило нарезки живут у того, кто ведёт задачи, — скилл
|
||||
`av-dev-pm:tasks`, его `references/split.md`. Пути туда конвейер не выносит: за
|
||||
пределы своего плагина он ходит вызовом скилла, а не файлом.
|
||||
|
||||
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно
|
||||
попадает в границы покрытия строкой «профиль понижен до X, потому что …».
|
||||
@@ -440,6 +478,14 @@ Recall обоих равен длине их источника — это и е
|
||||
профиля. Машину не держит, с `reimpl` конфликта не имеет: за барьером они уходят
|
||||
разом.
|
||||
|
||||
**Условие этой стадии и есть условие ступени `wide`:** изменение вводит новое
|
||||
понятие или структурную единицу. Не «изменение крупное» и не «изменение опасное»:
|
||||
у прохода появляется работа ровно тогда, когда в проекте становится больше
|
||||
сущностей, чем было, — и тогда осмысленны оба его вопроса. На изменении, которое
|
||||
ничего не вводит, вопрос «не появился ли второй способ» отвечается «нет» до
|
||||
запуска, а вопрос «что опытный человек отсюда удалил бы» вырождается во
|
||||
вкусовщину, которую потом отсеивает триаж.
|
||||
|
||||
Получает **вход шире диффа**: дерево пакетов с
|
||||
назначением, граф внутренних зависимостей, инвентарь существующих концепций.
|
||||
Команду, которая это готовит, даёт раздел команд `CLAUDE.md`; нет команды —
|
||||
@@ -477,36 +523,51 @@ Recall обоих равен длине их источника — это и е
|
||||
|
||||
Запускается на шаге ревью спек (шаг 4 скилла `av-dev-pipeline:task-pipeline`),
|
||||
когда change уже
|
||||
имеет `proposal.md` и дельта-спеки, но кода ещё нет. Состав:
|
||||
имеет `proposal.md` и дельта-спеки, но кода ещё нет.
|
||||
|
||||
1. `review-specs` в режиме «дизайн ДО кода»;
|
||||
2. `review-rubric`, фаза 1 без фазы 2: рубрика на задуманный узел становится
|
||||
приёмочными критериями и уезжает в `tasks.md`;
|
||||
3. `review-architecture` на предложении: вводит ли change новое понятие, можно ли
|
||||
выразить существующими — **включая конструкции стандартной библиотеки**, — не
|
||||
появляется ли второй способ. Вопрос «не изобретаем ли то, что уже есть в
|
||||
библиотеке» живёт здесь;
|
||||
4. вопрос автору дизайна: **«предложи три формы решения и назови компромисс
|
||||
каждой»** — если ответ показывает, что рассматривалась одна, это находка.
|
||||
**Состав здесь тоже не постоянный, и условие то же самое, что у `wide`:**
|
||||
изменение вводит новое понятие или структурную единицу.
|
||||
|
||||
- **всегда** — `review-specs` в режиме «дизайн ДО кода». Дельта-спеки сверяются
|
||||
на каждой задаче: это самый дешёвый чекпоинт конвейера, и он ловит то, что на
|
||||
готовом коде уже не чинят;
|
||||
- **при новом понятии** — плюс `review-rubric` (фаза 1 без фазы 2: рубрика на
|
||||
задуманный узел становится приёмочными критериями и уезжает в `tasks.md`) и
|
||||
`review-architecture` на предложении: можно ли выразить существующими понятиями
|
||||
— **включая конструкции стандартной библиотеки**, — не появляется ли второй
|
||||
способ. Вопрос «не изобретаем ли то, что уже есть в библиотеке» живёт здесь;
|
||||
тогда же задаётся вопрос автору дизайна: **«предложи три формы решения и назови
|
||||
компромисс каждой»** — если ответ показывает, что рассматривалась одна, это
|
||||
находка.
|
||||
|
||||
Причина условия — арифметика, а не экономия на осторожности. Чекпоинт стоит
|
||||
**на каждой задаче**, поэтому три прохода здесь умножаются на число задач, и при
|
||||
мелкой нарезке это самая большая статья конвейера. Рубрика же на узел, который не
|
||||
вводит нового понятия, порождает свойства уже существующего рода — те, что и так
|
||||
записаны конвенциями и спеками; а `architecture` без нового понятия отвечает «нет»
|
||||
на свой главный вопрос ещё до запуска (см. «Стадия 4»).
|
||||
|
||||
**Граф этого профиля свой, и он плоский.** Гейта нет — кода ещё нет, запускать
|
||||
нечего; машину не держит ни один из трёх; сток — не триаж, а шаг 5 пайплайна
|
||||
нечего; машину не держит ни один проход; сток — не триаж, а шаг 5 пайплайна
|
||||
задачи, где замечания отрабатываются правкой спек. Триаж здесь не нужен: находок
|
||||
единицы, и каждая либо правит спеку, либо становится развилкой.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
proposal["предложение: proposal.md + дельта-спеки"]
|
||||
specs["specs (режим «дизайн ДО кода»)"]
|
||||
specs["specs (режим «дизайн ДО кода») — всегда"]
|
||||
novelty{{"вводит новое понятие<br/>или структурную единицу?"}}
|
||||
rubric["rubric, фаза 1 → приёмочные критерии в tasks.md"]
|
||||
arch["architecture на предложении"]
|
||||
author["вопрос автору: три формы решения и компромисс каждой"]
|
||||
fix["шаг 5 пайплайна: правка спек, развилки — вопросом в запись"]
|
||||
|
||||
proposal --> specs
|
||||
proposal --> rubric
|
||||
proposal --> arch
|
||||
proposal --> author
|
||||
proposal --> novelty
|
||||
novelty -->|да| rubric
|
||||
novelty -->|да| arch
|
||||
novelty -->|да| author
|
||||
novelty -->|нет| fix
|
||||
specs --> fix
|
||||
rubric --> fix
|
||||
arch --> fix
|
||||
|
||||
@@ -219,14 +219,19 @@ flowchart TD
|
||||
### 4. (Нетривиальная) Ревью предложения — профиль `design`, ДО кода
|
||||
|
||||
Первый чекпоинт. Вызови Skill **`av-dev-pipeline:review-pipeline`** с профилем
|
||||
`design` и ссылкой на change `<id>`. Он запустит `review-specs`
|
||||
(режим «дизайн ДО кода»), `review-rubric` (фаза 1: приёмочные критерии для
|
||||
задуманного узла) и `review-architecture` по предложению.
|
||||
`design` и ссылкой на change `<id>`.
|
||||
|
||||
**Состав чекпоинта решает конвейер, а не ты**: `review-specs` в режиме «дизайн ДО
|
||||
кода» идёт всегда, а `review-rubric` и `review-architecture` — только когда
|
||||
изменение вводит новое понятие или структурную единицу (то же условие, что у
|
||||
ступени `wide`). Причина в том, что чекпоинт стоит на **каждой** задаче: при
|
||||
мелкой нарезке три прохода здесь умножаются на число задач и становятся самой
|
||||
большой статьёй конвейера.
|
||||
|
||||
Смысл профиля: архитектурная находка на готовом коде стоит переписывания и
|
||||
потому игнорируется — та же находка здесь стоит абзаца обсуждения. Рубрику из
|
||||
`review-rubric` перенеси в `tasks.md` как приёмочные критерии; там же уже лежат
|
||||
критерии от постановки, если они были.
|
||||
потому игнорируется — та же находка здесь стоит абзаца обсуждения. Если
|
||||
`review-rubric` запускался, перенеси его рубрику в `tasks.md` как приёмочные
|
||||
критерии; там же уже лежат критерии от постановки, если они были.
|
||||
|
||||
### 5. Отработать замечания ревью предложения
|
||||
|
||||
|
||||
Reference in New Issue
Block a user