From 7473cbd6d3984c7519ad10bc164710e5859fe084 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 23 Jul 2026 19:41:57 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E:=20=D0=B2=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B8=D1=82=D1=8C=20review-code=20=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=B4=D0=B8=D0=B5=D0=B9=201=20=D0=B8=20=D1=83?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20=D1=82=D1=80=D0=B8=20=D0=B8?= =?UTF-8?q?=D0=B7=D0=B1=D1=8B=D1=82=D0=BE=D1=87=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По итогам разбора собственной работы. jellybit-review-code не запускался нигде: charter обещал «проход профиля quick», а quick состоял из стадий 0, 1, 5. Проход, который нельзя запустить, нельзя и откалибровать. Теперь он стадия 1 рядом с review-specs — оба applicative, у обоих критерий записан, различаются источники (дельта-спека и конвенции). review-context.sh больше не выгружает go doc -short по всему модулю: это было 264 строки из 458 при том, что граф зависимостей — единственное, чего агент не восстановит сам, — занимает 21. Публичную поверхность он вытянет go doc по нужному месту. Из calibration.md убрана секция дополнительных метрик: precision, корреляция и стоимость прогона вручную никем не считаются, а набор показателей, который не собирают, изображает измеряемость вместо того, чтобы её давать. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../agents/jellybit-review-architecture.md | 9 +++--- .claude/agents/jellybit-review-code.md | 12 ++++---- .claude/skills/review-pipeline/SKILL.md | 21 ++++++++++---- .../review-pipeline/references/calibration.md | 18 ++++-------- .../references/migration-2026-07.md | 29 ++++++++++++++++--- Taskfile.yml | 2 +- scripts/review-context.sh | 23 ++++----------- 7 files changed, 66 insertions(+), 48 deletions(-) diff --git a/.claude/agents/jellybit-review-architecture.md b/.claude/agents/jellybit-review-architecture.md index 669ac55..9349f5b 100644 --- a/.claude/agents/jellybit-review-architecture.md +++ b/.claude/agents/jellybit-review-architecture.md @@ -1,6 +1,6 @@ --- name: jellybit-review-architecture -description: Архитектурный проход ревью jellybit — получает вход шире диффа (дерево пакетов, публичные интерфейсы, граф внутренних зависимостей, инвентарь существующих концепций через task review:context). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими, не появился ли второй способ делать то, что уже делается. Потолок 3 находки + секция «дешевле переделать до мерджа». Работает и на OpenSpec-предложении до кода (профиль design). Только чтение. +description: Архитектурный проход ревью jellybit — получает вход шире диффа (дерево пакетов, граф внутренних зависимостей, инвентарь существующих концепций через task review:context). Главный вопрос — концептуальная целостность: вводит ли изменение новое понятие, можно ли выразить существующими, не появился ли второй способ делать то, что уже делается. Потолок 3 находки + секция «дешевле переделать до мерджа». Работает и на OpenSpec-предложении до кода (профиль design). Только чтение. tools: Read, Grep, Glob, Bash color: yellow --- @@ -19,9 +19,10 @@ color: yellow task review:context > tmp/review-context.md ``` -Даёт: пакеты с назначением, граф внутренних зависимостей, публичную поверхность -каждого пакета, инвентарь концепций (доменные ошибки, состояния загрузки, секции -конфига, публичные команды воркера, capabilities OpenSpec). +Даёт: пакеты с назначением, граф внутренних зависимостей, инвентарь концепций +(доменные ошибки, состояния загрузки, секции конфига, публичные команды воркера, +capabilities OpenSpec). Публичную поверхность пакетов он намеренно не выгружает — +`go doc <пакет>` по нужному месту дешевле, чем дамп по всему модулю. Плюс: `docs/specs/architecture.md`, `CLAUDE.md`, дельта-спеки change. Дифф — последним, не первым: он должен ложиться на карту, а не задавать её. diff --git a/.claude/agents/jellybit-review-code.md b/.claude/agents/jellybit-review-code.md index 6ab175d..6f365b9 100644 --- a/.claude/agents/jellybit-review-code.md +++ b/.claude/agents/jellybit-review-code.md @@ -1,14 +1,16 @@ --- name: jellybit-review-code -description: Дешёвый applicative-проход ревью jellybit по конвенциям, которые НЕ выражаются правилом линтера: уровень лога по адресату, единственный логирующий чокпоинт, трансляция доменной ошибки на внешней границе, транзиентный ответ против персистентной диагностики, конфиг и его образец, htmx-партиалы, ident.Parse на границе. Механизируемое проверяет task gate, архитектуру — jellybit-review-architecture, стиль и лишнее — generative-проходы. Только чтение. +description: Стадия 1 конвейера review-pipeline (во всех профилях, параллельно с jellybit-review-specs) — дешёвый applicative-проход по конвенциям, которые НЕ выражаются правилом линтера: уровень лога по адресату, единственный логирующий чокпоинт, трансляция доменной ошибки на внешней границе, транзиентный ответ против персистентной диагностики, конфиг и его образец, htmx-партиалы, ident.Parse на границе. Механизируемое проверяет task gate, архитектуру — jellybit-review-architecture, стиль и лишнее — generative-проходы. Только чтение. tools: Read, Grep, Glob, Bash color: blue --- -Ты — проход по **прозаическим конвенциям** jellybit. Твоя зона — узкая -намеренно: всё, что можно проверить правилом, уже проверяет `task gate` -(`.golangci.yml` + `internal/archrules`), и повторять это в промпте вредно — -внимание, потраченное на именование полей лога, не доходит до формы решения. +Ты — проход по **прозаическим конвенциям** jellybit, стадия 1 конвейера +`review-pipeline` (идёшь параллельно с `jellybit-review-specs`, во всех +профилях). Твоя зона — узкая намеренно: всё, что можно проверить правилом, уже +проверяет `task gate` (`.golangci.yml` + `internal/archrules`), и повторять это +в промпте вредно — внимание, потраченное на именование полей лога, не доходит до +формы решения. Находки — по контракту `.claude/skills/review-pipeline/references/finding-contract.md`. Русская проза, diff --git a/.claude/skills/review-pipeline/SKILL.md b/.claude/skills/review-pipeline/SKILL.md index cda19b4..9059263 100644 --- a/.claude/skills/review-pipeline/SKILL.md +++ b/.claude/skills/review-pipeline/SKILL.md @@ -65,9 +65,20 @@ description: Конвейер ревью изменений jellybit — дет ## Стадия 1 — Conformance (обязательна во всех профилях) -Агент `jellybit-review-specs`. Источник требований — **дельта-спеки change в -`openspec/changes//specs/`**, а не proposal, не сообщение коммита и не -описание задачи. Сверка двунаправленная; направление `code → spec` важнее. +Два applicative-прохода: оба применяют **записанный** критерий, оба дешёвые, +запускаются **одним сообщением параллельно**. + +- `jellybit-review-specs` — критерий взят из **дельта-спек change в + `openspec/changes//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`) @@ -86,8 +97,8 @@ description: Конвейер ревью изменений jellybit — дет ## Стадия 3 — Global (`deep`, `design`) Агент `jellybit-review-architecture`. Получает **вход шире диффа**: дерево -пакетов с назначением, публичные интерфейсы, граф внутренних зависимостей, -инвентарь существующих концепций проекта. Готовит вход команда: +пакетов с назначением, граф внутренних зависимостей, инвентарь существующих +концепций проекта. Готовит вход команда: ``` task review:context > tmp/review-context.md diff --git a/.claude/skills/review-pipeline/references/calibration.md b/.claude/skills/review-pipeline/references/calibration.md index f0f02d8..51cee50 100644 --- a/.claude/skills/review-pipeline/references/calibration.md +++ b/.claude/skills/review-pipeline/references/calibration.md @@ -51,18 +51,12 @@ | `jellybit-review-ops` | деградация зависимости | убрать обработку недоступности qBittorrent в фоновом цикле | | `jellybit-review-triage` | шум | подать 20 находок, из них 15 вкусовщина и 3 дубля — проверить потолок и дедуп | -## Дополнительные метрики - -Собираются попутно, в журнале прогонов (свободной формой, там же где вердикты): - -- **precision** — доля находок, отвергнутых при ревью. Если отвергается меньше - трети — хорошо; если больше — триаж съедает больше, чем экономит проход. -- **корреляция между проходами** — стабильно одинаковые находки у двух проходов - означают, что один лишний. Смотрится по полю `Найдено проходом` в - триажированных отчётах. -- **стоимость прогона** — токены и время. Профиль `deep` дороже `standard` - примерно на порядок; если разница в найденном не видна, состав профиля - пересматривается. +Метрик сверх этого не заводим. Precision, корреляция между проходами, стоимость +прогона в токенах — всё это красиво звучит и никем не считается вручную; набор +показателей, который не собирают, создаёт впечатление измеряемости и тем вреден. +Работает ровно один механизм: инъекция дефекта и вердикт. Если корреляция двух +проходов действительно бросается в глаза — это видно по полю `Найдено проходом` +в триажированных отчётах и без отдельной метрики. ## Когда калибровать diff --git a/.claude/skills/review-pipeline/references/migration-2026-07.md b/.claude/skills/review-pipeline/references/migration-2026-07.md index e5aea09..ac27f48 100644 --- a/.claude/skills/review-pipeline/references/migration-2026-07.md +++ b/.claude/skills/review-pipeline/references/migration-2026-07.md @@ -24,7 +24,7 @@ | `task test`/`task lint` внутри apply, lefthook на коммите | **Stage 0** `jellybit-review-gate` + `task gate`: build, vet, lint, gofmt, тесты, повтор на флаки, `-race`, покрытие изменённых строк, миграции, ER-схема, gitleaks, govulncheck. Блокирует опиниативные проходы | детерминированный оракул надёжнее мнения; проверка, идущая после ревью, не защищает ревью | | `jellybit-review-specs`: spec → code | **Stage 1** он же + **code → spec** (тихие ветки, самодеятельные дефолты, проглоченные ошибки, незаказанные ретраи), границы спеки, право сказать «требование неверно» | системная болезнь агентского кода — тихо добавленное поведение; односторонняя сверка его не видит | | — | **Stage 2** `jellybit-review-rubric`, `jellybit-review-reimpl`, `jellybit-review-idiom`, `jellybit-review-negative` | recall чек-листа равен его длине; неявный слой достаётся только порождением критерия | -| архитектура как один из 9 буллетов `review-code`, вход = дифф | **Stage 3** `jellybit-review-architecture`, вход = `task review:context` (пакеты, граф зависимостей, публичная поверхность, инвентарь концепций) + дифф. Потолок 3 находки | агент, видящий только дифф, не знает словаря проекта и потому не может судить о втором способе делать то же самое | +| архитектура как один из 9 буллетов `review-code`, вход = дифф | **Stage 3** `jellybit-review-architecture`, вход = `task review:context` (пакеты, граф зависимостей, инвентарь концепций) + дифф. Потолок 3 находки | агент, видящий только дифф, не знает словаря проекта и потому не может судить о втором способе делать то же самое | | — | **Stage 4** `jellybit-review-adversary` (находка = построенный путь), `jellybit-review-ops` (условный постмортем) | враждебная постановка находит то, чего не находит перечисление свойств | | разгребал оркестратор вручную | **Stage 5** `jellybit-review-triage`: дедуп по причине, оракул для critical/major, понижение неподтверждённого, отсев вкусовщины, потолок 7, разметка `инлайн`/`развилка` | отчёт читает оркестратор и молча реализует прочитанное: без потолка узкое место переезжает в незаказанные правки кода | | `review-code`: 9 углов, включая механизируемое | `review-code` сжат до конвенций, **не выраженных правилом** | всё, что проверяет линтер, в промпте только отвлекает внимание | @@ -37,9 +37,30 @@ `jellybit-review-code` в отдельные проходы с разными классами дефектов; per-capability прогон в `task-batch` сужен до стыков вместо повторного полного ревью. -- **Удалено:** ничего. Существующий проход не удаляется без замера — сначала - калибровка (`calibration.md`), потом решение. `jellybit-review-code` оставлен - как дешёвый проход профиля `quick`. +- **Удалено:** ни одного прохода. Существующий проход не удаляется без замера — + сначала калибровка (`calibration.md`), потом решение. `jellybit-review-code` + остался стадией 1 рядом с `jellybit-review-specs`: оба applicative, критерий у + обоих записан, только источники разные (дельта-спека и конвенции). + +## Правка по итогам самопроверки (2026-07-23) + +Разбор собственной работы нашёл три избыточности; все три устранены: + +- `jellybit-review-code` **не запускался ни в одном профиле** — charter обещал + «проход профиля `quick`», а `quick` состоял из стадий 0, 1, 5. Проход, который + нельзя запустить, нельзя и откалибровать. Включён стадией 1. +- `scripts/review-context.sh` выгружал `go doc -short` по всему модулю — 264 + строки из 458. Убрано: граф зависимостей, который иначе не восстановить, — это + 21 строка, а публичную поверхность агент вытянет `go doc` сам по нужному месту. +- Из `calibration.md` убрана секция «дополнительных метрик» (precision, + корреляция, стоимость): показатели, которые никто не считает, изображают + измеряемость вместо того, чтобы её давать. + +Под подозрением остались `jellybit-review-idiom` (собственные правила загоняют +почти все его находки в `minor`) и половина вопросов `jellybit-review-ops` +(рост объёма в 50 раз для однопользовательского домашнего сервиса умозрителен). +Не тронуты намеренно: удалять проход по ощущению, а не по замеру — ровно то, +против чего написана процедура калибровки. ## Конвенции → правила diff --git a/Taskfile.yml b/Taskfile.yml index b062cc4..96ef8b1 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -47,7 +47,7 @@ tasks: - bash scripts/gate.sh {{.BASE}} review:context: - desc: 'Вход для архитектурного прохода ревью: пакеты, граф зависимостей, публичная поверхность, инвентарь концепций' + desc: 'Вход для архитектурного прохода ревью: пакеты, граф зависимостей, инвентарь концепций' cmds: - bash scripts/review-context.sh diff --git a/scripts/review-context.sh b/scripts/review-context.sh index c3b7acd..f634590 100755 --- a/scripts/review-context.sh +++ b/scripts/review-context.sh @@ -3,8 +3,12 @@ # # Агент, видящий только `git diff`, физически не может судить об архитектуре — # он не знает, какие понятия в проекте уже есть и как они называются. Скрипт -# собирает дерево пакетов с назначением, публичную поверхность, граф внутренних -# зависимостей и инвентарь существующих концепций. +# собирает дерево пакетов с назначением, граф внутренних зависимостей и +# инвентарь существующих концепций. +# +# Публичную поверхность пакетов намеренно НЕ выгружаем: дамп `go doc -short` по +# всему модулю занимал больше половины вывода, а агент вытянет `go doc` по +# нужному пакету сам. Здесь — только то, что иначе не восстановить. # # Использование: scripts/review-context.sh [> tmp/review-context.md] @@ -39,21 +43,6 @@ done echo '```' echo -echo "## Публичная поверхность пакетов" -echo -echo "Экспортированные типы, интерфейсы и функции — то, чем пакеты договариваются." -echo -for p in $PKGS; do - short="${p#"$MOD"/}" - body="$(go doc -short "$p" 2>/dev/null | grep -v '^$' || true)" - [ -z "$body" ] && continue - echo "### $short" - echo '```go' - echo "$body" - echo '```' - echo -done - echo "## Инвентарь концепций" echo echo "Как в проекте уже называются вещи. Новое понятие вводим, только убедившись,"