From f8edfc17822b05d9d3b715cf9bd8b0d65c54f4c8 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 23 Jul 2026 18:18:16 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E:=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=D1=82=D1=8C=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D0=B2=D0=B5=D0=B9=D0=B5=D1=80=20=D0=B2=20task-pipeline?= =?UTF-8?q?=20=D0=B8=20task-batch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Шаг 4 стал профилем design на предложении (архитектурная находка на готовом коде стоит переписывания и потому игнорируется — на предложении она стоит абзаца), шаг 7 — вызовом review-pipeline с профилем по факту изменения. Границы покрытия протаскиваются в финальный доклад строкой. В task-batch финальная сверка сужена до того, что появилось от слияния: повторять полный конвейер на интегрированном диффе бессмысленно — те же проходы на тех же файлах дают те же находки и удорожают триаж. Заодно убрана ссылка на несуществующий скилл verify: шага не было ни в проекте, ни у пользователя, поведенческую верификацию делает Skill run. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/task-batch/SKILL.md | 53 ++++++++++--------- .claude/skills/task-pipeline/SKILL.md | 76 ++++++++++++++++----------- CLAUDE.md | 16 ++++-- 3 files changed, 86 insertions(+), 59 deletions(-) diff --git a/.claude/skills/task-batch/SKILL.md b/.claude/skills/task-batch/SKILL.md index b6a176f..53a2d89 100644 --- a/.claude/skills/task-batch/SKILL.md +++ b/.claude/skills/task-batch/SKILL.md @@ -110,17 +110,18 @@ remote — `git fetch` и синк). Зафиксируй базовый ком полный цикл SDD с промежуточными ревью-чекпоинтами. - Если задаче на шаге 2 назначен **номер миграции** — используй строго его (`internal/store/migrations/<номер>_*`), не бери «следующий свободный» сам. - - **Ревью-чекпоинты**: попробуй запустить агентов `jellybit-review-specs` / - `jellybit-review-code` через Agent tool (как в `task-pipeline`). Если - вложенный запуск сабагента недоступен — проведи ревью **инлайн**, используя - charter'ы `.claude/agents/jellybit-review-*.md` как чеклист. Чекпоинт «ревью - спек ДО кода» не пропускай. + - **Ревью-чекпоинты**: оба идут через Skill `review-pipeline` (профиль + `design` до кода, потом профиль по факту изменения). Если вложенный запуск + сабагентов недоступен — проведи ревью **инлайн** по тем же charter'ам + `.claude/agents/jellybit-review-*.md`, но обязательно сохрани гейт + (`task gate` до опиниативных проходов) и триаж; в отчёте прямо укажи, что + ревью шло инлайн — это меняет доверие к результату. - **Коммит.** `task-pipeline` коммитит в текущую ветку — а это твоя `task/` в worktree, так что специально ничего переопределять не нужно. Всё остальное (`opsx:archive`, чистка беклога `docs/backlog/.md` + строка индекса, синк спек/ADR) ложится коммитами туда же. Master не трогай, ветку не переключай, ничего не пушь, новых worktree не создавай. - - `task test` / `task lint` в своём worktree — добейся зелёного. + - `task gate` в своём worktree — добейся зелёного. - Верни отчёт: что сделано, какие развилки решались, изменённые файлы, **добавлял ли миграцию и её номер**, затронутые capability, статус тестов/линта, все неразрешённые вопросы. @@ -143,7 +144,7 @@ remote — `git fetch` и синк). Зафиксируй базовый ком форсируй**: прерви (`git rebase --abort`), оставь ветку/worktree как есть и вынеси развилку пользователю (это признак нераспознанного пересечения). - `git checkout master && git merge --ff-only task/`. -- После каждой интеграции: `task test` (+ `task lint`) на master. **Красное — +- После каждой интеграции: `task gate` на master. **Красное — откати эту интеграцию** (`git reset --hard` на прошлую вершину master), ветку с worktree сохрани, вынеси пользователю. Master **никогда** не остаётся полузелёным. @@ -159,28 +160,30 @@ worktree и ветке нетронутой (ничего не удаляем), перечисляем провалившиеся с их отчётами и причиной. Пользователь потом решит: дожать вручную, переназначить, отложить. -### 6. Финальный гейт — все тесты +### 6. Финальный гейт -На master после всех интеграций: `task test` + `task lint` (+ `task build`). -Зелёное — обязательно. +На master после всех интеграций: `task gate` (+ `task build`). Зелёное — +обязательно; пока красное, шаг 7 не начинается. -### 7. Финальная сверка кода с требованиями — по затронутым capability +### 7. Финальная сверка — только то, чего не видел никто -Собери **объединение затронутых capability** по всем задачам. Запусти **по одному -сабагенту-ревьюверу на каждую затронутую capability, все в одном сообщении** -(параллельно), `subagent_type: jellybit-review-specs`. Каждому дай: -- имя capability и путь `openspec/specs//spec.md`; -- интегрированный diff `git diff <база>..HEAD`, сфокусированный на файлах этой - capability; -- задание: сверить **код на master с требованиями** capability — покрытие - `### Requirement` (все содержат `SHALL`/`MUST`), сценарии `GIVEN/WHEN/THEN`, - инварианты безопасности данных, непротиворечивость код↔спека после слияния - нескольких задач (косвенные рассинхроны на стыках). +Каждая задача уже прошла полный конвейер ревью в своём worktree. Повторять его +на интегрированном диффе бессмысленно: те же проходы на тех же файлах дадут те +же находки и удорожат триаж. Здесь проверяется **только то, что появилось от +слияния** и потому не было видно ни одному прогону: -Опционально, если задач много и они пересекаются, добавь один -`jellybit-review-code` на весь интегрированный diff (архитектура/конвенции/стиль -сквозняком). Замечания отрабатывай как в `task-pipeline`: мелочь чини инлайн, -развилки — на пользователя; после правок — снова `task test`/`task lint`. +- Запусти **по одному `jellybit-review-specs` на каждую затронутую capability, + все в одном сообщении** (параллельно). Задание сузь до стыков: не сверять + capability целиком заново, а искать **рассинхрон код↔спека, возникший от + слияния нескольких задач** — требование, которое одна задача выполнила, а + соседняя незаметно отменила; два change, по-разному описавшие одно поведение. +- Если задачи пересекались по файлам, добавь один + `jellybit-review-architecture` на интегрированный дифф с вопросом «не появился + ли второй способ делать то, что уже делается» — именно он возникает, когда + две задачи независимо решали похожее. + +Замечания отрабатывай как в `task-pipeline`: `инлайн` чини сам, `развилка` — на +пользователя; после правок — снова `task gate`. ### 8. Прибраться и доложить diff --git a/.claude/skills/task-pipeline/SKILL.md b/.claude/skills/task-pipeline/SKILL.md index 39976bf..a94f1f8 100644 --- a/.claude/skills/task-pipeline/SKILL.md +++ b/.claude/skills/task-pipeline/SKILL.md @@ -60,15 +60,19 @@ description: Автономно проводит задачу jellybit чере `### Requirement` содержит `SHALL`/`MUST`; структурные заголовки английские, сценарии `GIVEN/WHEN/THEN`. Прогони `openspec validate --strict `. -### 4. (Нетривиальная) Ревью спек — сабагент, ДО кода +### 4. (Нетривиальная) Ревью предложения — профиль `design`, ДО кода -Первый чекпоинт ревью-процесса из CLAUDE.md. Запусти **один** сабагент -`jellybit-review-specs` (Agent tool, `subagent_type`) в режиме «дизайн/спеки ДО -кода». Charter самодостаточен — дай ссылку на change ``. Агент проверит -полноту покрытия, сценарии `GIVEN/WHEN/THEN`, scope, инварианты безопасности -данных, согласованность со спеками и capability-нарезкой, наличие `SHALL`/`MUST`. +Первый чекпоинт ревью-процесса. Вызови Skill **`review-pipeline`** с профилем +`design` и ссылкой на change ``. Он запустит `jellybit-review-specs` (режим +«дизайн/спеки ДО кода»), `jellybit-review-rubric` (фаза 1: приёмочные критерии +для задуманного узла), `jellybit-review-idiom` и `jellybit-review-architecture` +по предложению. -### 5. Отработать замечания ревью спек +Смысл профиля: архитектурная находка на готовом коде стоит переписывания и +потому игнорируется — та же находка здесь стоит абзаца обсуждения. Рубрику из +`jellybit-review-rubric` перенеси в `tasks.md` как приёмочные критерии. + +### 5. Отработать замечания ревью предложения - Мелочь и явные улучшения — правь сам в спеках/дизайне. - Развилки (компромисс, scope, инвариант) — на пользователя (AskUserQuestion). @@ -80,33 +84,38 @@ description: Автономно проводит задачу jellybit чере `docs/conventions/*`: ошибки stdlib с `%w`/`errors.Is`, логи только `slog` без секретов, время в UTC через `store.Now()`, ULID через `internal/ident`, миграции goose + синк ER-схемы `docs/specs/database.md`, htmx по web-ui-конвенции. -Прогони `task test` и `task lint` (или `task build`), добейся зелёного. +Прогони `task gate` и добейся зелёного — он же гейт следующего шага. **Поведенческая верификация (нетривиальные задачи с рантайм-поверхностью).** Если задача меняет реальное поведение (новый флоу, схема БД, эндпоинт/htmx-путь, разбор -входа) — зелёных юнит-тестов мало: прогони через Skill **`verify`**, чтобы -прокатить изменение end-to-end и увидеть его вживую, а не только в тестах. -Пропусти для чисто внутренних правок без наблюдаемого рантайма (рефактор, доки, -правка только тестов). Под `task-batch` verify идёт в worktree задачи — портами/БД -не конфликтуй с соседними прогонами. +входа) — зелёных юнит-тестов мало: прогони изменение вживую через Skill **`run`**, +чтобы увидеть его end-to-end, а не только в тестах. Пропусти для чисто внутренних +правок без наблюдаемого рантайма (рефактор, доки, правка только тестов). Под +`task-batch` запуск идёт в worktree задачи — портами/БД не конфликтуй с соседними +прогонами. -### 7. Ревью кода — сабагент(ы) +### 7. Ревью кода — Skill `review-pipeline` -Второй чекпоинт. Ревьюеры — кастомные агенты из `.claude/agents/` (запускай их -через Agent tool с `subagent_type`). Число зависит от тривиальности: +Второй чекпоинт. Вызови Skill **`review-pipeline`**, дав ссылку на change +``, базу диффа и профиль. Профиль выбирается по факту изменения, а не по +ощущению важности (правило — в самом скилле): -- **Тривиальная задача — один сабагент** `jellybit-review-code`. В промпте - добавь просьбу дополнительно **бегло сверить соответствие дельта-спекам и - tasks.md** (он единственный, покрывает и спеки, и конвенции). -- **Нетривиальная — два параллельных сабагента одним сообщением**, чтобы шли - конкурентно: `jellybit-review-specs` (оптика спек) и `jellybit-review-code` - (оптика архитектуры/конвенций/стиля). +- миграция, новый пакет, изменение публичного контракта, раскладка файлов/пути → + `deep`; +- иначе меняется поведение, видимое снаружи → `standard`; +- иначе (багфикс, локальная правка, доки) → `quick`. -Charter'ы агентов самодостаточны — детальный промпт писать не нужно, дай ссылку -на change (``) и diff/список файлов (`git diff`). +Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с +потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ +покрытия. -Отработай так же, как шаг 5: мелочь чини инлайн, развилки — на пользователя. -После правок — снова `task test`/`task lint`. +Отработай так же, как шаг 5: помеченное `инлайн` чини сам и не логируй, +`развилка` — на пользователя через AskUserQuestion (вопрос уже сформулирован +триажем). После правок — снова `task gate`. + +**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад +(шаг 10) сжатой строкой. Отчёт, из которого исчезло «что проверить было +невозможно», превращается в ложное ощущение проверенности. ### 8. Архивировать — `opsx:archive` @@ -139,7 +148,10 @@ Charter'ы агентов самодостаточны — детальный п шёл apply). Готово — доложи пользователю кратко: что сделано, какие развилки решались, ссылки -на архивный change и спеки. +на архивный change и спеки. **Плюс одна строка границ покрытия** из отчёта ревью: +какой профиль гонялся и что проверить было невозможно (пропущенный шаг гейта, +непокрытая ветка, вопрос, оставшийся человеку). Доклад без неё сообщает +«проверено», не сообщая, что именно. ## Тонкости @@ -148,9 +160,11 @@ Charter'ы агентов самодостаточны — детальный п пушь. При одиночном запуске это master, под `task-batch` — ветка задачи в своём worktree; поведение одинаковое. - Не пропускай `openspec validate --strict` перед архивацией. -- Тривиальная задача: шаги 2 и 4 пропускаются; ревью кода (шаг 7) оставляем, но - одним сабагентом на всё. Два параллельных ревьювера — только на нетривиальных. -- Если сабагент-ревьюер сам предлагает крупную переработку — это развилка, не - правь молча, вынеси пользователю. +- Тривиальная задача: шаги 2 и 4 пропускаются; ревью кода (шаг 7) остаётся + всегда, но в профиле `quick` — гейт, сверка со спекой, триаж. +- Гейт блокирует: пока `task gate` красный, опиниативные проходы не запускаются. + Чинить и перезапускать, а не «посмотреть заодно». +- Если ревью предлагает крупную переработку — это развилка, не правь молча, + вынеси пользователю. - Держи пользователя в цикле короткими репликами на переходах фаз, но не проси подтверждать механику. diff --git a/CLAUDE.md b/CLAUDE.md index 70687cf..657fee1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,9 +72,12 @@ - Сценарии — в формате `GIVEN/WHEN/THEN`. - `openspec validate --strict` перед коммитом change. -Ревью (процесс, не артефакт): нетривиальная задача — два чекпоинта (ревью -дизайна после design/specs, ДО кода; ревью кода после apply, до archive); -тривиальная — одного прохода по коду достаточно. +Ревью (процесс, не артефакт): два чекпоинта — профиль `design` на предложении +(после design/specs, ДО кода) и ревью изменения после apply, до archive. Оба +идут через скилл `.claude/skills/review-pipeline`: детерминированный гейт +(`task gate`) → сверка с дельта-спеками в обе стороны → generative-проходы → +триаж с потолком 7 находок. Профиль (`quick`/`standard`/`deep`) выбирается по +факту изменения, правило — в скилле. **Миграция:** capabilities постепенно переносятся из `docs/specs/` в OpenSpec (пилот — `ingest`). До переноса источник истины по теме — @@ -120,6 +123,9 @@ OpenSpec (пилот — `ingest`). До переноса источник ис - `task run` — локальный запуск (`go run ./cmd/jellybit --config ./config.toml`) - `task build` — статический бинарь `linux/amd64` для сервера - `task test` / `task lint` — тесты и golangci-lint +- `task gate` — детерминированный гейт ревью (build/vet/lint/test/race/покрытие + изменённых строк/миграции/секреты); блокирует опиниативные проходы ревью +- `task review:context` — карта проекта для архитектурного прохода ревью - `task tidy` — `go mod tidy` - `task image` — docker-образ из готового бинаря @@ -154,3 +160,7 @@ Module path — `git.vakhrushev.me/av/jellybit`. Go 1.26, `CGO_ENABLED=0`. Кросс-каттинг конвенции (как пишем код, а не что система делает) живут в [docs/conventions/](docs/conventions/README.md) и не переносятся в OpenSpec. +Механизируемое там **не держим**: правило уезжает в `.golangci.yml` или в +`internal/archrules` и вычёркивается из прозы и из промптов ревью — процедура в +[references/promote.md](.claude/skills/review-pipeline/references/promote.md). +Прозой остаётся только то, что правилом не выражается.