From 58cf5c07d8eabd422a2de66f8bc7e9a1a0825bd4 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 2 Aug 2026 20:57:20 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E:=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D0=BE=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B4=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=83=D1=81=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - профиль отвечает «какие проходы», режим — «как их запускать» - явная просьба владельца — достаточное основание, без обоснований и переспрашивания; перекрывает эвристики в обе стороны - главный собственный повод — ожидаемые замеры: adversary и ops меряют одно железо (блокировка SQLite, куча, рост -wal) и портят числа друг другу, а находка с испорченным оракулом дороже сэкономленных минут - декорреляция не меняется ни в каком режиме: проход не видит чужих находок, «последовательно» ≠ «читает предыдущего» - ранний выход только при переделке формы изменения, с перезапуском с нулевой стадии; триаж — только на полном прогоне --- .../skills/healthlog-review-pipeline/SKILL.md | 80 +++++++++++++++++-- .../skills/healthlog-task-pipeline/SKILL.md | 13 ++- 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/.claude/skills/healthlog-review-pipeline/SKILL.md b/.claude/skills/healthlog-review-pipeline/SKILL.md index 84dbe22..adc1914 100644 --- a/.claude/skills/healthlog-review-pipeline/SKILL.md +++ b/.claude/skills/healthlog-review-pipeline/SKILL.md @@ -1,6 +1,6 @@ --- name: healthlog-review-pipeline -description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода. +description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, независимая реализация по триггеру, архитектура и обязательный триаж. Проходы гонятся параллельно или последовательно (второе — когда ожидаются замеры или занята машина). Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода. --- # Конвейер ревью (healthlog) @@ -119,7 +119,7 @@ description: Конвейер ревью изменений healthlog — дет измерена: семь находок и отдельная задача на их дозакрытие (`docs/review-journal.md`, 2026-08-02). -Правило выбора — по факту изменения, не по ощущению важности: +Правило выбора профиля — по факту изменения, не по ощущению важности: - есть миграция в `internal/store/migrations/`, новый пакет `internal/*`, изменение контракта Read API или MCP, трогается правило слияния точек или @@ -131,6 +131,69 @@ description: Конвейер ревью изменений healthlog — дет Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно попадает в границы покрытия строкой «профиль понижен до 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 (обязательна во всех профилях) Агент `healthlog-review-gate`. Запускает `task gate` и интерпретирует вывод. @@ -155,8 +218,9 @@ description: Конвейер ревью изменений healthlog — дет ## Стадия 1 — Conformance (обязательна во всех профилях) -Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые, -запускаются **одним сообщением параллельно**. +Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые. +По умолчанию — одним сообщением параллельно; замеров они не делают, так что +последовательный режим им нужен только из-за занятой машины. - `healthlog-review-specs` — критерий взят из **дельта-спек change в `openspec/changes//specs/`**, а не из proposal, сообщения коммита или @@ -173,13 +237,19 @@ Recall обоих равен длине их источника — это и е ## Стадия 2 — Adversarial и operational (`standard`, `deep`) -Два прохода, запускаются **одним сообщением параллельно**: +Два прохода: - `healthlog-review-adversary` — находка есть **построенный путь**, а не свойство; - `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке кода. +**Это главные кандидаты на последовательный режим.** Оба доказывают находки +замером, и оба меряют одно и то же железо: удержание блокировки SQLite, пик +кучи, рост `-wal`, длительность транзакции. Запущенные разом, они портят числа +друг другу. Если ждёшь от прогона хоть один такой замер — гони их по очереди, +а не одним сообщением. + **Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в `standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход дал пять из семи выживших находок дозапуска на `f8200f7` (включая обе верхние) и diff --git a/.claude/skills/healthlog-task-pipeline/SKILL.md b/.claude/skills/healthlog-task-pipeline/SKILL.md index f890a72..a5a7981 100644 --- a/.claude/skills/healthlog-task-pipeline/SKILL.md +++ b/.claude/skills/healthlog-task-pipeline/SKILL.md @@ -151,14 +151,23 @@ healthlog — хранилище данных о здоровье, у котор ### 7. Ревью кода — Skill `healthlog-review-pipeline` Второй чекпоинт. Вызови Skill **`healthlog-review-pipeline`**, дав ссылку на change -``, базу диффа и профиль. Профиль выбирается по факту изменения, а не по -ощущению важности (правило — в самом скилле): +``, базу диффа, профиль **и режим запуска**. Профиль выбирается по факту +изменения, а не по ощущению важности (правило — в самом скилле): - миграция, новый пакет, контракт Read API или MCP, правило слияния точек или вывод слоя → `deep`; - иначе меняется поведение, видимое снаружи → `standard`; - иначе (багфикс, локальная правка, доки) → `quick`. +Режим по умолчанию параллельный. **Попросили последовательный — значит +последовательный**, без обоснований и переспрашивания. Сам проси +**последовательный**, если ждёшь от +прохода замеров — времени удержания блокировки, пика кучи, роста `-wal`, +длительности транзакции: два меряющих прохода на одной машине портят числа друг +другу, а находка с испорченным оракулом дороже сэкономленных минут. Второй +повод — машина занята (поднят сервис, идёт `task gate` или +`task verify:archive`). Правило и его оговорки — в самом скилле. + Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ покрытия.