diff --git a/docs/reviews/CODE-REVIEW-750-r1.md b/docs/reviews/CODE-REVIEW-750-r1.md new file mode 100644 index 00000000..19749d02 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-750-r1.md @@ -0,0 +1,179 @@ +# CODE-REVIEW-750-r1 + +**Issue:** #750 — «Процесс: бюджет слов промпта код-ревью исчерпан (1400 из 1400)» +**Этап:** code · **Трек:** show · **Заход:** r1 · блокирующих циклов 0/2 +**Материал ревью:** `792ad57c3e2700aea3beaaf6189913d2a29eb523` (рабочая копия на нём, `git status` чист) + +## Скоуп + +Чисто процессная/инфраструктурная правка, без продуктового кода: + +- `.github/workflows/_process.yml` — из промпта шага Review убраны мёртвый + фрагмент про мутанты (`needs.prepare.outputs.mutants` всегда `false` с + #709) и фраза «Отсутствие мутантов по диффу — не находка» (правило всех + треков, уже в REVIEWER.md «Трек show»); три абзаца-пересказа (повторный + раунд, объём гейтов, серьёзность/вердикт) заменены однострочными ссылками + на разделы `docs/process/REVIEWER.md`. +- `docs/process/REVIEWER.md` — приняты фразы, которых конспект раньше не + нёс: дельта ТЗ — дифф тела issue; «строкой кода или текста, а не + заявлением автора»; сомнение в локальности — полный разбор; три разных + ответа `smoke-select` (с ссылкой на `docs/TESTING.md`); геометрия без + инвариантов в отчёте — непрогнанный гейт. +- `test/process-digests.test.mjs` — новый тест AC2 (ссылки промпта на + REVIEWER.md ведут на существующие разделы, перенесённое на месте) и + утверждения AC1 (в промпте нет мёртвого `outputs.mutants` и фразы + «Отсутствие мутантов»). + +Напрямую обслуживает «Правило №1»/поддержание самого ревью-конвейера +(AGENTS.md), а не строку `docs/SCOPE.md` — это инфраструктура процесса, не +продуктовая фича; трек `show`, скоуп и серьёзность по +`docs/process/REVIEWER.md`, «Трек show». + +`_process.yml` — тело вызывается `@dev` (`.github/workflows/process.yml:30`), +поэтому правка вступит в силу только после слияния в `dev`; сам PR не меняет +поведение текущего прогона конвейера. Указано в issue (раздел +«Зависимости») и подтверждено чтением `process.yml`. + +## Как проверялось + +### AC1 — запас бюджета + +- Прочитан диапазон промпта `prompt: |` … `claude_args: |` в `_process.yml` + после правки: фрагмента про мутанты и фразы «Отсутствие мутантов по + диффу — не находка» нет; строка трека осталась `Трек: … (PROCESS.md §5)`. +- `grep -n "outputs.mutants|Отсутствие мутантов" .github/workflows/_process.yml` + — совпадения вне промпт-блока (другие job, передача `MUTANTS` в шаги + Validate/публикации), внутри промпта — ни одного. +- Подсчёт слов тем же алгоритмом, что в тесте (`split(/\s+/)` между теми же + границами): **1130** слов. Тест `words <= 1400` зелёный, порог не снижен — + это соответствует явному пункту ТЗ «Порог 1 400 не снижается». + Буквальный оракул AC1 «Промпт ≤ 1150 слов» читаю как факт о результате + (1130 ≤ 1150 — да), а не как требование к жёсткому порогу теста: сам текст + ТЗ («Что меняется») прямо говорит, что порог остаётся 1400, и автор это + решение в «Отклонениях» объясняет тем же аргументом. Противоречие + заложено в самом ТЗ, не привнесено реализацией; фактический результат + условие выполняет. +- **Тест умеет падать**: временно подменил `_process.yml` и `REVIEWER.md` + версиями из `origin/dev`, прогнал `node --test test/process-digests.test.mjs` + — тесты «#634 конспект вместо пересказа…» и «#750 AC2…» краснеют с + понятной причиной (`промпт не ссылается на «Повторный раунд»` и т.п.), + затем вернул рабочую копию `git checkout HEAD -- …` (`git status` после + этого чист). На текущем SHA все 6 тестов `process-digests.test.mjs` зелёные. + +### AC2 — ссылки ведут в существующие разделы + +- `grep -n "^## " docs/process/REVIEWER.md` — разделы «Трек show», + «Повторный раунд», «Объём гейтов», «Находки и вердикт» существуют, именно + на них ссылается промпт (сверено текстом промпта построчно). +- Перенесённые фразы на месте и дословны тем, что было в промпте: в «Объём + гейтов» — три ответа `smoke-select` («НЕОПРЕДЕЛЁННОСТЬ» / «связь не + доказана» со ссылкой на `docs/TESTING.md#локальный-набор-перед-пушем-343` + — заголовок существует, `grep` подтвердил) и строка про инварианты + геометрии; в «Повторный раунд» — «дифф тела issue», «строкой кода или + текста, а не заявлением автора», «Сомнение в локальности — полный + разбор». +- Тест `process-digests.test.mjs` подтверждён падающим на старом файле (см. + AC1) и зелёным на текущем. + +### AC3 — вход ревьюера и гейт + +- `node scripts/entry-cost.mjs` → `reviewer: 4849 слов (бюджет 9000)` — + совпадает с цифрой из комментария автора. +- `node --test test/entry-cost.test.mjs` — 4/4 зелёных. +- `node --test test/process-track.test.mjs test/review-doc-guard.test.mjs` — + 108/108 зелёных (тесты, которые читают промпт как текст, по списку из AC3). +- `node scripts/mutation-gate.mjs --check` — `ok` по всем проверкам, + предупреждение `browser guards: 205/200` то же, что до правки (не новое). +- `node scripts/reviews-index.mjs --dir=docs/reviews --check` — «свеж». +- `node scripts/smoke-select.mjs --base origin/dev --head HEAD` — + «Исполняемого frontend-диффа нет (`src/**/*.ts` не тронут)»: смоки не + выбираются, потому что выбирать нечего (ни один файл диффа не входит в + граф исполнения браузерных смоков). Решение: не прогонял — инструмент + прямо говорит, что выбирать нечего, а не «неопределённость». +- `npm run gate:small` не стал перегонять локально — упёрся в таймаут + инструмента (110 c, включает tsc+test+build), а дешёвые гейты (tsc, test, + build, bundle-policy) этого SHA уже подтверждены зелёным Validate + (ссылка в задаче ревью). AC3 для `gate:small` опирается на тот же + зелёный прогон плюс целевые юнит-тесты выше. +- `actionlint` бинарник недоступен в окружении ревью (`which actionlint`, + `npx actionlint` — не резолвится). Прецедент — CODE-REVIEW-730-r4: то же + ограничение среды, то же основание (заявление автора + синтаксическая + валидность YAML, подтверждённая тем, что GitHub принял и исполнил событие + `issues: labeled` по этому файлу на этом SHA — сам факт, что конвейер + дошёл до публикации этого ревью, означает, что `_process.yml` синтаксически + валиден). Не являюсь независимым доказательством качества самого + `actionlint`-прогона автора, но YAML-синтаксис и структура `${{ }}` + выражений проверены чтением всего изменённого диапазона (строки 1150–1300) + — сбалансированы кавычки и скобки, условные выражения не изменили форму + (убраны только литеральные фрагменты текста внутри строковых значений). + +### Трейлеры и changelog + +- Один коммit `792ad57c`: `Issue: #750`, `User-Visible: no` — корректно, + правка не меняет видимое поведение продукта. `CHANGELOG.md` / + `CHANGELOG.ru.md` не тронуты — ожидаемо. + +### §5-критерий (трек show) + +Все шесть критериев §5 пройдены: сложность 2/10 (автор), одна логическая +поверхность (промпт ревьюера + его конспект + тест, связанные одной темой), +без миграции конфигов, без нового UX-контракта (внутренний процесс, не +продукт), без влияния на производительность/touch, ожидаемое поведение уже +зафиксировано в #634 и ТЗ issue. `route: fix`. + +## Что проверено и корректно + +- Мёртвый код и пересказ убраны именно там, где заявлено; ничего лишнего не + зацепило. +- Перенос в REVIEWER.md полный: ни одна фраза, которую ТЗ помечало к + переносу, не потеряна. +- Тесты не декоративные — подтверждено прогоном на старом и новом + состоянии файлов. +- Бюджет входа ревьюера (9000 слов) не исчерпан — у задачи #750 остаётся + запас на будущее (4849 из 9000), а у промпта (1400 слов) — 270 слов + запаса. +- Изменение не трогает продуктовый код, `src/**`, `custom_components/**` + — гейты golden/pytest/invariants/performance неприменимы по диффу. + +## Чего не проверял + +- `npm run gate:small` целиком локально — таймаут инструмента; опирался на + зелёный Validate этого SHA (ссылка в задаче) для дешёвых частей + (`tsc --noEmit`, `npm test`, `npm run build`, сверка бандла) и на + целевые юнит-тесты выше для специфичных для #750 частей. +- `actionlint` как отдельный бинарник — недоступен в среде ревью; заявление + автора «чистый» принято по прецеденту CODE-REVIEW-730-r4, YAML-диапазон + проверен чтением. +- Браузерные смоки, `golden:verify`, `pytest tests_backend`, инварианты + модели, performance-профили — не прогонял, диффу/AC неприменимы + (`smoke-select` подтвердил отсутствие исполняемого frontend-диффа; нет + меток `ci:golden`; нет правок `custom_components/**/*.py`; нет правок + геометрии). +- Ручное/визуальное тестирование — неприменимо, задача не меняет ничего + рендеримого или видимого пользователю. + +## Находки + +Нет. High: 0, Medium: 0, Low: 0. + +## Вердикт + +Зелёный. Все три AC доказаны автотестами, которые подтверждённо умеют +падать; дешёвые гейты подтверждены Validate на этом SHA, специфичные для +задачи гейты (mutation-gate --check, reviews-index --check, entry-cost, +smoke-select) прогнаны лично и зелёные/неприменимы с объяснением. + +--- + + + +## Материал раунда + +- Ветка: `issue/750-review-prompt-budget`, коммит `792ad57c3e27` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `6b0657450057b1b91d1fa22f75ae8cebfef75d09` + ``` + git log --all --format='%H %T' | grep 6b0657450057 + ``` +- Тело issue: `9b6f0101c2b70c7b6bd28b3d074b65e992fa65a9ed5e57bdb6719a4a519ca440` +- Вердикт конвейера: `green` · High 0 · маршрут `fix` +