- профиль отвечает «какие проходы», режим — «как их запускать» - явная просьба владельца — достаточное основание, без обоснований и переспрашивания; перекрывает эвристики в обе стороны - главный собственный повод — ожидаемые замеры: adversary и ops меряют одно железо (блокировка SQLite, куча, рост -wal) и портят числа друг другу, а находка с испорченным оракулом дороже сэкономленных минут - декорреляция не меняется ни в каком режиме: проход не видит чужих находок, «последовательно» ≠ «читает предыдущего» - ранний выход только при переделке формы изменения, с перезапуском с нулевой стадии; триаж — только на полном прогоне
19 KiB
name, description
| name | description |
|---|---|
| healthlog-task-pipeline | Автономно проводит задачу healthlog через полный цикл SDD — от выбора в беклоге до коммита (opsx explore→propose→ревью спек→apply→ревью кода→archive→чистка беклога). Использовать, когда пользователь просит взять/сделать задачу из беклога или довести идею до реализации. |
Пайплайн задачи (healthlog)
Оркестратор одной задачи по Spec Driven Development: проводит её от беклога до коммита максимально автономно, привлекая пользователя только на реальных развилках (компромиссы, изменение scope, угроза инвариантам). Механику не согласовываем — делаем.
Перед стартом прочитай CLAUDE.md, а также README.md, docs/architecture.md,
docs/conventions.md, если ещё не в контексте. Это тонкая обёртка над
каноническими скиллами opsx:explore / opsx:propose / opsx:apply /
opsx:archive — вызывай их через Skill, не переизобретай их шаги.
Что нельзя сломать
healthlog — хранилище данных о здоровье, у которого источник (телефон) шлёт непрерывно и молча. Отсюда особенности, которых нет в обычном сервисе:
- Поток не останавливается на время задачи. Сервис поднят в контейнере
(
task up/task restart), данные в./data. Перезапуск на пару секунд безопасен — дыру закроют средний и глубокий проходы синхронизации; а вот сломанный приём, оставленный работать, теряет данные необратимо. - Потерянная доставка не восстанавливается. Тело, не попавшее в архив, в
журнал не попадает вовсе: телефон его не перешлёт. Разобранное же всегда
пересобираемо свёрткой, поэтому цена ошибки разбора и цена ошибки приёма
различаются на порядок. Любая правка разбора, слияния или вывода слоя — это
deep-профиль ревью, без исключений. - Данные чувствительны. Ничего из
./dataне попадает ни в git, ни в логи вышеDEBUG, ни в вывод агента. Гейт проверяет первое механически (no-health-data), остальное — на тебе. - Разведка уже проведена.
docs/local-research.md— 46 находок на живом потоке, половина расходится с документацией HAE. Проверь там, прежде чем строить догадку о формате: скорее всего вопрос уже закрыт измерением.
Принцип автономности
Умолчание — делать, а не спрашивать. Задача доводится до коммита без участия человека; предполагается, что так пройдёт большинство задач.
Наткнулся на вопрос, который решать не тебе, — не останавливайся и не спрашивай. Вынь его блокером и продолжай:
- Заведи пункт в секции
блокерыбеклога:backlog.py add --slug <slug> --priority блокеры --hook <что заблокировано>. Тело отвечает на три вопроса: что именно решить, какие есть варианты и цена каждого, что стоит, пока решения нет. Плюс твоя рекомендация — человек чаще соглашается, чем выбирает заново, и готовое суждение экономит ему весь контекст. - Переформулируй задачу на остаток — то, что делается без этого решения. Впиши в её тело ссылку на блокер и границу: докуда доводим сейчас.
- Доведи остаток до конца и закоммить. Задача не «висит на вопросе», она сделана в объявленных границах.
Если полезного остатка нет вовсе — блокер заводится, задача остаётся на месте со ссылкой на него, и берётся следующая. Это редкий случай; чаще остаток есть.
Блокеры разбираются пачками, а не по одному: прерывать поток ради каждого дороже, чем накопить.
Когда всё-таки спрашивать
Узко и по другому основанию — не «сложное решение», а необратимое действие:
- деплой, выкладка наружу, смена публичного адреса или токенов;
- удаление или перезапись данных в
./data, включая подрезку архива; - всё, что уходит за пределы машины.
Здесь ошибка не откатывается коммитом, поэтому спрашиваем даже когда решение кажется очевидным. Развилка в дизайне — блокер; необратимое действие — вопрос.
Стиль правок — заточка под проект и конвенции, right-size, без золочения.
Шаги
1. Выбрать / прочитать задачу
- Если задача задана (slug, файл в
docs/backlog/или описание) — прочитай её файл и связанные спеки/черновики. - Если не задана — выбирай сам: верхняя секция приоритета, не
[idea], не заблокированная целиком. Из равных бери ту, что разблокирует больше других. Выбор объявляешь в докладе, а не согласовываешь заранее. - Задача с префиксом
[idea](ещё без решения «делаем») — сперва обязательно через explore (шаг 2), там она либо становится задачей, либо остаётся идеей.
Формат файла задачи и индекса держит скилл backlog — здесь мы беклог только
читаем. Если по ходу выбора вскрылось, что задача устарела, дублируется или
разрослась в эпик, это работа для скилла backlog, а не для пайплайна.
Оцени тривиальность (влияет на шаг 4):
- Тривиальная — локальная правка без изменения поведения/спек/схемы БД, очевидное решение. Explore и ревью спек пропускаем.
- Нетривиальная — новое/изменённое поведение, дизайн-развилки, затрагивает инварианты, схему БД или несколько capability. Полный цикл.
2. (Опц.) Груммить идею — opsx:explore
Только для [idea]-задач или когда постановка мутная. Вызови Skill
opsx:explore. Развилку грумминга не выноси на человека — заведи блокером и
груми остаток. Выход: ясная постановка, готовая к propose. В explore не
пишем код.
3. Завести change — opsx:propose
Вызови Skill opsx:propose. Получаем proposal.md, дизайн (для нетривиальных),
дельта-спеки (ADDED/MODIFIED/REMOVED Requirements), tasks.md. Каждое
### Requirement содержит SHALL/MUST; структурные заголовки английские,
сценарии GIVEN/WHEN/THEN. Прогони openspec validate --strict <id>.
4. (Нетривиальная) Ревью предложения — профиль design, ДО кода
Первый чекпоинт ревью-процесса. Вызови Skill healthlog-review-pipeline с профилем
design и ссылкой на change <id>. Он запустит healthlog-review-specs (режим
«дизайн/спеки ДО кода»), healthlog-review-rubric (фаза 1: приёмочные критерии
для задуманного узла) и healthlog-review-architecture по предложению.
Смысл профиля: архитектурная находка на готовом коде стоит переписывания и
потому игнорируется — та же находка здесь стоит абзаца обсуждения. Рубрику из
healthlog-review-rubric перенеси в tasks.md как приёмочные критерии.
5. Отработать замечания ревью предложения
- Мелочь и явные улучшения — правь сам в спеках/дизайне.
- Развилки (компромисс, scope, инвариант) — блокером, спеки урезаются на остаток.
- После правок перепрогони
openspec validate --strict <id>.
6. Написать код — opsx:apply
Вызови Skill opsx:apply для реализации tasks.md. Код по конвенциям
docs/conventions.md: ошибки stdlib с %w/errors.Is, логи только slog без
секретов и тел запросов, время в UTC через store.Now(), ULID через
internal/ident, миграции goose. Меняешь схему — обнови ER-схему
docs/database.md в том же change (гейт это проверяет).
Прогони task gate и добейся зелёного — он же гейт следующего шага.
Поведенческая верификация. Если задача меняет реальное поведение (новый
эндпоинт, разбор входа, схема БД, форма ответа) — зелёных юнит-тестов мало.
Подними изменение вживую: task restart, затем прогони сценарий по настоящим
данным из ./data (89+ доставок реального потока) или скриптом из
tmp/research/. Пропусти только для чисто внутренних правок без наблюдаемого
рантайма.
Сервис не оставляем лежать. Если task restart упал — почини или откати
до конца шага: телефон продолжает слать всё это время.
7. Ревью кода — Skill healthlog-review-pipeline
Второй чекпоинт. Вызови Skill healthlog-review-pipeline, дав ссылку на change
<id>, базу диффа, профиль и режим запуска. Профиль выбирается по факту
изменения, а не по ощущению важности (правило — в самом скилле):
- миграция, новый пакет, контракт Read API или MCP, правило слияния точек или
вывод слоя →
deep; - иначе меняется поведение, видимое снаружи →
standard; - иначе (багфикс, локальная правка, доки) →
quick.
Режим по умолчанию параллельный. Попросили последовательный — значит
последовательный, без обоснований и переспрашивания. Сам проси
последовательный, если ждёшь от
прохода замеров — времени удержания блокировки, пика кучи, роста -wal,
длительности транзакции: два меряющих прохода на одной машине портят числа друг
другу, а находка с испорченным оракулом дороже сэкономленных минут. Второй
повод — машина занята (поднят сервис, идёт task gate или
task verify:archive). Правило и его оговорки — в самом скилле.
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
потолком 7 пунктов, разметкой Действие: инлайн | развилка и секцией границ
покрытия.
Сверь состав прогона с таблицей профилей в скилле, прежде чем коммитить. Пропуск прохода не отличим от прохода без находок: гейт зелёный, спеки сошлись, отчёт выглядит полным. Единственный, кто мог бы заметить пропуск, — триаж, а он заполняется тем, что ему подали. Отчёт обязан называть запущенные проходы поимённо и с исходом; непущенный идёт строкой «не запускался» в границы покрытия. Реестр короткий (4–8 проходов) — сверка стоит одного взгляда, а молчащий пропуск уже стоил семи находок и отдельной задачи на их дозакрытие.
Отработай так же, как шаг 5: помеченное инлайн чини сам и не логируй,
развилка — блокером в беклог (вопрос уже сформулирован триажем, его остаётся
перенести). После правок — снова task gate.
Границы покрытия из отчёта не выбрасывай — они уезжают в финальный доклад (шаг 10) сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно», превращается в ложное ощущение проверенности.
8. Архивировать — opsx:archive
Вызови Skill opsx:archive: change уезжает в openspec/changes/archive/,
дельты вливаются в openspec/specs/.
9. Закрыть беклог и синк доков
Ревью выполненного — до чистки. Затем:
- Удали файл задачи
docs/backlog/<slug>.mdи строку вdocs/backlog/README.md. Реализованное не держим в беклоге — у него есть коммит и спека. - Суть переехавшего решения — в
docs/architecture.md, если ещё не там. - Менялась структура БД — убедись, что
docs/database.mdобновлён в этом же change. - Новое, узнанное о формате HAE или о данных, — в
docs/local-research.mdочередной находкой. Это источник истины по формату, и он ценнее кода. - Проверь согласованность индекса командой
checkскиллаbacklog.
10. Коммит
Коммить в текущую ветку (git rev-parse --abbrev-ref HEAD), сам ветку не
создавай и не переключай, ничего не пушь. При ручном запуске HEAD обычно на
master — коммит идёт прямо в него, без feature-веток.
Сообщение — по-русски, по скиллу commit (первая строка отвечает «что
сделано», тело списком 1–3 пункта, без трейлеров). Одна задача — один
осмысленный коммит.
Готово — доложи пользователю кратко: что сделано, какие блокеры заведены и чем ограничен остаток, ссылка на архивный change. Плюс одна строка границ покрытия из отчёта ревью: какой профиль гонялся и что проверить было невозможно. Доклад без неё сообщает «проверено», не сообщая, что именно.
Тонкости
- Не завязывайся на master и корень репо. Скилл работает в текущем worktree
и на текущей ветке: не делай
git checkout/switch, не создавай веток, не пушь. - Не пропускай
openspec validate --strictперед архивацией. - Тривиальная задача: шаги 2 и 4 пропускаются; ревью кода (шаг 7) остаётся
всегда, но в профиле
quick. - Гейт блокирует: пока
task gateкрасный, опиниативные проходы не запускаются. Чинить и перезапускать, а не «посмотреть заодно». - Если ревью предлагает крупную переработку — это развилка: не правь молча и не спрашивай, заведи блокером и доведи остаток.
- Держи пользователя в цикле короткими репликами на переходах фаз, но не проси подтверждать механику.