diff --git a/.claude/skills/healthlog-review-pipeline/SKILL.md b/.claude/skills/healthlog-review-pipeline/SKILL.md index adc1914..240fdc9 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) @@ -138,31 +138,44 @@ description: Конвейер ревью изменений healthlog — дет | Режим | Как | Когда | |---|---|---| -| **параллельно** (умолчание) | все проходы стадии — одним сообщением | обычный случай: проходы только читают код | -| **последовательно** | по одному, следующий стартует после отчёта предыдущего | причины ниже, любой одной достаточно | +| **последовательно** (умолчание) | по одному, следующий стартует после отчёта предыдущего | всегда, пока не попросили иначе | +| **параллельно** | названные проходы — одним сообщением | только по явной просьбе **и** с явно названным набором | -Последовательный режим выбирается, когда верно хоть что-то из: +**Умолчание — последовательно, и его не надо обосновывать.** Обосновывается +отступление. -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. **Разбирается сам конвейер.** Когда выясняется, почему проход что-то не - нашёл, порядок и изоляция важнее скорости. +**Параллельный режим включается при двух условиях сразу**, и второе так же +обязательно, как первое: + +1. **о нём попросили явно** — «гони параллельно», а не «сделай побыстрее»; +2. **названо, что именно гнать параллельно** — поимённый набор проходов + («`specs` и `code` параллельно») или стадия целиком («стадию 1 параллельно»). + +Просьба без набора — **не основание**: гоним последовательно и одной строкой +говорим, что набор не был назван. Это не придирка к формулировке. Параллелить +можно ровно то, что не мешает друг другу, а знание об этом лежит у того, кто +просит: он видит, занята ли машина, и ждёт ли он от прогона замеров. Домысливать +набор за него — значит принять решение, которое он оставил себе. + +Почему умолчание именно такое: + +- **Замеры.** Проходы `adversary` и `ops` доказывают находки числами: время + удержания блокировки, пик кучи, рост `-wal`, длительность транзакции. Два + меряющих прохода на одной машине соревнуются за диск, CPU и за саму SQLite и + выдают числа, которые не воспроизведутся. Это не гипотеза: находки сессии + опираются ровно на такие замеры (5.019 с удержания блокировки при + `busy_timeout` 5000, пик 768 МиБ на теле 40 МиБ, 7 МБ/с роста `-wal`, 1492 + тика из 5502). Число, снятое под конкурентную нагрузку от соседнего прохода, — + это находка с испорченным оракулом, а её опровержение стоит дороже всего + выигрыша от параллельности. +- **Машина одна.** Рядом идёт задача, поднят сервис, гоняется `task gate` или + `task verify:archive`. +- **Ранний выход** возможен только при последовательном прогоне (см. ниже). +- **Разбор самого конвейера.** Когда выясняется, почему проход чего-то не нашёл, + порядок и изоляция важнее скорости. + +Если параллельный режим всё же включён, в границы покрытия идёт строка: какие +проходы шли разом и что замеры, снятые в этом прогоне, как оракул слабее. **Чего режим не меняет — и это не подлежит обсуждению.** Проход **не видит** находок других проходов ни в каком режиме. «Последовательно» значит «по @@ -173,8 +186,9 @@ description: Конвейер ревью изменений healthlog — дет маскируется под независимое подтверждение. Единственный, кто видит всё, — триаж, и это его работа. -**Ранний выход.** В последовательном режиме допустимо остановить прогон, не -докатив остаток, ровно в одном случае: находка требует **переделки формы** +**Ранний выход** (последовательный режим делает его возможным — это его побочная +выгода, а не повод его выбирать). Допустимо остановить прогон, не докатив +остаток, ровно в одном случае: находка требует **переделки формы** изменения, и остальные проходы будут смотреть на код, которого через час не станет. Тогда: @@ -190,9 +204,10 @@ description: Конвейер ревью изменений healthlog — дет (`Действие: инлайн`), **не делается**: дешевле дособрать все находки и починить пачкой, чем гонять конвейер дважды. -Режим объявляется в отчёте наравне с профилем, и если он последовательный — с -причиной. Строка «режим: последовательный, ожидались замеры удержания -блокировки» стоит ничего и объясняет, почему прогон занял втрое дольше. +Режим объявляется в отчёте наравне с профилем, и если он **параллельный** — с +причиной и составом: «режим: параллельный по просьбе, одним сообщением шли +`specs` и `code`». Последовательный режим объявляется одним словом: +обосновывается отступление, а не умолчание. ## Стадия 0 — Gate (обязательна во всех профилях) @@ -219,8 +234,8 @@ description: Конвейер ревью изменений healthlog — дет ## Стадия 1 — Conformance (обязательна во всех профилях) Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые. -По умолчанию — одним сообщением параллельно; замеров они не делают, так что -последовательный режим им нужен только из-за занятой машины. +Замеров они не делают и потому безобиднее прочих, если параллельный режим +попросят с их именами; сами по себе идут по очереди, как и все. - `healthlog-review-specs` — критерий взят из **дельта-спек change в `openspec/changes//specs/`**, а не из proposal, сообщения коммита или @@ -244,11 +259,12 @@ Recall обоих равен длине их источника — это и е - `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке кода. -**Это главные кандидаты на последовательный режим.** Оба доказывают находки -замером, и оба меряют одно и то же железо: удержание блокировки SQLite, пик -кучи, рост `-wal`, длительность транзакции. Запущенные разом, они портят числа -друг другу. Если ждёшь от прогона хоть один такой замер — гони их по очереди, -а не одним сообщением. +**Эту пару параллелить не стоит даже по просьбе — переспроси.** Оба доказывают +находки замером, и оба меряют одно и то же железо: удержание блокировки SQLite, +пик кучи, рост `-wal`, длительность транзакции. Запущенные разом, они портят +числа друг другу, а испорченный оракул хуже отсутствующего: находка выглядит +доказанной. Если их всё же назвали в параллельном наборе — выполняй, но скажи в +границах покрытия, что числа этого прогона сняты под соседней нагрузкой. **Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в `standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход diff --git a/.claude/skills/healthlog-task-pipeline/SKILL.md b/.claude/skills/healthlog-task-pipeline/SKILL.md index a5a7981..3a30252 100644 --- a/.claude/skills/healthlog-task-pipeline/SKILL.md +++ b/.claude/skills/healthlog-task-pipeline/SKILL.md @@ -159,14 +159,14 @@ healthlog — хранилище данных о здоровье, у котор - иначе меняется поведение, видимое снаружи → `standard`; - иначе (багфикс, локальная правка, доки) → `quick`. -Режим по умолчанию параллельный. **Попросили последовательный — значит -последовательный**, без обоснований и переспрашивания. Сам проси -**последовательный**, если ждёшь от -прохода замеров — времени удержания блокировки, пика кучи, роста `-wal`, -длительности транзакции: два меряющих прохода на одной машине портят числа друг -другу, а находка с испорченным оракулом дороже сэкономленных минут. Второй -повод — машина занята (поднят сервис, идёт `task gate` или -`task verify:archive`). Правило и его оговорки — в самом скилле. +**Режим по умолчанию последовательный, и обосновывать его не надо.** Параллельно +гоняем только тогда, когда об этом попросили явно **и назвали набор** — какие +именно проходы или какую стадию. Просьба без набора основанием не считается: +гони последовательно и скажи строкой, что набор не был назван. Причина умолчания +— замеры: `adversary` и `ops` доказывают находки числами (удержание блокировки, +пик кучи, рост `-wal`), а два меряющих прохода на одной машине портят числа друг +другу; находка с испорченным оракулом хуже отсутствующей, потому что выглядит +доказанной. Правило целиком и его оговорки — в самом скилле. Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