Беклог теперь ведётся пользовательским скиллом `backlog` (заведение из диалога, разбор находок ревью, груминг, приоритизация, декомпозиция, штурм). CLAUDE.md делегирует ему формат и держит только проектные тонкости; добавлены источники задач (диалог, Tududi, находки ревью) и кладбище `docs/backlog/CLOSED.md` для выкинутого без реализации. - task-pipeline: шаги 1 и 9 больше не описывают формат сами, ссылаются на скилл; шаг 9 гоняет `backlog.py check` после удаления файла задачи. - review-pipeline: отложенная реальная находка (не для текущего мерджа) заводится задачей через скилл с тегом партии review-ГГГГ-ММ-ДД. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
16 KiB
name, description
| name | description |
|---|---|
| review-pipeline | Конвейер ревью изменений jellybit — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, generative-проходы (рубрика, независимая реализация, stdlib grounding, negative space), архитектура, враждебные постановки и обязательный триаж. Вызывается из task-pipeline (чекпоинты ревью), task-batch (финальная сверка) и отдельно — профилем design на OpenSpec-предложении ДО кода. |
Конвейер ревью (jellybit)
Готовит ревью — не заменяет его. Потребитель отчёта — оркестратор, который чинит код; человек читает только сводку, развилки и границы покрытия.
Три правила, из которых всё следует
Если ситуация не покрыта инструкцией — решай по ним.
- Recall чек-листа равен длине чек-листа. Проход, устроенный как «проверь пункты 1..N», найдёт ровно перечисленное. Всё неявное — идиомы, форма решения, «так не делают» — неперечислимо по определению: перечислимое уже стало бы конвенцией. Отсюда деление проходов на applicative (применяют заданный критерий) и generative (сперва порождают критерий или альтернативу, потом сравнивают). Расширять чек-листы бесполезно; неявный слой достают только generative-проходы.
- Ценность верификатора = наличие внешнего оракула × декорреляция с автором, а не число ролей. Под всеми ролями одна модель с одними априорными, вход у всех общий: седьмая роль почти не добавляет recall, но линейно удорожает триаж. Иерархия надёжности: детерминированный инструмент > агент, который его запускает и интерпретирует вывод > агент с чистым мнением. Максимум работы переносим вниз.
- Отчёт без границ покрытия хуже отсутствия отчёта. «Критичных проблем не обнаружено» потребляет ощущение проверенности, ничего не гарантируя. Секция границ покрытия обязательна и не сокращается — в том числе в докладе человеку.
Профили
| Профиль | Когда | Стадии |
|---|---|---|
quick |
багфикс, локальная правка, доки | 0, 1, 5 |
standard |
новая функциональность в существующем модуле | 0, 1, 2, 5 |
deep |
новый модуль/пакет, изменение публичного контракта, миграция БД, трогает инварианты безопасности данных | 0, 1, 2, 3, 4, 5 |
design |
до кода, на OpenSpec-предложении | rubric + idiom + architecture (см. ниже) |
Правило выбора — по факту изменения, не по ощущению важности:
- есть миграция в
internal/store/migrations/, новый пакетinternal/*, изменение сигнатуры публичной команды воркера или трогается раскладка файлов/пути →deep; - иначе меняется поведение, видимое снаружи (эндпоинт, htmx-путь, состояние
загрузки, формат сообщения бота) →
standard; - иначе →
quick.
Профиль объявляется в отчёте. Понижение профиля — решение оркестратора, и оно попадает в границы покрытия строкой «профиль понижен до X, потому что …».
Стадия 0 — Gate (обязательна во всех профилях)
Агент jellybit-review-gate. Запускает task gate и интерпретирует вывод.
Пока гейт красный — опиниативные проходы не запускаются. Оркестратор чинит и перезапускает гейт. Исключение одно: отказ, унаследованный от базовой ветки (гейт проверяет это прогоном на базе) — тогда он фиксируется находкой и не блокирует.
Гейт возвращает не только «зелено/красно», но и находки класса отсутствующая
верификация: изменённые строки без покрытия, конкурентность без теста с
параллельным доступом, флаки-тест (не ниже major), недоступный инструмент.
Шаги выбираются по изменённым файлам: правка документации не гоняет тесты,
линтеры и -race. Пропуск при этом не молчит — он виден в сводке с причиной и
уезжает в границы покрытия, как и любой другой SKIP.
Стадия 1 — Conformance (обязательна во всех профилях)
Два applicative-прохода: оба применяют записанный критерий, оба дешёвые, запускаются одним сообщением параллельно.
jellybit-review-specs— критерий взят из дельта-спек change вopenspec/changes/<id>/specs/, а не из proposal, сообщения коммита или описания задачи. Сверка двунаправленная; направлениеcode → specважнее.jellybit-review-code— критерий взят изdocs/conventions/*.md, и только та его часть, которая не выражается правилом: механизируемое уже проверила стадия 0. Уровень лога по адресату, единственный логирующий чокпоинт, новая ветвь отказа вhttpapi.classifyErr, транзиентный ответ против персистентной диагностики,ident.Parseна входной границе, htmx-партиалы.
Recall обоих равен длине их источника — это и есть предел applicative-проходов, ради которого существует стадия 2.
Стадия 2 — Tacit layer (generative; standard, deep)
Четыре прохода, каждый в своём контексте, запускаются одним сообщением параллельно:
jellybit-review-rubric— порождает рубрику до чтения кода, потом судит по ней;jellybit-review-reimpl— пишет свою реализацию, не открывая существующую, затем диффит по решениям (в профилеstandardвключается только если изменение содержит новый файл или функцию длиннее ~60 строк — иначе дорог и бесполезен);jellybit-review-idiom— заземляет «идиоматичность» на stdlib и поимённые положения гайдов;jellybit-review-negative— чего нет и что лишнее.
Стадия 3 — Global (deep, design)
Агент jellybit-review-architecture. Получает вход шире диффа: дерево
пакетов с назначением, граф внутренних зависимостей, инвентарь существующих
концепций проекта. Готовит вход команда:
task review:context > tmp/review-context.md
Главный вопрос — концептуальная целостность и второй способ делать то, что уже делается. Потолок — 3 находки плюс секция «дешевле переделать до мерджа».
Стадия 4 — Adversarial и operational (deep)
jellybit-review-adversary (находка = построенный путь, не свойство) и
jellybit-review-ops (постмортем от симптома у владельца сервиса к строке).
Запускаются параллельно со стадией 2, если профиль deep.
Стадия 5 — Triage (обязательна)
Агент jellybit-review-triage. Единственный, кто агрегирует. Получает сырые
выводы всех проходов и git diff; возвращает финальный отчёт.
Без триажа шесть проходов дают порядка сорока замечаний при единицах существенных. Потребитель здесь — оркестратор, который молча реализует всё, что прочитал: цена нетриажированного отчёта — не потерянное время человека, а разросшийся от вкусовщины код.
Порядок: дедупликация по причине → оракул для всего critical/major →
понижение неподтверждённого до гипотезы → отсев вкусовщины → ранжирование по
ущербу × вероятности → потолок 7 пунктов в основном списке.
Профиль design — до кода
Запускается на шаге ревью спек (task-pipeline шаг 4), когда change уже имеет
proposal.md + дельта-спеки, но кода ещё нет. Состав:
jellybit-review-specsв режиме «дизайн ДО кода» — как раньше;jellybit-review-rubric, фаза 1 без фазы 2: рубрика на задуманный узел становится приёмочными критериями и уезжает вtasks.md;jellybit-review-idiomпо описанию решения (какие конструкции stdlib закрывают задачу; не изобретаем ли то, что уже есть);jellybit-review-architectureна предложении: вводит ли change новое понятие, можно ли выразить существующими, не появляется ли второй способ;- вопрос автору дизайна: «предложи три формы решения и назови компромисс каждой» — если ответ показывает, что рассматривалась одна, это находка.
Смысл профиля: архитектурная находка на готовом коде стоит переписывания и поэтому игнорируется; та же находка на предложении стоит абзаца обсуждения.
Контракт находок
Единый для всех проходов — references/finding-contract.md.
Коротко: заголовок через последствие, обязательные поля Файл, Severity,
Confidence, Оракул, Последствие, Предложение, Найдено проходом.
critical без оракула или построенного пути не существует. Находка без поля
«Последствие» не выводится вовсе.
Каждый проход завершает вывод блоком ## Coverage of this pass.
Что происходит с находками дальше
- Оркестратор чинит помеченное
Действие: инлайни не логирует мелочь. Действие: развилка— на человека черезAskUserQuestion, вопросом с вариантами.- Находка не для этого мерджа, но реальная (отложенный
major, развилка, решённая «потом») — не теряется: заводится задачей через скиллbacklog(интейк из ревью), с оракулом и провенансом в теле. Мелочь классаnit— в пакетный файл, а не файлом на находку. Promote candidates— по процедуре references/promote.md: находка → конвенция → правило линтера → удаление из конвенций и из промптов. Третий шаг обязателен.- Дефект, проскочивший ревью и всплывший позже, идёт в docs/review/journal.md — сразу, не ретроспективно: теряется именно причина непоймания.
Честный предел
Модель воспроизводит медиану публичного Go, смещённую к популярному и туториальному: отсюда тяга к интерфейсам ради интерфейсов, лишним мокам и конфигурируемости, которую никто не просил. «Идиоматично» и «распространено» — разные вещи; проходы обязаны различать их и опираться на поимённое положение гайда, а не на ощущение частотности.
Согласие нескольких проходов — не подтверждение: это один источник,
высказавшийся несколько раз. Совпадение повышает приоритет, но не confidence.
Ни одному проходу принципиально недоступно:
- история инцидентов на umbar и то, что уже ломалось в проде;
- поведение таблицы SQLite под реальным объёмом и профилем нагрузки;
- завязка внешних потребителей (Jellyfin, бот, закладки) на текущее поведение;
- суждение «этой фичи не должно существовать».
Это и есть причина, по которой конвейер готовит ревью, а не заменяет его.
Ссылки
- references/finding-contract.md — контракт находок.
- references/promote.md — промоут находка → конвенция → правило → удаление.
- references/calibration.md — калибровка инъекцией, вердикты keep/retune/drop.
- references/migration-2026-07.md — отчёт «было → стало» по переработке конвейера.
- docs/review/journal.md — журнал проскочивших дефектов.