From 6abb589f0c03cc83a6bf058a066bad362bc2d369 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 12:14:08 +0000 Subject: [PATCH] docs: review document for #753 Issue: #753 User-Visible: no --- docs/reviews/CODE-REVIEW-753-r1.md | 147 +++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 docs/reviews/CODE-REVIEW-753-r1.md diff --git a/docs/reviews/CODE-REVIEW-753-r1.md b/docs/reviews/CODE-REVIEW-753-r1.md new file mode 100644 index 00000000..bdb0dacc --- /dev/null +++ b/docs/reviews/CODE-REVIEW-753-r1.md @@ -0,0 +1,147 @@ +# CODE-REVIEW #753 · r1 + +Материал раунда: `23447c36` (ровно он, рабочая копия на нём). Диапазон `origin/dev..HEAD` — один коммит. + +## Скоуп + +Issue #753: исключение #562 («инфраструктурный диапазон статуса не требует, если +в диффе нет файлов класса A») по тексту гейта не знало, где находится задача. +Из-за этого issue в `S3-spec`/`S4-spec-review` (трек `ask`) могла пушить ветку +из одних тестов без статусной метки — Rule 8 пропускала её с предупреждением. +Такая ветка становится материалом ревью ТЗ (конвейер берёт свежую +`origin/issue/-*`), что прямо нарушает §11.8 («до `S5` не пушится ни код, +ни сама ветка») и даёт ревьюеру ТЗ код, который он по §2.4 видеть не должен. + +Задача сужает исключение #562: оно действует только для issue БЕЗ меток +`S3-spec`/`S4-spec-review`. Решение принимается по каждому issue в +`checkIssueStatuses`, а не по диапазону, как раньше. + +Трек show (#696) — чистая функция одного гейта, решать нечего, поведение уже +записано каноном (§11.8, §2.5). Проверка соразмерна: объём и строгость — не +находки, сверх находок канона track show не расширяет. + +Критерий §5 (маршрут вердикта): задача проходит все пункты — +`complexity` (2/10 по оценке автора, чистая правка одной функции), +`surfaces` (один модуль — `scripts/process-gate.mjs`, Rule 8), `migration` +(нет), `ux-contract` (нет — это CI-гейт, не пользовательский интерфейс), +`perf-touch` (нет), `undocumented` (поведение уже в каноне §11.8/§2.5, задача +устраняет расхождение гейта с каноном, а не вводит новое). → `route: fix`. + +## Как проверялось + +1. Прочитан полный `git diff origin/dev...HEAD` (4 файла, 141 вставка / 3 + удаления) — PROCESS.md, `scripts/process-gate.mjs`, + `scripts/mutation-registry.mjs`, `test/process-gate.test.mjs`. +2. Прочитано тело issue #753 (ТЗ в теле, трек show) и три комментария + (взял/сделано, статус `S7-code-review`). +3. Код прочитан в контексте: `isInfrastructureRange`, `checkIssueStatuses`, + блок `main()` (`:997-1022`), где строится `statusOptional` и печатается + предупреждение #562. +4. Прогнаны тесты и гейты (ниже). +5. Сверен текст PROCESS.md §10.2 с формулировкой из ТЗ — совпадает дословно. +6. Проверено, что `SPEC_ROUTE_STATUS` используется ровно в одном месте и не + требует правок в других частях гейта (`ALLOWED_STATUS` не содержит + `S3-spec`/`S4-spec-review`, так что обычный путь — без `statusOptional` — + для этих меток и так уже даёт отказ, если в диапазоне есть класс A; + новизна — именно в диапазоне без класса A). + +## Что проверено и корректно + +- **AC1** (исключение не для маршрута ТЗ). Логика в `checkIssueStatuses` + (`scripts/process-gate.mjs:496-514`): `specRoute = names ∩ SPEC_ROUTE_STATUS`, + `optional = statusOptional && specRoute.length === 0`. При + `statusOptional=true` и непустом `specRoute` — отказ с текстом, называющим + статус, §11.8 и #562; при пустом `specRoute` — старое поведение не тронуто. + `S1-new`/`S2-analysis` в `SPEC_ROUTE_STATUS` не входят — соответствует ТЗ + («инфраструктурные issue от ревьюера приходят с `S1-new`»). + Юнит `test/process-gate.test.mjs:775-823` покрывает ровно все случаи из + таблицы АС, включая два issue в одном диапазоне (отказ только у того, что в + `S3`/`S4`) и `blocked` как отдельную находку поверх. Прогнан — + зелёный (см. ниже). +- **AC2** (сквозной CLI). `test/process-gate.test.mjs:888-947`: настоящий git- + репозиторий, один коммит только в `test/**`, подставной `gh`. При статусе + `S4-spec-review`/`S3-spec` — выход 1, `FAIL п.8`, текст с `#753 в <статус>`; + при `S1-new` — выход 0 и предупреждение #562, без `FAIL`. Прогнан — + зелёный. +- **AC3** (канон + мутант). PROCESS.md:1167-1172 — предложение внесено + дословно по ТЗ. Мутант `process-gate-infra-entry-covers-spec-route` + (`scripts/mutation-registry.mjs:3601-3611`) убирает условие `specRoute` + (возвращает `optional = statusOptional`) и назначен guard'ом + `node --test test/process-gate.test.mjs`. Проверено целевым прогоном + мутационного гейта на этом мутанте — статус `ok`, то есть патч действительно + ломает тест (мутант убивается новым тестом, не был бы убит без него). +- **Доказательство «тест умеет падать»**: проверено не только по заявлению + автора — целевой прогон `mutation-gate --id=process-gate-infra-entry-covers-spec-route + --check` подтвердил, что на патче без AC1/AC2-логики тест краснеет. +- Сообщение `main()` про предупреждение #562 (`:1012-1018`) по-прежнему + печатается для всего диапазона независимо от отказа по конкретному issue — + пропуск остаётся видимым, как того требует риск-раздел ТЗ («Отказ по S3/S4 + идёт отдельной находкой — пропуск не тихий»). Подтверждено тестом AC2: + оба сообщения (`FAIL п.8` и предупреждение #562) присутствуют одновременно. +- Трейлеры коммита: `Issue: #753`, `User-Visible: no` — корректны, CHANGELOG не + тронут и не должен быть (изменение не пользовательское, это CI-гейт). +- Числовых величин, видимых пользователю дважды, дифф не вводит (не + применимо — задача чисто инфраструктурная, UI не затронут). + +### Прогон гейтов (сам, в дополнение к Validate на этом SHA) + +- `node --test test/process-gate.test.mjs` — 48/48 зелёные (включая оба новых + теста AC1 и AC2). +- `node scripts/mutation-gate.mjs --id=process-gate-infra-entry-covers-spec-route --check` + — `ok` (мутант убит). +- `npm run gate:small` — зелёный целиком (сборка+typecheck, no-new-any, + no-new-private-writes, smoke-select, юниты, bundle-policy, бюджет бандла, + lint:unused); `smoke-select` подтвердил: «исполняемого frontend-диффа нет — + смоки этим диффом не выбираются» (ожидаемо: диффа в `src/**`/`www/**` нет). + +## Чего не проверял и почему + +- `npx tsc --noEmit`, `npm test` целиком и `npm run build` со сверкой трёх + копий бандла отдельно не перегонял — Validate на этом SHA (`23447c36`) + зелёный (ссылка в задаче ревью), а `gate:small`, который я прогнал сам, + включает typecheck+build+юниты заново и тоже зелёный. +- Полный `mutation-gate --check` по всему реестру не гонял — дорого и не + нужно для track show на диапазоне, трогающем один мутант; прогнал целевой + `--id=` на изменённом мутанте, этого достаточно для AC3. +- Браузерные смоки и `smoke-select.mjs` — вывод уже получен внутри + `gate:small` («frontend-диффа нет»), отдельно не перезапускал. Diff не + трогает `src/**`, рендер, UI — смоки неприменимы по содержанию дельты. +- `npm run golden:verify` — не применимо, диффа в golden-поверхности нет, + метки `ci:golden` у issue нет. +- `python -m pytest tests_backend -q` — не применимо, `custom_components/**` + дифф не трогает. +- `npm run invariants` — не применимо, диффа в геометрии/модели нет. +- Performance-профили — в АС не названы, не применимо. +- Ручное тестирование UI — не применимо: задача меняет только CI-скрипт + (`process-gate.mjs`) и канон-документ, никакого пользовательского + поведения в приложении нет. +- Зависимость от #748 п.1 (подсказка `S3` со стороны `task-packet.mjs`) — + вне скоупа этой задачи согласно самому ТЗ («Порядок любой»), не проверял + и не требую: #753 решает только сторону гейта Rule 8, расхождение с + `task-packet.mjs` остаётся открытым по дизайну до #748. + +## Находки + +Нет. High: 0, Medium: 0 (в скоупе и вне скоупа). + +## Вердикт + +Зелёный. Все три AC доказаны автотестами, которые проверены на способность +падать (целевой прогон мутанта и прогон новых тестов), PROCESS.md обновлён +дословно по ТЗ, гейты (`gate:small`, целевой мутационный гейт, полный прогон +`test/process-gate.test.mjs`) зелёные. Изменение сфокусировано, не выходит за +рамки Rule 8, не трогает продуктовый код или UI. + +--- + + + +## Материал раунда + +- Ветка: `issue/753-rule8-spec-statuses`, коммит `23447c361277` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `e94227ed9fa22ff494cba779cfcc30dd43bb390a` + ``` + git log --all --format='%H %T' | grep e94227ed9fa2 + ``` +- Тело issue: `6ed6d6796ac50ee54325c0f740dc43953899f6c0b846c8bdc7ea2d41767a498f` +- Вердикт конвейера: `green` · High 0 · маршрут `fix`