--- name: healthlog-task-pipeline description: Автономно проводит задачу 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. Проверь там, прежде чем строить догадку о формате: скорее всего вопрос уже закрыт измерением. ## Принцип автономности **Умолчание — делать, а не спрашивать.** Задача доводится до коммита без участия человека; предполагается, что так пройдёт большинство задач. Наткнулся на вопрос, который решать не тебе, — **не останавливайся и не спрашивай**. Вынь его блокером и продолжай: 1. Заведи пункт в секции `блокеры` беклога: `backlog.py add --slug --priority блокеры --hook <что заблокировано>`. Тело отвечает на три вопроса: **что именно решить**, **какие есть варианты и цена каждого**, **что стоит, пока решения нет**. Плюс твоя рекомендация — человек чаще соглашается, чем выбирает заново, и готовое суждение экономит ему весь контекст. 2. **Переформулируй задачу на остаток** — то, что делается без этого решения. Впиши в её тело ссылку на блокер и границу: докуда доводим сейчас. 3. Доведи остаток до конца и закоммить. Задача не «висит на вопросе», она сделана в объявленных границах. Если полезного остатка нет вовсе — блокер заводится, задача остаётся на месте со ссылкой на него, и берётся следующая. Это редкий случай; чаще остаток есть. Блокеры разбираются пачками, а не по одному: прерывать поток ради каждого дороже, чем накопить. ### Когда всё-таки спрашивать Узко и по другому основанию — не «сложное решение», а **необратимое действие**: - деплой, выкладка наружу, смена публичного адреса или токенов; - удаление или перезапись данных в `./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 `. ### 4. (Нетривиальная) Ревью предложения — профиль `design`, ДО кода Первый чекпоинт ревью-процесса. Вызови Skill **`healthlog-review-pipeline`** с профилем `design` и ссылкой на change ``. Он запустит `healthlog-review-specs` (режим «дизайн/спеки ДО кода»), `healthlog-review-rubric` (фаза 1: приёмочные критерии для задуманного узла), `healthlog-review-idiom` и `healthlog-review-architecture` по предложению. Смысл профиля: архитектурная находка на готовом коде стоит переписывания и потому игнорируется — та же находка здесь стоит абзаца обсуждения. Рубрику из `healthlog-review-rubric` перенеси в `tasks.md` как приёмочные критерии. ### 5. Отработать замечания ревью предложения - Мелочь и явные улучшения — правь сам в спеках/дизайне. - Развилки (компромисс, scope, инвариант) — блокером, спеки урезаются на остаток. - После правок перепрогони `openspec validate --strict `. ### 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 ``, базу диффа и профиль. Профиль выбирается по факту изменения, а не по ощущению важности (правило — в самом скилле): - миграция, новый пакет, контракт Read API или MCP, правило слияния точек или вывод слоя → `deep`; - иначе меняется поведение, видимое снаружи → `standard`; - иначе (багфикс, локальная правка, доки) → `quick`. Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ покрытия. Отработай так же, как шаг 5: помеченное `инлайн` чини сам и не логируй, `развилка` — блокером в беклог (вопрос уже сформулирован триажем, его остаётся перенести). После правок — снова `task gate`. **Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад (шаг 10) сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно», превращается в ложное ощущение проверенности. ### 8. Архивировать — `opsx:archive` Вызови Skill `opsx:archive`: change уезжает в `openspec/changes/archive/`, дельты вливаются в `openspec/specs/`. ### 9. Закрыть беклог и синк доков Ревью выполненного — **до** чистки. Затем: - Удали файл задачи `docs/backlog/.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` красный, опиниативные проходы не запускаются. Чинить и перезапускать, а не «посмотреть заодно». - Если ревью предлагает крупную переработку — это развилка: не правь молча и не спрашивай, заведи блокером и доведи остаток. - Держи пользователя в цикле короткими репликами на переходах фаз, но не проси подтверждать механику.