Files
dev-skills/av-dev-pipeline/skills/review-pipeline/references/calibration.md
T
avandClaude Opus 5 21b840a8e4 профили ревью: тяжёлые проходы в верхнюю ступень, на умолчании — один базовый
Тема 33 сняла самую большую разовую статью расхода, но не тронула главную —
частоту. Меряющая пара стояла в standard, то есть на большинстве задач, и именно
она делала прогон долгим: два прохода держат машину, идут цепочкой и доказывают
находки запуском. Цель разбора названа прямо: лучше поправить в следующей задаче,
чем держать одну два часа.

adversary и ops переехали в wide. Стадия осталась самой урожайной за всю историю
замеров — пять из семи выживших находок дозапуска и единственная находка про
молчаливый старт отката, — но её ценность оплачивается на каждой задаче, а
получается на немногих. Решение по цене, не по ценности.

Заведён review-basics: мелкая осадка двух тяжёлых проходов, без единого запуска.
Стоит только в standard. Восемь вопросов, на которые отвечают чтением: таймаут и
отказ соседа, идемпотентность и одновременная запись, остановка на середине,
частичный откат при двух версиях, наблюдаемость и тишина, очевидный рост объёма,
второй способ мимо единой точки (грепом, не картой), что отсюда удалить. Потолок
4 находки, машину не держит, ничего не меряет.

Вопрос про частичный откат — не для полноты списка. Без него правило «миграция
схемы не поднимает ступень» рассыпалось бы: раньше миграцию разбирал ops, а он
теперь наверху. Проход заведён затем, чтобы у standard остался хоть один взгляд
на ось времени.

Модель у него верхняя, opus, и это не спорит со словом «средний»: усилие режется
входом и потолком, а не моделью. Дешёвая модель на опиниативном проходе платит
триажем — это записанный замер, отменять его без нового замера нечем.

Лестница вышла 4/5/7. Главный выигрыш не в числе проходов, а в том, что из
standard ушла цепочка: теперь там гейт, три прохода одним сообщением и триаж —
граф плоский, ждать некому.

Правило выбора ступени переписано на два вопроса, и объём изменения вошёл в него
впервые. Крупное или незнакомое — трогает несколько узлов, переносит
ответственность, форму решения нащупывают по ходу — это wide, и он рассчитан на
5-10% задач. Мелкое — один узел, форма очевидна заранее, откат сводится к
обратной правке — quick. Всё остальное standard, рабочее умолчание. Раньше
ступень выбиралась только по классу изменения и на размер смотреть запрещала;
теперь признаков два: класс отвечает за обратимость, объём — за цену
разбирательства.

Отрицательный тест сохранил прежнюю мудрость в новой рамке: что после мерджа не
откатывается обратной правкой — не quick, каким бы маленьким ни был дифф. Три
строки миграции идут в standard.

Спорный случай решается вниз, и асимметрия объяснена ценой: ошибка в сторону
standard стоит находки на следующей задаче, ошибка в обратную — трёх тяжёлых
проходов на каждой задаче, выбранной неверно.

Сделка записана вместе с обратной связью, иначе это тихая потеря качества. На
quick и standard не проверяется ничего, что требует запуска: построенный путь,
эксперимент против драйвера, любое число. Это самая крупная граница покрытия
конвейера, и она идёт строкой в каждом таком прогоне поимённо. Сигналов о том,
что ступень занижена, два: журнал дефектов в docs/review.md и сам basics —
он единственный, кто смотрит на дифф целиком на нижних ступенях, и обязан
сказать строкой, если задача выглядит крупнее профиля.

Побочно: условие профиля design то же самое, так что rubric и architecture на
предложении тоже упали до 5-10% задач.

Тема 34 в DECISIONS.md, следствия 130-133. Версия канона не поднята; инструкция
проекту дописана в пункт 8 записи «Версия 4».

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 19:29:07 +03:00

