ревью: добавлен последовательный режим запуска проходов
- профиль отвечает «какие проходы», режим — «как их запускать» - явная просьба владельца — достаточное основание, без обоснований и переспрашивания; перекрывает эвристики в обе стороны - главный собственный повод — ожидаемые замеры: adversary и ops меряют одно железо (блокировка SQLite, куча, рост -wal) и портят числа друг другу, а находка с испорченным оракулом дороже сэкономленных минут - декорреляция не меняется ни в каком режиме: проход не видит чужих находок, «последовательно» ≠ «читает предыдущего» - ранний выход только при переделке формы изменения, с перезапуском с нулевой стадии; триаж — только на полном прогоне
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: healthlog-review-pipeline
|
name: healthlog-review-pipeline
|
||||||
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
|
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Проходы гонятся параллельно или последовательно (второе — когда ожидаются замеры или занята машина). Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Конвейер ревью (healthlog)
|
# Конвейер ревью (healthlog)
|
||||||
@@ -119,7 +119,7 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
измерена: семь находок и отдельная задача на их дозакрытие
|
измерена: семь находок и отдельная задача на их дозакрытие
|
||||||
(`docs/review-journal.md`, 2026-08-02).
|
(`docs/review-journal.md`, 2026-08-02).
|
||||||
|
|
||||||
Правило выбора — по факту изменения, не по ощущению важности:
|
Правило выбора профиля — по факту изменения, не по ощущению важности:
|
||||||
|
|
||||||
- есть миграция в `internal/store/migrations/`, новый пакет `internal/*`,
|
- есть миграция в `internal/store/migrations/`, новый пакет `internal/*`,
|
||||||
изменение контракта Read API или MCP, трогается правило слияния точек или
|
изменение контракта Read API или MCP, трогается правило слияния точек или
|
||||||
@@ -131,6 +131,69 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно
|
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно
|
||||||
попадает в границы покрытия строкой «профиль понижен до X, потому что …».
|
попадает в границы покрытия строкой «профиль понижен до X, потому что …».
|
||||||
|
|
||||||
|
## Режим запуска: параллельно или последовательно
|
||||||
|
|
||||||
|
Профиль отвечает «какие проходы», режим — «как их запускать». Стадии всегда идут
|
||||||
|
по порядку номеров; выбор касается только проходов **внутри** стадии.
|
||||||
|
|
||||||
|
| Режим | Как | Когда |
|
||||||
|
|---|---|---|
|
||||||
|
| **параллельно** (умолчание) | все проходы стадии — одним сообщением | обычный случай: проходы только читают код |
|
||||||
|
| **последовательно** | по одному, следующий стартует после отчёта предыдущего | причины ниже, любой одной достаточно |
|
||||||
|
|
||||||
|
Последовательный режим выбирается, когда верно хоть что-то из:
|
||||||
|
|
||||||
|
0. **Его попросили.** Владелец сказал «гони последовательно» — этого достаточно,
|
||||||
|
обоснования не требуется и переспрашивать не надо. Просьба перекрывает любую
|
||||||
|
эвристику ниже, в том числе когда по ним вышло бы «параллельно». В отчёте —
|
||||||
|
строкой «режим: последовательный, по просьбе». Симметрично: явная просьба
|
||||||
|
гнать параллельно перекрывает пункты 1–4, и тогда в границы покрытия идёт
|
||||||
|
оговорка, что замеры сняты под конкурентной нагрузкой и как оракул слабее.
|
||||||
|
1. **Ожидаются замеры.** Проход измеряет время удержания блокировки, пик кучи,
|
||||||
|
рост `-wal`, длительность транзакции, пропускную способность. Два таких
|
||||||
|
прохода, запущенных разом на одной машине, соревнуются за диск, CPU и за саму
|
||||||
|
SQLite — и выдают числа, которые не воспроизведутся. Это не гипотеза:
|
||||||
|
находки сессии опираются ровно на такие замеры (5.019 с удержания блокировки
|
||||||
|
при `busy_timeout` 5000, пик 768 МиБ на теле 40 МиБ, 7 МБ/с роста `-wal`,
|
||||||
|
1492 тика из 5502). Число, снятое под конкурентную нагрузку от соседнего
|
||||||
|
прохода, — это находка с испорченным оракулом, а её опровержение стоит
|
||||||
|
дороже, чем весь выигрыш от параллельности.
|
||||||
|
2. **Машина занята.** Идёт другая задача, поднят сервис, гоняется
|
||||||
|
`task verify:archive` (минута) или `task gate` (несколько минут).
|
||||||
|
3. **Нужен ранний выход.** См. ниже.
|
||||||
|
4. **Разбирается сам конвейер.** Когда выясняется, почему проход что-то не
|
||||||
|
нашёл, порядок и изоляция важнее скорости.
|
||||||
|
|
||||||
|
**Чего режим не меняет — и это не подлежит обсуждению.** Проход **не видит**
|
||||||
|
находок других проходов ни в каком режиме. «Последовательно» значит «по
|
||||||
|
очереди», а не «следующий читает предыдущего». Вся ценность конвейера держится
|
||||||
|
на декорреляции: под всеми ролями одна модель с одними априорными, и стоит
|
||||||
|
показать ей чужой вывод — она согласится. Согласие нескольких проходов и так не
|
||||||
|
повышает `confidence` (см. «Честный предел»); согласие **наведённое** ещё и
|
||||||
|
маскируется под независимое подтверждение. Единственный, кто видит всё, —
|
||||||
|
триаж, и это его работа.
|
||||||
|
|
||||||
|
**Ранний выход.** В последовательном режиме допустимо остановить прогон, не
|
||||||
|
докатив остаток, ровно в одном случае: находка требует **переделки формы**
|
||||||
|
изменения, и остальные проходы будут смотреть на код, которого через час не
|
||||||
|
станет. Тогда:
|
||||||
|
|
||||||
|
- прогон останавливается, находка чинится, конвейер запускается **заново с
|
||||||
|
нулевой стадии** — а не «доезжает» остатком по старому коду;
|
||||||
|
- незапущенные проходы идут в границы покрытия строкой «не запускался: прогон
|
||||||
|
остановлен на <проход> из-за <находка>», поимённо;
|
||||||
|
- триаж запускается только на полном прогоне. Отчёт триажа по половине проходов
|
||||||
|
— ровно тот случай, который уже стоил семи находок: он выглядит полным,
|
||||||
|
потому что агрегирует всё, что ему подали.
|
||||||
|
|
||||||
|
Ранний выход по находке, которая чинится в пределах существующей формы
|
||||||
|
(`Действие: инлайн`), **не делается**: дешевле дособрать все находки и починить
|
||||||
|
пачкой, чем гонять конвейер дважды.
|
||||||
|
|
||||||
|
Режим объявляется в отчёте наравне с профилем, и если он последовательный — с
|
||||||
|
причиной. Строка «режим: последовательный, ожидались замеры удержания
|
||||||
|
блокировки» стоит ничего и объясняет, почему прогон занял втрое дольше.
|
||||||
|
|
||||||
## Стадия 0 — Gate (обязательна во всех профилях)
|
## Стадия 0 — Gate (обязательна во всех профилях)
|
||||||
|
|
||||||
Агент `healthlog-review-gate`. Запускает `task gate` и интерпретирует вывод.
|
Агент `healthlog-review-gate`. Запускает `task gate` и интерпретирует вывод.
|
||||||
@@ -155,8 +218,9 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
|
|
||||||
## Стадия 1 — Conformance (обязательна во всех профилях)
|
## Стадия 1 — Conformance (обязательна во всех профилях)
|
||||||
|
|
||||||
Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые,
|
Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые.
|
||||||
запускаются **одним сообщением параллельно**.
|
По умолчанию — одним сообщением параллельно; замеров они не делают, так что
|
||||||
|
последовательный режим им нужен только из-за занятой машины.
|
||||||
|
|
||||||
- `healthlog-review-specs` — критерий взят из **дельта-спек change в
|
- `healthlog-review-specs` — критерий взят из **дельта-спек change в
|
||||||
`openspec/changes/<id>/specs/`**, а не из proposal, сообщения коммита или
|
`openspec/changes/<id>/specs/`**, а не из proposal, сообщения коммита или
|
||||||
@@ -173,13 +237,19 @@ Recall обоих равен длине их источника — это и е
|
|||||||
|
|
||||||
## Стадия 2 — Adversarial и operational (`standard`, `deep`)
|
## Стадия 2 — Adversarial и operational (`standard`, `deep`)
|
||||||
|
|
||||||
Два прохода, запускаются **одним сообщением параллельно**:
|
Два прохода:
|
||||||
|
|
||||||
- `healthlog-review-adversary` — находка есть **построенный путь**, а не
|
- `healthlog-review-adversary` — находка есть **построенный путь**, а не
|
||||||
свойство;
|
свойство;
|
||||||
- `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке
|
- `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке
|
||||||
кода.
|
кода.
|
||||||
|
|
||||||
|
**Это главные кандидаты на последовательный режим.** Оба доказывают находки
|
||||||
|
замером, и оба меряют одно и то же железо: удержание блокировки SQLite, пик
|
||||||
|
кучи, рост `-wal`, длительность транзакции. Запущенные разом, они портят числа
|
||||||
|
друг другу. Если ждёшь от прогона хоть один такой замер — гони их по очереди,
|
||||||
|
а не одним сообщением.
|
||||||
|
|
||||||
**Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в
|
**Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в
|
||||||
`standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход
|
`standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход
|
||||||
дал пять из семи выживших находок дозапуска на `f8200f7` (включая обе верхние) и
|
дал пять из семи выживших находок дозапуска на `f8200f7` (включая обе верхние) и
|
||||||
|
|||||||
@@ -151,14 +151,23 @@ healthlog — хранилище данных о здоровье, у котор
|
|||||||
### 7. Ревью кода — Skill `healthlog-review-pipeline`
|
### 7. Ревью кода — Skill `healthlog-review-pipeline`
|
||||||
|
|
||||||
Второй чекпоинт. Вызови Skill **`healthlog-review-pipeline`**, дав ссылку на change
|
Второй чекпоинт. Вызови Skill **`healthlog-review-pipeline`**, дав ссылку на change
|
||||||
`<id>`, базу диффа и профиль. Профиль выбирается по факту изменения, а не по
|
`<id>`, базу диффа, профиль **и режим запуска**. Профиль выбирается по факту
|
||||||
ощущению важности (правило — в самом скилле):
|
изменения, а не по ощущению важности (правило — в самом скилле):
|
||||||
|
|
||||||
- миграция, новый пакет, контракт Read API или MCP, правило слияния точек или
|
- миграция, новый пакет, контракт Read API или MCP, правило слияния точек или
|
||||||
вывод слоя → `deep`;
|
вывод слоя → `deep`;
|
||||||
- иначе меняется поведение, видимое снаружи → `standard`;
|
- иначе меняется поведение, видимое снаружи → `standard`;
|
||||||
- иначе (багфикс, локальная правка, доки) → `quick`.
|
- иначе (багфикс, локальная правка, доки) → `quick`.
|
||||||
|
|
||||||
|
Режим по умолчанию параллельный. **Попросили последовательный — значит
|
||||||
|
последовательный**, без обоснований и переспрашивания. Сам проси
|
||||||
|
**последовательный**, если ждёшь от
|
||||||
|
прохода замеров — времени удержания блокировки, пика кучи, роста `-wal`,
|
||||||
|
длительности транзакции: два меряющих прохода на одной машине портят числа друг
|
||||||
|
другу, а находка с испорченным оракулом дороже сэкономленных минут. Второй
|
||||||
|
повод — машина занята (поднят сервис, идёт `task gate` или
|
||||||
|
`task verify:archive`). Правило и его оговорки — в самом скилле.
|
||||||
|
|
||||||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||||||
покрытия.
|
покрытия.
|
||||||
|
|||||||
Reference in New Issue
Block a user