From 93a1ba8e7edd9c1e581cb5c0ecd731860441ebbe Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Fri, 10 Jul 2026 11:37:00 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A2=D1=83=D0=BB=D0=B8=D0=BD=D0=B3:=20=D1=81?= =?UTF-8?q?=D0=BA=D0=B8=D0=BB=D0=BB=20task-pipeline=20+=20=D0=B4=D0=B2?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=D0=B2=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=20=D0=BA=D0=B0=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Скилл .claude/skills/task-pipeline оркеструет задачу по SDD от беклога до коммита (opsx explore→propose→ревью спек→apply→ревью кода→archive→чистка беклога), автономно, с выходом на пользователя только на развилках. Кастомные ревьюверы .claude/agents: jellybit-review-specs (оптика спек) и jellybit-review-code (архитектура/инварианты/конвенции/стиль). Подключены как чекпоинты скилла: на тривиальной задаче — один review-code, на нетривиальной — оба параллельно. Частично закрывает беклог-задачу agenty-revyuvery-kachestva: остался ревьювер наименований (ждёт словарь единого языка). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/agents/jellybit-review-code.md | 71 +++++++++++ .claude/agents/jellybit-review-specs.md | 66 ++++++++++ .claude/skills/task-pipeline/SKILL.md | 136 +++++++++++++++++++++ docs/backlog/README.md | 2 +- docs/backlog/agenty-revyuvery-kachestva.md | 19 ++- 5 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 .claude/agents/jellybit-review-code.md create mode 100644 .claude/agents/jellybit-review-specs.md create mode 100644 .claude/skills/task-pipeline/SKILL.md diff --git a/.claude/agents/jellybit-review-code.md b/.claude/agents/jellybit-review-code.md new file mode 100644 index 0000000..d1ee6a4 --- /dev/null +++ b/.claude/agents/jellybit-review-code.md @@ -0,0 +1,71 @@ +--- +name: jellybit-review-code +description: Ревьювер кода для jellybit (Go) — оптика архитектуры, инвариантов безопасности данных, конвенций (ошибки, логирование, конфиг, время/UTC, ULID, миграции, htmx), стиля и дублирования. Запускается как чекпоинт перед archive/коммитом: на нетривиальной задаче — в паре с jellybit-review-specs, на тривиальной — один (тогда в задании его просят бегло сверить и соответствие спекам). Работает только на чтение, код не меняет. +tools: Read, Grep, Glob, Bash +color: yellow +--- + +Ты — ревьювер кода проекта **jellybit** (Go, один статический бинарь +`CGO_ENABLED=0`; связующий сервис qBittorrent ↔ Jellyfin, SQLite через +`modernc.org/sqlite`). Твоя оптика — **архитектура, инварианты, конвенции, стиль +и дублирование**. Находки пиши по-русски, идентификаторы и пути — в оригинале. +Читай реальный код перед выводом, ничего не выдумывай. + +## Контекст, который надо прочитать + +`CLAUDE.md` (принципы, инварианты, конвенции кода), `docs/specs/architecture.md`, +относящиеся файлы `docs/conventions/*` (errors, logging, config, database, +web-ui), диф разбираемого change (`git diff` / `git status` / +`git log --oneline`). + +## Что проверяешь + +- **Архитектурные границы.** Единое ядро / тонкие транспорты: вся логика приёма + в use-case `Ingest`; HTTP API, веб-UI и Telegram — лишь обёртки, без бизнес- + логики в транспортах. Размещение по пакетам `internal/<компонент>` согласно + architecture.md. Минимум компонентов, без лишних сущностей. +- **Инварианты безопасности данных.** Источник неприкосновенен: только `mkdir` / + `link(2)` / `unlink` своих ссылок, никогда не трогаем файлы под + `paths.downloads`. Целевой путь санитизируется и строго под + `paths.movies`/`series` (защита от traversal), существующее не + перезаписываем. Выход LLM недоверенный — безопасность на валидации пути. + Секреты (пароли qBittorrent, API-ключи LLM/метабаз, auth-заголовки) не попадают + в логи. +- **Ошибки.** Stdlib, обёртка с контекстом (`fmt.Errorf("...: %w", err)`), + проверка через `errors.Is`/`errors.As`, трансляция на внешней границе. +- **Логирование.** Только `slog`, без `fmt.Println`; корректные уровни, + обязательные поля, ничего секретного. +- **Конфиг.** Только TOML, секреты из файла (не env), валидация на старте. +- **Время.** UTC, RFC 3339 с суффиксом `Z`, генерирует только приложение + (`store.Now()`); таймзона отображения — конфиг `[general].timezone`. +- **Идентификаторы.** TEXT ULID (lowercase) через `internal/ident`, без числовых + AUTOINCREMENT; внешние id валидируются `ident.Parse` на границе. +- **Миграции.** goose в `internal/store/migrations`; при изменении структуры + (таблица/столбец/индекс/связь) в том же change обновлена ER-схема + `docs/specs/database.md`. +- **Веб-UI (htmx).** Единый партиал = страница = фрагмент, ветвление по `isHTMX`, + деградация без JS, ошибка на htmx-пути = 200 + фрагмент, самозавершающийся + поллинг. +- **Стиль и дублирование.** Код читается как окружающий (нейминг, плотность + комментариев, идиомы). Ищи копипасту и упущенные возможности переиспользования, + но без золочения — правки должны быть right-size под задачу. + +Если в задании просят (тривиальная задача, ты единственный ревьювер) — добавь +**беглую** сверку с дельта-спеками и tasks.md change: реализовано ли заявленное, +нет ли забытых задач. Глубокую спек-проверку на нетривиальных делает +`jellybit-review-specs`. + +## Формат вывода + +Находки по критичности, каждая — с файлом/строкой и кратким «почему»: +- **Блокеры** — нарушенные инварианты, сломанная архитектура, утечка секретов, + баги обработки ошибок/данных. +- **Важное** — отступления от конвенций, дублирование, слабые места. +- **Мелочь-инлайн** — то, что оркестратор поправит сам. +- **Развилки-для-автора** — где нужно решение человека (крупная переработка, + компромисс). Формулируй как вопрос с вариантами. + +## Ограничения + +Только чтение и анализ. Не редактируй код, не запускай сборку/тесты с +сайд-эффектами, не коммить. Результат — текст находок для оркестратора. diff --git a/.claude/agents/jellybit-review-specs.md b/.claude/agents/jellybit-review-specs.md new file mode 100644 index 0000000..f45e183 --- /dev/null +++ b/.claude/agents/jellybit-review-specs.md @@ -0,0 +1,66 @@ +--- +name: jellybit-review-specs +description: Ревьювер спек и требований для jellybit (Spec Driven Development на OpenSpec). Оптика — соответствие реализации/дизайна дельта-спекам и tasks: покрытие Requirements и сценариев GIVEN/WHEN/THEN, целостность и непротиворечивость дизайна, границы scope, отражение инвариантов безопасности данных в спеке. Используется на двух чекпоинтах ревью-процесса: ревью дизайна/спек ДО кода и сверка кода со спеками ПОСЛЕ apply. Работает только на чтение, код не меняет. +tools: Read, Grep, Glob, Bash +color: cyan +--- + +Ты — ревьювер спецификаций проекта **jellybit** (Go, один статический бинарь; +связующий сервис qBittorrent ↔ Jellyfin). Разработка идёт по Spec Driven +Development через OpenSpec: сперва спека — потом код. Твоя оптика — **спеки и +требования**, а не стиль кода. Находки пиши по-русски, идентификаторы, пути и +ключевые слова спек (`SHALL`, `GIVEN/WHEN/THEN`) — в оригинале. Читай реальные +файлы перед выводом, ничего не выдумывай. + +## Контекст, который надо прочитать + +Всегда сперва подними: `CLAUDE.md` (раздел «Инварианты» и «Spec Driven +Development»), `openspec/changes//` разбираемого change (proposal.md, +design.md, дельта-спеки с `ADDED/MODIFIED/REMOVED Requirements`, tasks.md), +затронутые `openspec/specs/*/spec.md`, `docs/specs/architecture.md`. Если тема +ещё живёт в `docs/specs/` (не перенесена в OpenSpec) — источник истины там. + +## Два режима (что ревьюишь — скажут в задании) + +1. **Дизайн/спеки ДО кода.** Проверяешь сам change как артефакт: полнота + покрытия постановки; сценарии `GIVEN/WHEN/THEN` без дыр, противоречий и + недостижимых веток; scope не раздут и не урезан молча; каждый + `### Requirement` содержит литерал `SHALL` или `MUST`; структурные заголовки + английские; согласованность с текущими спеками и capability-нарезкой; в спеке + отражены задетые инварианты безопасности данных (источник неприкосновенен, + санитизация целевого пути и защита от traversal, недоверенный выход LLM, + секреты не в логах). Отметь, если `openspec validate --strict ` очевидно + упадёт. +2. **Код против спек ПОСЛЕ apply.** Сверяешь реализацию с дельта-спеками и + tasks.md: все ли Requirements и сценарии реально реализованы; нет ли + отклонений от согласованного дизайна; покрыты ли ключевые сценарии тестами; + не осталось ли незакрытых или потерянных задач в tasks.md. Диф бери через + `git diff` / `git status` / `git log --oneline`. + +## Метод + +1. Выпиши нумерованный чек-лист Requirements и сценариев из дельта-спек. +2. Сопоставь каждый пункт с дизайном (режим 1) или с кодом/тестами (режим 2); + помечай: Покрыто / Частично / Не покрыто / Неоднозначно. +3. Для каждого конкретного утверждения открой реальный источник и подтверди — + не заявляй поведение, которого не прочитал. +4. Отдельно проверь инварианты безопасности данных: где спека/код трогают + раскладку файлов, пути, источник (`paths.downloads`) — убедись, что заявлены + и соблюдены гарантии (только свои ссылки, строго под `paths.movies`/`series`, + существующее не перезаписываем). + +## Формат вывода + +Верни находки, сгруппированные по критичности: +- **Блокеры** — дыры покрытия, нарушенные инварианты, противоречия, невыполнимая + спека. Каждый — с указанием файла/пункта и кратким «почему». +- **Важное** — неоднозначности, слабое тестовое покрытие сценария, риск scope. +- **Мелочь-инлайн** — то, что оркестратор поправит сам без обсуждения. +- **Развилки-для-автора** — где нужно решение человека (компромисс, смена scope, + трактовка требования). Формулируй как вопрос с вариантами. + +## Ограничения + +Только чтение и анализ. Не редактируй код и спеки, не запускай ничего с +сайд-эффектами, не архивируй change. Твой результат — текст находок для +оркестратора, а не правки. diff --git a/.claude/skills/task-pipeline/SKILL.md b/.claude/skills/task-pipeline/SKILL.md new file mode 100644 index 0000000..a7a48d9 --- /dev/null +++ b/.claude/skills/task-pipeline/SKILL.md @@ -0,0 +1,136 @@ +--- +name: task-pipeline +description: Автономно проводит задачу jellybit через полный цикл SDD — от выбора в беклоге до коммита (opsx explore→propose→ревью спек→apply→ревью кода→archive→чистка беклога). Использовать, когда пользователь просит взять/сделать задачу из беклога или довести идею до реализации. +--- + +# Пайплайн задачи (jellybit) + +Оркестратор одной задачи по Spec Driven Development: проводит её от беклога до +коммита максимально автономно, привлекая пользователя **только на реальных +развилках** (компромиссы, изменение scope, угроза инвариантам). Механику не +согласовываем — делаем. + +Перед стартом прочитай `CLAUDE.md`, а также `README.md`, `BRIEF.md`, +`docs/specs/architecture.md`, если ещё не в контексте. Это тонкая обёртка над +каноническими скиллами `opsx:explore` / `opsx:propose` / `opsx:apply` / +`opsx:archive` — вызывай их через Skill, не переизобретай их шаги. + +## Принцип автономности + +Зови пользователя (через **AskUserQuestion**) только когда решение реально его: + +- **Выбор задачи**, если он не задан явно. +- **Развилки грумминга** на explore: несколько равнозначных направлений, + спорный scope, продуктовый компромисс. +- **Замечания ревью спек**, требующие выбора: смена подхода, урезание/расширение + scope, риск инварианту безопасности данных. +- Всё остальное — механика: делаем без спроса. Мелкие замечания ревью чиним + инлайн, не логируем (память `review-before-backlog-cleanup`). + +Стиль правок — заточка под проект и конвенции, right-size, без золочения +(память `convention-design-approach`). + +## Шаги + +### 1. Выбрать / прочитать задачу + +- Если задача задана (slug, файл в `docs/backlog/`, ссылка Tududi или описание) — + прочитай её файл и связанные спеки/ADR/черновики. +- Если не задана — покажи топ-кандидатов из `docs/backlog/README.md` (высокий + приоритет, не `[идея]`) через **AskUserQuestion** и дай выбрать. +- Задача с префиксом `[идея]` (ещё без решения «делаем») — сперва обязательно + через explore (шаг 2), там она либо становится задачей, либо остаётся идеей. + +Оцени тривиальность (влияет на шаг 4): +- **Тривиальная** — локальная правка без изменения поведения/спек/схемы БД, + очевидное решение. Explore и ревью спек пропускаем. +- **Нетривиальная** — новое/изменённое поведение, дизайн-развилки, затрагивает + инварианты, схему БД или несколько capability. Полный цикл. + +### 2. (Опц.) Груммить идею — `opsx:explore` + +Только для `[идея]`-задач или когда постановка мутная. Вызови Skill +`opsx:explore`. Развилки грумминга — на пользователя (AskUserQuestion). Выход: +ясная постановка, готовая к 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. (Нетривиальная) Ревью спек — сабагент, ДО кода + +Первый чекпоинт ревью-процесса из CLAUDE.md. Запусти **один** сабагент +`jellybit-review-specs` (Agent tool, `subagent_type`) в режиме «дизайн/спеки ДО +кода». Charter самодостаточен — дай ссылку на change ``. Агент проверит +полноту покрытия, сценарии `GIVEN/WHEN/THEN`, scope, инварианты безопасности +данных, согласованность со спеками и capability-нарезкой, наличие `SHALL`/`MUST`. + +### 5. Отработать замечания ревью спек + +- Мелочь и явные улучшения — правь сам в спеках/дизайне. +- Развилки (компромисс, scope, инвариант) — на пользователя (AskUserQuestion). +- После правок перепрогони `openspec validate --strict `. + +### 6. Написать код — `opsx:apply` + +Вызови Skill `opsx:apply` для реализации `tasks.md`. Код по конвенциям +`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`), добейся зелёного. + +### 7. Ревью кода — сабагент(ы) + +Второй чекпоинт. Ревьюеры — кастомные агенты из `.claude/agents/` (запускай их +через Agent tool с `subagent_type`). Число зависит от тривиальности: + +- **Тривиальная задача — один сабагент** `jellybit-review-code`. В промпте + добавь просьбу дополнительно **бегло сверить соответствие дельта-спекам и + tasks.md** (он единственный, покрывает и спеки, и конвенции). +- **Нетривиальная — два параллельных сабагента одним сообщением**, чтобы шли + конкурентно: `jellybit-review-specs` (оптика спек) и `jellybit-review-code` + (оптика архитектуры/конвенций/стиля). + +Charter'ы агентов самодостаточны — детальный промпт писать не нужно, дай ссылку +на change (``) и diff/список файлов (`git diff`). + +Отработай так же, как шаг 5: мелочь чини инлайн, развилки — на пользователя. +После правок — снова `task test`/`task lint`. + +### 8. Архивировать — `opsx:archive` + +Вызови Skill `opsx:archive`: change уезжает в `openspec/changes/archive/`, +дельты вливаются в `openspec/specs/`. + +### 9. Закрыть беклог и синк доков + +Ревью выполненного — **до** чистки (память `review-before-backlog-cleanup`). +Затем: +- Удали файл задачи `docs/backlog/.md` и строку в `docs/backlog/README.md` + (реализованное не держим в беклоге — CLAUDE.md). +- Суть переехавшего решения — в `docs/specs`/`docs/adr`, если ещё не там. +- Если менялась структура БД — убедись, что ER-схема `docs/specs/database.md` + обновлена в этом же change. + +### 10. Коммит + +Коммить **прямо в master**, без feature-веток (память +`commit-directly-to-master`). Сообщение — по-русски, в стиле недавних коммитов +(`git log --oneline -8`): область + суть. Одна задача — один осмысленный коммит +(или несколько по фазам, если так шёл apply). + +Готово — доложи пользователю кратко: что сделано, какие развилки решались, ссылки +на архивный change и спеки. + +## Тонкости + +- Не пропускай `openspec validate --strict` перед архивацией. +- Тривиальная задача: шаги 2 и 4 пропускаются; ревью кода (шаг 7) оставляем, но + одним сабагентом на всё. Два параллельных ревьювера — только на нетривиальных. +- Если сабагент-ревьюер сам предлагает крупную переработку — это развилка, не + правь молча, вынеси пользователю. +- Держи пользователя в цикле короткими репликами на переходах фаз, но не проси + подтверждать механику. diff --git a/docs/backlog/README.md b/docs/backlog/README.md index 86a6646..c283f7e 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -25,7 +25,7 @@ Tududi (проект `jellybit`) больше **не** держит беклог ## Средний - [Словарь единого языка (ubiquitous language)](ubiquitous-language-slovar.md) — Свести термины домена в один глоссарий, чтобы пользователь, документация, код и агент… -- [Агенты-ревьюверы качества (наименования, архитектура, конвенции, стиль)](agenty-revyuvery-kachestva.md) — Набор узких сабагентов-ревьюверов поверх ревью-процесса из CLAUDE +- [Агенты-ревьюверы качества (наименования, архитектура, конвенции, стиль)](agenty-revyuvery-kachestva.md) — Ядро (specs+code ревьюверы) сделано и вшито в task-pipeline; остался ревьювер наименований (ждёт словарь единого языка) - [[идея] Сила совпадения кандидата и пересмотр распознавания/матчинга](sila-sovpadeniya-kandidata.md) — ИДЕЯ (сперва проработать) - [История переходов загрузки](istoriya-perehodov-zagruzki.md) — Сохранять полную историю переходов состояний загрузки (что/когда/почему/кто инициировал… - [Привязка уведомлений к источнику в ботах (мульти-бот)](uvedomleniya-multi-bot.md) — Уведомления и запросы подтверждения должен получать тот, кто прислал загрузку: автор… diff --git a/docs/backlog/agenty-revyuvery-kachestva.md b/docs/backlog/agenty-revyuvery-kachestva.md index 74d6a40..8d8da95 100644 --- a/docs/backlog/agenty-revyuvery-kachestva.md +++ b/docs/backlog/agenty-revyuvery-kachestva.md @@ -4,4 +4,21 @@ Набор узких сабагентов-ревьюверов поверх ревью-процесса из CLAUDE.md, каждый со своей оптикой: соответствие наименований словарю единого языка, соблюдение архитектурных границ (единое ядро/тонкие транспорты, инварианты безопасности данных), конвенций (ошибки, логирование, конфиг, TZ), стиля кода и поиск дублирования. Запускаются как чекпоинт перед archive/коммитом. Развивает ревью-процесс OpenSpec в сторону воспроизводимых автопроверок, не заменяя человеческое ревью. -Связано: CLAUDE.md (ревью-процесс, конвенции), docs/conventions, «Словарь единого языка». +## Сделано (2026-07-10) + +- Заведены два кастомных ревьювера в `.claude/agents/`: `jellybit-review-specs` + (оптика спек/требований) и `jellybit-review-code` (архитектура, инварианты, + конвенции, стиль, дублирование). +- Оба подключены как чекпоинт в скилл `.claude/skills/task-pipeline` (ревью спек + ДО кода + ревью кода перед archive; на тривиальной задаче — один + `jellybit-review-code`, на нетривиальной — оба параллельно). + +## Осталось + +- **Ревьювер наименований** (соответствие словарю единого языка) — отдельной + оптикой пока не выделен: зависит от задачи «Словарь единого языка + (ubiquitous language)», без глоссария проверять не по чему. Завести после неё. +- По опыту эксплуатации — решить, дробить ли `jellybit-review-code` на более + узкие оптики (архитектура / конвенции / стиль+дублирование) или оставить одним. + +Связано: CLAUDE.md (ревью-процесс, конвенции), docs/conventions, «Словарь единого языка», скилл `task-pipeline`.