доки: ADR о переработке конвейера ревью и обновление беклога
ADR фиксирует «почему»: recall чек-листа равен его длине, ценность верификатора определяется оракулом и декорреляцией с автором (а не числом ролей), отчёт без границ покрытия хуже отсутствия отчёта. В беклоге закрыт открытый вопрос «дробить ли review-code на узкие оптики» — не дробим; осталась калибровка проходов и ревьювер наименований. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# Конвейер ревью: гейт, generative-проходы и обязательный триаж
|
||||
|
||||
- Дата: 2026-07-23
|
||||
|
||||
## Контекст
|
||||
|
||||
Ревью изменений вели два сабагента (`jellybit-review-specs`,
|
||||
`jellybit-review-code`), вызываемые из `task-pipeline`. Оба устроены одинаково:
|
||||
получают дифф и применяют записанный чек-лист — конвенции, инварианты, пункты
|
||||
дельта-спеки. Инструменты им запускать было запрещено, детерминированные
|
||||
проверки (`lefthook`, `task test`/`task lint`) шли отдельно и **после**
|
||||
опиниативных проходов.
|
||||
|
||||
У такой конфигурации три ограничения, которые нельзя снять её же средствами.
|
||||
|
||||
**Recall чек-листа равен длине чек-листа.** Проход, устроенный как «проверь
|
||||
пункты 1..N», находит ровно перечисленное. Всё неявное — форма решения,
|
||||
идиоматичность, «так не делают» — неперечислимо по определению: то, что можно
|
||||
выписать, уже стало бы конвенцией. Удлинение списков не помогает, а вредит:
|
||||
внимание уходит на именование полей лога и не доходит до формы решения.
|
||||
|
||||
**Ценность верификатора определяется наличием внешнего оракула и декорреляцией
|
||||
с автором, а не числом ролей.** Разделение на «архитектура / конвенции / стиль»
|
||||
декоррелирует внимание, но не суждение: под всеми ролями одна модель с одними
|
||||
априорными, и код писала она же. Бюджет уходил на мнения при непокрытом уровне
|
||||
детерминированных инструментов (`-race`, покрытие изменённых строк, флаки,
|
||||
`govulncheck` не гонялись вовсе).
|
||||
|
||||
**Отчёт без границ покрытия хуже отсутствия отчёта.** «Замечаний нет»
|
||||
потребляло ощущение проверенности, ничего не гарантируя.
|
||||
|
||||
Дополнительно: сверка со спекой шла только в направлении spec → code, поэтому
|
||||
поведение, которое код имеет, а дельта не заказывала, не ловилось никем — а это
|
||||
системная болезнь агентского кода. Измерения качества ревью не существовало.
|
||||
|
||||
## Рассмотренные варианты
|
||||
|
||||
- **Дробить `jellybit-review-code` на узкие оптики** (архитектура / конвенции /
|
||||
стиль) — так стоял открытый вопрос в беклоге. Отвергнуто: добавляет роли, не
|
||||
добавляя ни оракула, ни декорреляции суждения; recall почти не растёт, а
|
||||
стоимость триажа растёт линейно.
|
||||
- **Удлинять чек-листы и конвенции** — прямо противоположно причине проблемы.
|
||||
- **Заменить конвейер CI-проверками** — покрывает только выразимое правилом;
|
||||
неявный слой остаётся непокрытым.
|
||||
|
||||
## Решение
|
||||
|
||||
Конвейер пересобран по типу проходов, а не по ролям, и оформлен скиллом
|
||||
`.claude/skills/review-pipeline`.
|
||||
|
||||
1. **Детерминированный гейт первым** (`task gate`): агент запускает инструменты
|
||||
и интерпретирует вывод, отличая новые отказы от унаследованных. Пока гейт
|
||||
красный, опиниативные проходы не запускаются. Гейт также выдаёт находки
|
||||
класса «отсутствующая верификация» — непокрытые изменённые строки,
|
||||
конкурентность без параллельного теста, флаки.
|
||||
2. **Сверка со спекой двунаправленная**, причём code → spec важнее: ищем
|
||||
поведение, которого дельта не заказывала, и классифицируем — дописать спеку
|
||||
или починить код. Проходу явно разрешено сомневаться в самом требовании.
|
||||
3. **Generative-проходы** как отдельный слой: рубрика до чтения кода,
|
||||
независимая реализация без подглядывания, заземление идиоматичности на
|
||||
stdlib и поимённые положения гайдов, негативное пространство. Только они
|
||||
достают то, чего нет ни в одном списке.
|
||||
4. **Обязательный триаж** с потолком 7 находок и разметкой `инлайн`/`развилка`.
|
||||
Отчёт читает оркестратор и молча реализует прочитанное, поэтому потолок
|
||||
защищает кодовую базу от незаказанных правок, а не внимание человека.
|
||||
5. **Храповик**: находка → конвенция → правило линтера → **удаление из прозы и
|
||||
промптов**. Третий шаг обязателен; в конвенциях остаётся только то, что
|
||||
правилом не выражается.
|
||||
6. **Измеримость**: журнал проскочивших дефектов и калибровка инъекцией с
|
||||
вердиктами `keep`/`retune`/`drop`. Проход, не находящий дефект своего класса
|
||||
в 2 из 3 прогонов после двух правок промпта, удаляется, а не правится дальше.
|
||||
|
||||
## Последствия
|
||||
|
||||
- `+` У ревью появился объективный оракул там, где он вообще возможен, и явная
|
||||
граница между «проверено», «не проверялось» и «недоступно в принципе».
|
||||
- `+` Неявный слой (форма решения, лишние абстракции, отсутствующее) стал
|
||||
предметом отдельных проходов, а не побочным эффектом чтения диффа.
|
||||
- `+` Механизируемое ушло в `.golangci.yml` и `internal/archrules`: конвенции и
|
||||
промпты разгружены, правило проверяется бесплатно и всегда.
|
||||
- `-` Профиль `deep` заметно дороже прежнего ревью по токенам и времени; отсюда
|
||||
профили и правило выбора по факту изменения.
|
||||
- `-` Generative-проходы шумят: без триажа они делают хуже, чем ничего.
|
||||
Триаж стал обязательным элементом, а не опцией.
|
||||
- `-` Набор проходов теперь нужно **измерять**, иначе он вырождается в театр.
|
||||
Журнал заполняется по горячим следам, ретроспективные записи бесполезны.
|
||||
- Как следствие: калибровку проходов надо провести на реальных пробах —
|
||||
процедура заведена, первые прогоны за владельцем.
|
||||
Reference in New Issue
Block a user