Files
avandClaude Opus 5 bd1ea6d6b1 старшинство диаграмм объявлено, рендер проверяется скриптом
Диаграмма и проза вокруг неё описывают один факт — это второй дом, и
разойтись они могут молча: то самое, против чего написан copies.py.
Механической сверки здесь нет, дословного соответствия между текстом и
графом не существует, поэтому работает объявление. В review-pipeline
старший граф — он и есть алгоритм планировщика, проза объясняет рёбра;
в остальных местах старшая проза, диаграмма там сводка; в calibration.md
старшая таблица вердиктов, схема добавляет к ней только счётчик.

Объявление стоит у каждой диаграммы строкой в месте, а не общим правилом
в README: скилл читают целиком, README — нет. В task-batch добавлена
оговорка про соседний скилл — два вызова с разным старшинством рядом это
место, где легко ошибиться.

scripts/diagrams.py вынимает все mermaid-блоки и рендерит каждый через
mmdc или npx @mermaid-js/mermaid-cli. Коды выхода — общий словарь; нет
рендерера — код 3, а не молчаливый успех. Chromium с --no-sandbox:
без флага падает на «No usable sandbox», причина в докстроке. Проверены
обе ветки: 11 диаграмм в 9 файлах зелено, сломанный блок даёт точное
место с текстом ошибки парсера и код 1.

README: раздел «Проверка диаграмм» рядом с проверкой копий — что ловит,
чего не ловит и почему не в гейте. DECISIONS 63 и 64.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 20:41:42 +03:00

106 lines
8.7 KiB
Markdown
Raw Permalink 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-reimpl` | форма решения | размазать решение по трём слоям там, где хватало одной функции |
| `review-architecture` | второй способ | завести вторую точку генерации id мимо единой |
| `review-adversary` | построенный путь | принять внешний идентификатор без разбора до запроса в хранилище |
| `review-ops` | деградация окружения | убрать обработку недоступности внешней зависимости в фоновом цикле |
| `review-triage` | шум | подать 20 находок, из них 15 вкусовщина и 3 дубля — проверить потолок и дедуп |
Метрик сверх этого не заводим. Precision, корреляция между проходами, стоимость
прогона в токенах — всё это красиво звучит и никем не считается вручную; набор
показателей, который не собирают, создаёт впечатление измеряемости и тем вреден.
Работает ровно один механизм: инъекция дефекта и вердикт. Если корреляция двух
проходов действительно бросается в глаза — это видно по полю `Найдено проходом`
в триажированных отчётах и без отдельной метрики.
## Когда калибровать
- при заведении нового прохода — **до** включения в профиль по умолчанию;
- при правке charter'а существующего — иначе непонятно, правка помогла или нет;
- при появлении записи в журнале проскочивших дефектов — калибруем тот проход,
который должен был поймать;
- планово — нет. Календарная калибровка ради галочки сама превращается в театр.