ревью: конвейер сужен с 11 проходов до 6–9

- negative удалён, два его живых вопроса переселены в ops и architecture
- rubric остаётся только в профиле design, reimpl — по триггеру
  «новое правило слияния, идентичности или разбора»
- adversary и ops переехали из deep-только в standard: профиль, которым
  закрывается большинство задач, гонял четыре самых слабых прохода и не
  гонял двух, принёсших почти все находки сессии
- idiom оставлен вопреки первоначальной оценке: он зарабатывает
  экспериментами против stdlib и драйвера, а не цитатами из гайдов
- основания и цена решения — в docs/review-journal.md
This commit is contained in:
av
2026-08-02 20:48:35 +03:00
parent 8db2ec7ff4
commit 33cf1b7bae
8 changed files with 146 additions and 177 deletions
@@ -1,6 +1,6 @@
---
name: healthlog-review-pipeline
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, generative-проходы (рубрика, независимая реализация, stdlib grounding, negative space), архитектура, враждебные постановки и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, generative-проходы (stdlib grounding, независимая реализация по триггеру), архитектура и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
---
# Конвейер ревью (healthlog)
@@ -57,7 +57,7 @@ description: Конвейер ревью изменений healthlog — дет
| Модель | Проходы | Почему |
|---|---|---|
| `sonnet` | gate, code, ops | вход структурный, критерий записан заранее |
| `opus` | specs, idiom, negative, adversary, rubric, reimpl | суждение без опоры на инструмент |
| `opus` | specs, idiom, adversary, rubric, reimpl | суждение без опоры на инструмент |
| `fable` | triage, architecture | ошибка распространяется дальше самой находки |
**Fable — только двум проходам, и это калибровка, а не осторожность.** Первый
@@ -96,17 +96,27 @@ description: Конвейер ревью изменений healthlog — дет
дефектом. Ошибка триажа дороже ошибки любого отдельного прохода.
Экономия при этом достигается не понижением модели, а **непуском прохода**:
`quick`три стадии, `deep`одиннадцать. Правило выбора профиля ниже и есть
`quick`четыре прохода, `deep`восемь. Правило выбора профиля ниже и есть
главный рычаг стоимости.
## Профили
| Профиль | Когда | Стадии |
|---|---|---|
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 |
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 |
| `deep` | новый пакет, изменение публичного контракта, миграция БД, трогает инварианты выше | 0, 1, 2, 3, 4, 5 |
| `design` | **до кода**, на OpenSpec-предложении | rubric + idiom + architecture (см. ниже) |
| Профиль | Когда | Стадии | Проходов |
|---|---|---|---|
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 |
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 | 6 |
| `deep` | новый пакет, изменение публичного контракта, миграция БД, трогает инварианты выше | 0, 1, 2, 3, 4, 5 | 89 |
| `design` | **до кода**, на OpenSpec-предложении | specs + rubric + idiom + architecture (см. ниже) | 4 |
**Состав сверяется по этой таблице до коммита.** Реестр из шести-девяти
пунктов проверяется взглядом — и это единственная защита от промаха, который
уже случился: пропуск прохода **не отличим от прохода без находок** (гейт
зелёный, спеки сошлись, отчёт выглядит полным), а заметить его мог бы только
триаж, который сам заполняется тем, что ему подали. Отчёт обязан перечислять
запущенные проходы **поимённо и с исходом**; непущенный идёт строкой «не
запускался» в границы покрытия, а не отсутствует. Цена молчащего пропуска
измерена: семь находок и отдельная задача на их дозакрытие
(`docs/review-journal.md`, 2026-08-02).
Правило выбора — по факту изменения, не по ощущению важности:
@@ -160,21 +170,50 @@ description: Конвейер ревью изменений healthlog — дет
Recall обоих равен длине их источника — это и есть предел applicative-проходов,
ради которого существует стадия 2.
## Стадия 2 — Tacit layer (generative; `standard`, `deep`)
## Стадия 2 — Adversarial и operational (`standard`, `deep`)
Четыре прохода, каждый в своём контексте, запускаются **одним сообщением
параллельно**:
Два прохода, запускаются **одним сообщением параллельно**:
- `healthlog-review-adversary` — находка есть **построенный путь**, а не
свойство;
- `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке
кода.
**Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в
`standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход
дал пять из семи выживших находок дозапуска на `f8200f7` (включая обе верхние) и
`critical` на каталоге (доставка с метками из будущего подменяла род метрики);
эксплуатационный — единственный, кто нашёл, что откат бинаря поверх новой схемы
стартует молча. Оба несут внешний оракул по построению: один обязан путь
**прогнать**, второй смотрит ось времени и эксплуатации, которую не смотрит
никто другой.
Для healthlog эксплуатационный проход обязан держать в голове: телефон шлёт
непрерывно и молча, тела доходили до 42 МБ, запись в часовой объект —
read-modify-write под конкурентными доставками, а тихо сломавшаяся
автоматизация обнаруживается не сразу. Отдельным обязательным вопросом —
**хватит ли сигналов владельцу, когда поток оборвётся ночью**: не «есть ли
лог», а увидит ли человек факт, не залезая в SQLite.
## Стадия 3 — Tacit layer (generative; `deep`)
- `healthlog-review-rubric` — порождает рубрику до чтения кода, потом судит по ней;
- `healthlog-review-reimpl` — пишет свою реализацию, не открывая существующую,
затем диффит по решениям (в профиле `standard` включается только если
изменение содержит новый файл или функцию длиннее ~60 строк — иначе дорог и
бесполезен);
- `healthlog-review-idiom` — заземляет «идиоматичность» на stdlib и поимённые
положения гайдов;
- `healthlog-review-negative` — чего нет и что лишнее.
положения гайдов. Зарабатывает он не цитатами, а **экспериментами против
поведения stdlib и драйвера**, и это его настоящая форма: три эксперимента на
дизайне `razbor-metrik-v-obekty` (`SQLITE_BUSY_SNAPSHOT` против
`_txlock=immediate`, куча `map[string]any` против `json.RawMessage`, потери
`json.Marshal` без `UseNumber`) и находка на чекпойнте WAL, где `-1 >= -1`
читалось как «журнал разобран целиком» — воспроизведено, 1492 тика из 5502.
- `healthlog-review-reimpl` — пишет свою реализацию, не открывая существующую,
затем диффит по решениям. **Запускается по триггеру, а не всегда:** изменение
вводит новое правило слияния, идентичности или разбора. Это самый дорогой
проход конвейера (его счёт определяется объёмом вывода — он пишет реализацию
целиком), а вне этого триггера независимый взгляд в значительной мере уже дал
профиль `design`: код писался под его находки. Триггер выбран по факту:
единственный раз, когда триаж назвал отсутствие `reimpl` дырой покрытия, —
это была задача с новым правилом слияния сущностей.
## Стадия 3 — Global (`deep`, `design`)
## Стадия 4 — Global (`deep`, `design`)
Агент `healthlog-review-architecture`. Получает **вход шире диффа**: дерево
пакетов с назначением, граф внутренних зависимостей, инвентарь существующих
@@ -185,25 +224,19 @@ task review:context > tmp/review-context.md
```
Главный вопрос — концептуальная целостность и **второй способ** делать то, что
уже делается. Потолок — 3 находки плюс секция «дешевле переделать до мерджа».
## Стадия 4 — Adversarial и operational (`deep`)
`healthlog-review-adversary`аходка = построенный путь, не свойство) и
`healthlog-review-ops` (постмортем от симптома у владельца сервиса к строке).
Запускаются параллельно со стадией 2, если профиль `deep`.
Для healthlog эксплуатационный проход обязан держать в голове: телефон шлёт
непрерывно и молча, тела доходили до 42 МБ, запись в часовой объект —
read-modify-write под конкурентными доставками, а тихо сломавшаяся
автоматизация обнаруживается не сразу.
уже делается. Он же и оправдывает проход: на задаче про пересборку архитектурный
проход нашёл, что прогон живого архива был **вторым проигрывателем журнала** со
своим порядком. Второй обязательный вопрос — **что опытный человек отсюда
удалил бы**: слой с единственной реализацией, интерфейс ради мока, незапрошенная
конфигурируемость, подстраховка поверх подстраховки. Потолок — 3 находки плюс
секция «дешевле переделать до мерджа».
## Стадия 5 — Triage (обязательна)
Агент `healthlog-review-triage`. Единственный, кто агрегирует. Получает сырые
выводы всех проходов и `git diff`; возвращает финальный отчёт.
Без триажа шесть проходов дают порядка сорока замечаний при единицах
Без триажа проходы дают порядка сорока замечаний при единицах
существенных. Потребитель здесь — оркестратор, который **молча реализует** всё,
что прочитал: цена нетриажированного отчёта — не потерянное время человека, а
разросшийся от вкусовщины код.
@@ -164,6 +164,14 @@ healthlog — хранилище данных о здоровье, у котор
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
покрытия.
**Сверь состав прогона с таблицей профилей в скилле, прежде чем коммитить.**
Пропуск прохода не отличим от прохода без находок: гейт зелёный, спеки сошлись,
отчёт выглядит полным. Единственный, кто мог бы заметить пропуск, — триаж, а он
заполняется тем, что ему подали. Отчёт обязан называть запущенные проходы
**поимённо и с исходом**; непущенный идёт строкой «не запускался» в границы
покрытия. Реестр короткий (6–9 проходов) — сверка стоит одного взгляда, а
молчащий пропуск уже стоил семи находок и отдельной задачи на их дозакрытие.
Отработай так же, как шаг 5: помеченное `инлайн` чини сам и не логируй,
`развилка` — блокером в беклог (вопрос уже сформулирован триажем, его остаётся
перенести). После правок — снова `task gate`.