106 lines
8.8 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.
# Калибровка проходов
Без измерения набор проходов растёт монотонно и вырождается в театр: каждый
кажется полезным, потому что иногда что-то говорит. Калибровка отвечает на
единственный вопрос — **ловит ли проход дефект своего класса**.
## Процедура (инъекция дефекта)
1. Взять **реальный коммит** из истории (`git log --oneline`), лучше
архивированный change с непустым диффом.
2. Внести в него **один** дефект того класса, который проход обязан ловить по
своему charter'у. Дефект должен быть правдоподобным — таким, какой реально
пишет модель, а не карикатурой (`panic("TODO")` не считается).
3. Прогнать **только этот проход** на подготовленном диффе — **три раза**,
каждый в чистом контексте.
4. Зафиксировать: нашёл `n/3`, число находок всего, число ложных.
5. Вердикт:
| Результат | Вердикт | Что делаем |
|---|---|---|
| нашёл 3/3 или 2/3, ложных немного | `keep` | ничего |
| нашёл 1/3 или 0/3 | `retune` | правим charter — сужаем вход, убираем чек-лист, добавляем оракул |
| `retune` уже был дважды подряд | `drop` | удаляем проход |
| находит, но ложных больше трети от всех находок | `retune` | триаж съедает больше, чем экономит проход |
Вердикты образуют храповик со счётчиком — его-то таблица и не показывает:
```mermaid
stateDiagram-v2
state "проход в профиле" as live
state "retune №1 — правка charter'а" as r1
state "retune №2 — последняя попытка" as r2
state "проход удалён" as dead
[*] --> live: заведён и откалиброван ДО включения
live --> r1: 1/3, 0/3 или ложных больше трети
r1 --> live: замер keep — счётчик сброшен
r1 --> r2: снова не ловит
r2 --> live: замер keep — счётчик сброшен
r2 --> dead: снова не ловит — это театр
```
Схема — **сводка** к таблице вердиктов выше: она добавляет только счётчик, и при
расхождении прав таблица.
**`retune` не более двух раз подряд.** Проход, не находящий дефект своего класса
в 2 из 3 прогонов после двух правок промпта, — это театр. Удалять, а не
бесконечно править формулировки: каждая итерация правки промпта стоит дороже,
чем отсутствие прохода.
**Существующий проход не удаляется без замера.** Сначала калибровка, потом
решение — иначе удаляется то, что работало, а остаётся то, что громче. Обратный
пример уже был: проход про идиоматичность стоял в списке на удаление как
«вкусовщина», а замер показал, что он зарабатывает **экспериментами против
поведения библиотеки и драйвера**, — и находка, воспроизведённая числом, отменила
решение, принятое по ощущению.
## Состав проходов принадлежит плагину, а не проекту
Проходы общие. Проект не может удалить проход — он может **не звать** его, и
тогда это идёт строкой «не запускался» в границы покрытия, как любой другой
пропуск. Молча сузить состав нельзя: пропуск прохода не отличим от прохода без
находок.
Отсюда два следствия:
- **правка charter'а — правка для всех проектов.** Прежде чем сужать
формулировку под свою боль, проверь, не место ли ей в документах проекта: предмет проверки
живёт там, метод — в charter'е;
- **удаление прохода из плагина требует замера на двух проектах**, а не на одном:
класс, не всплывший здесь, мог быть единственным работающим там.
## Пробы дефектов по проходам
Проба — заготовка инъекции. Список пополняется из журнала проскочивших дефектов
(см. [review-journal.md](review-journal.md)): реальный проскочивший дефект —
лучшая проба, какая вообще возможна, потому что синтетические смещены в сторону
тех, которые уже умеешь придумывать.
| Проход | Класс дефекта для инъекции | Заготовка пробы |
|---|---|---|
| `review-gate` | отсутствующая верификация | убрать тест на изменённую ветку, оставить код рабочим |
| `review-specs` | поведение вне спеки | добавить незаказанный фолбэк-дефолт на пустом входе |
| `review-code` | нарушение прозаической конвенции | увести штатный отказ мимо единой точки трансляции ошибки |
| `review-rubric` | нарушенное свойство узла | у клиента внешнего сервиса убрать таймаут и протяжку `context` |
| `review-basics` | отказ, видимый чтением | убрать обработку ошибки записи так, чтобы отказ считался успехом |
| `review-architecture` | второй способ | завести вторую точку генерации id мимо единой |
| `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище |
| `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле |
| `review-triage` | шум | подать 20 находок, из них 15 вкусовщина и 3 дубля — проверить потолок и дедуп |
Метрик сверх этого не заводим. Precision, корреляция между проходами, стоимость
прогона в токенах — всё это красиво звучит и никем не считается вручную; набор
показателей, который не собирают, создаёт впечатление измеряемости и тем вреден.
Работает ровно один механизм: инъекция дефекта и вердикт. Если корреляция двух
проходов действительно бросается в глаза — это видно по полю `Найдено проходом`
в триажированных отчётах и без отдельной метрики.
## Когда калибровать
- при заведении нового прохода — **до** включения в профиль по умолчанию;
- при правке charter'а существующего — иначе непонятно, правка помогла или нет;
- при появлении записи в журнале проскочивших дефектов — калибруем тот проход,
который должен был поймать;
- планово — нет. Календарная калибровка ради галочки сама превращается в театр.