docs: review document for #753

Issue: #753
User-Visible: no
This commit is contained in:
claude[bot]
2026-10-01 14:03:19 +00:00
parent 4aa6c85f98
commit 6abb589f0c
+147
View File
@@ -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/<NN>-*`), что прямо нарушает §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.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/753-rule8-spec-statuses`, коммит `23447c361277` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `e94227ed9fa22ff494cba779cfcc30dd43bb390a`
```
git log --all --format='%H %T' | grep e94227ed9fa2
```
- Тело issue: `6ed6d6796ac50ee54325c0f740dc43953899f6c0b846c8bdc7ea2d41767a498f`
- Вердикт конвейера: `green` · High 0 · маршрут `fix`