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 3078962b64
commit 475f391cf9
+215
View File
@@ -0,0 +1,215 @@
# CODE-REVIEW #753 · r2
Материал раунда: `1a086aa611b667c72885a952b4240d331c3b932c` (ровно он, рабочая
копия на нём). Диапазон `origin/dev..HEAD` — три коммита:
`94192889` (код), `cafc57fe` (документ ревью r1, публикация прошлого раунда),
`1a086aa6` (индекс ревью, публикация прошлого раунда).
## Скоуп
Issue #753 не меняется с r1: исключение #562 («инфраструктурный диапазон
статуса не требует, если в диффе нет файлов класса A») не знало, где
находится задача, и позволяло issue в `S3-spec`/`S4-spec-review` (маршрут
`track:ask`) пушить ветку из одних тестов без статусной метки — вопреки §11.8
(«до `S5` не пушится ни код, ни сама ветка») и с риском того, что эта ветка
станет материалом ревью ТЗ. Задача сужает исключение: решение по каждому
issue в `checkIssueStatuses`, а не по диапазону.
Трек show (#696), критерий §5 маршрута вердикта пройден так же, как в r1:
`complexity` (чистая правка одной функции), `surfaces` (один модуль
`scripts/process-gate.mjs`), `migration` (нет), `ux-contract` (нет — CI-гейт),
`perf-touch` (нет), `undocumented` (поведение уже в каноне §11.8/§2.5, задача
устраняет расхождение гейта с каноном). → `route: fix`.
### Почему r2, а не слияние после зелёного r1
r1 (материал `23447c36`) получил зелёный вердикт без находок, документ и
индекс были опубликованы в ветку (`cafc57fe`, `1a086aa6`) — штатный шаг
конвейера после зелёного вердикта. Дальше `dev` ушёл вперёд несколько раз во
время слияния (гонка #492), ветку трижды ребейзили, автосверка процесса
зафиксировала «Validate on the material is completed but the round was not
resumed» и разбудила `S7-code-review` заново на новом материале. Это ребейз на
ушедший вперёд `dev` — один из случаев, когда разбор остаётся полным, а не
сокращается до дельты (§2.10, конспект «Повторный раунд»), поэтому ниже —
полный разбор, а не только показ закрытия находок r1 (их и не было).
## Как проверялось
1. Сверено, что дерево материала r2 после ребейза не разошлось по содержанию
с тем, что проверял r1: `git diff 94192889~1 94192889 --stat` даёт ровно
те же 4 файла / 141 вставку / 3 удаления, что и r1 на `23447c36`; хеш
текста диффа (`scripts/process-gate.mjs`, `scripts/mutation-registry.mjs`,
`test/process-gate.test.mjs`, `PROCESS.md`) посчитан и сверен — **содержимое
патча бит-в-бит то же**, что проверял r1. Старое дерево материала r1
(`e94227ed9fa2…`) само по себе уже не резолвится — объект собран как
мусор после ребейза; это не находка (конспект «Повторный раунд»: мёртвый
SHA — обычное дело, если дерево при публикации существовало, а находка —
только мёртвый SHA уже в момент публикации отчёта; свежий тег подтверждён
числом изменённых строк и текстом).
2. Проверено, не задевает ли содержательно новые коммиты `dev` между
материалом r1 и r2 ту же область кода: `git log 88985d2e..origin/dev --
scripts/process-gate.mjs test/process-gate.test.mjs
scripts/mutation-registry.mjs PROCESS.md` нашёл один коммит
(`a7b02db6`, #755), трогающий `process-gate.mjs` — но правит
`classifyRisk` (риск по изменённым участкам), не пересекается с
`checkIssueStatuses`/`isInfrastructureRange`/`SPEC_ROUTE_STATUS`.
Остальные найденные коммиты (#745, #757, #742, #739, #729, #736, #738,
#718, #730, #727, #725, #728, #694, #707, #724, #723, #716) либо не
трогают эти файлы, либо (как #738, #729, #736) правят другие функции того
же файла. Семантического конфликта нет — ребейз был чист и для git
(отсутствие маркеров конфликта), и по смыслу.
3. Код прочитан заново в контексте текущего файла (не по диффу, а по месту):
`isInfrastructureRange` (`scripts/process-gate.mjs:404-423`),
`SPEC_ROUTE_STATUS` (`:459-463`), `checkIssueStatuses` (`:467-518`).
4. Тесты AC1/AC2 прочитаны целиком в текущем файле:
`test/process-gate.test.mjs:775-823` (юнит `checkIssueStatuses`,
`statusOptional does not cover an issue in the spec route S3/S4 (#753)`),
`:905-947` (сквозной CLI, `the CLI refuses a class-B-only range of an issue
in S3/S4 but not in S1 (#753)`).
5. Мутант `process-gate-infra-entry-covers-spec-route`
(`scripts/mutation-registry.mjs:3602-3612`) прочитан: патч убирает условие
`specRoute.length === 0`, возвращая `optional = statusOptional` — именно
регресс, который AC1 должен ловить.
6. Прогнаны гейты (ниже — свои, в дополнение к ссылке на Validate).
7. Текст PROCESS.md §10.2 (`:1169-1174`) сверен дословно с формулировкой ТЗ —
совпадает, то же предложение, что проверял r1.
8. Трейлеры всех трёх коммитов диапазона проверены (ниже).
9. Прочитано тело issue #753 и полная лента комментариев, включая гонку
ребейза и сообщение автосверки — расхождений с тем, что знал r1, нет.
## Что проверено и корректно
- **AC1** (исключение не для маршрута ТЗ) — без изменений от r1, содержимое
патча идентично. `specRoute = names ∩ SPEC_ROUTE_STATUS`,
`optional = statusOptional && specRoute.length === 0`; при непустом
`specRoute` — отказ с текстом, называющим статус, §11.8 и #562 (`:505-508`
в текущей нумерации, что совпадает по смыслу с `:496-514` из r1 — смещение
строк из-за восстановленных комментариев выше по файлу, не из-за правки
логики). `S1-new`/`S2-analysis` вне `SPEC_ROUTE_STATUS` — соответствует
ТЗ. Юнит покрывает все случаи таблицы АС, включая два issue в одном
диапазоне и `blocked` поверх специального статуса. Прогнан заново — зелёный.
- **AC2** (сквозной CLI) — без изменений от r1. `S4-spec-review`/`S3-spec` →
выход 1, `FAIL п.8`, текст с `#753 в <статус>`; `S1-new` → выход 0 и
предупреждение #562 без `FAIL`. Прогнан заново — зелёный.
- **AC3** (канон + мутант) — без изменений от r1. PROCESS.md §10.2 содержит
предложение дословно. Мутант `process-gate-infra-entry-covers-spec-route`
назначен guard'ом `node --test test/process-gate.test.mjs`; целевой прогон
мутационного гейта на этом SHA подтверждает `ok` (мутант убит новым тестом).
- **Доказательство «тест умеет падать»**: перепрогнано самостоятельно на
текущем материале, не принято на слово ни от автора, ни от документа r1:
`node scripts/mutation-gate.mjs --id=process-gate-infra-entry-covers-spec-route --check`
→ `ok`.
- Сообщение `main()` про предупреждение #562 по-прежнему печатается для
всего диапазона независимо от отказа по конкретному issue — подтверждено
тестом AC2 (оба сообщения одновременно).
- Трейлеры: `94192889` несёт `Issue: #753`, `User-Visible: no` — корректно
(CI-гейт, пользовательского поведения нет, CHANGELOG не тронут и не
должен быть). `cafc57fe` и `1a086aa6` — документация публикации
(документ ревью и индекс), тоже с `Issue: #753`, `User-Visible: no`; по
правилу (PROCESS.md §3 п.10) докс-коммит класса C может не нести трейлеры
вовсе — здесь они проставлены сверх минимума, это не находка.
- Числовых величин, видимых пользователю дважды, диапазон не вводит —
не применимо, задача не трогает UI.
- Ребейз не оставил конфликтных маркеров, `.orig`-файлов или следов
неполного мержа ни в одном из четырёх правленных файлов.
### Прогон гейтов (сам, в дополнение к Validate на этом SHA)
- Validate на `1a086aa6` зелёный (ссылка в задаче ревью) — закрывает
`tsc --noEmit`, `npm test`, `npm run build` + сверку бандла.
- `node --test test/process-gate.test.mjs` — 48/48 зелёные, включая оба
теста AC1 и AC2 (перепрогнано на материале r2, не принято из документа r1).
- `node scripts/mutation-gate.mjs --id=process-gate-infra-entry-covers-spec-route --check`
— `ok` (мутант убит); попутно вывод отметил
`WARN browser guards: 205 при ориентире 200` — это накопленное
превышение мягкого ориентира реестра мутантов в целом, не связанное с
диффом #753 (диапазон не добавляет и не трогает ни один `browser`-мутант;
добавленный мутант — не браузерный), отдельной находкой не считаю.
## Чего не проверял и почему
- Полный `mutation-gate --check` по всему реестру — дорого и не нужно для
track show на диапазоне, трогающем один мутант; целевой `--id=` на нём
достаточен для AC3.
- Браузерные смоки / `smoke-select.mjs` — diff не трогает `src/**`/`www/**`,
frontend-диффа нет; r1 это уже подтвердил внутри `gate:small`, повторный
запуск не даёт новой информации на идентичном патче.
- `npm run golden:verify`, `python -m pytest tests_backend`,
`npm run invariants`, performance-профили — не применимо: диффа в golden,
`custom_components/**`, геометрии или производительности нет, в АС не
названы.
- Ручное тестирование UI — не применимо: задача меняет CI-скрипт
(`process-gate.mjs`) и канон-документ, пользовательского поведения нет.
- Зависимость #748 п.1 (подсказка `S3` со стороны `task-packet.mjs`) —
вне скоупа этой задачи по самому ТЗ («Порядок любой»), не проверял.
- Содержательно не перепроверял историческую часть ТЗ (происхождение
исключения #562 из #207/#118, хронология `ad8e7a50`/`3934f8d8`) — она не
менялась между r1 и r2 и не относится к коду; принимаю её из r1 (раздел
ниже).
## Находки
Нет. High: 0, Medium: 0 (в скоупе и вне скоупа).
## Вердикт
Зелёный. Содержимое патча идентично тому, что уже получило зелёный вердикт в
r1 (сверено бит-в-бит, не только по статистике диффа); причина r2 —
исключительно гонка ребейза с продвигающимся `dev` (#492), а не правка кода.
Ребейз чист и для git, и по смыслу: единственный коммит `dev`, тронувший тот
же файл (#755), правит не пересекающуюся функцию. Оба AC1/AC2 перепрогнаны
самостоятельно на материале r2 и зелёные, мутант AC3 убит целевым прогоном на
этом SHA, PROCESS.md §10.2 дословно совпадает с ТЗ. Трейлеры корректны на всех
трёх коммитах диапазона.
## Закрытие раунда r1
r1 находок не содержал (High 0, Medium 0) — закрывать нечего. Таблица ниже
фиксирует это явно, как того требует формат раздела:
| Находка r1 | Чем закрыта | Где видно |
|---|---|---|
| — (находок не было) | не применимо | `docs/reviews/CODE-REVIEW-753-r1.md`, раздел «Находки»: «Нет. High: 0, Medium: 0» |
## Унаследовано из r1
Принято без повторной проверки — материал не менялся по содержанию между
раундами:
- Историческая реконструкция происхождения исключения #562 (`ad8e7a50`/#118,
`3934f8d8`/#562) и её связь с ТЗ — документ `CODE-REVIEW-753-r1.md`,
материал `23447c36` (дерево `e94227ed9fa2…`, не резолвится после ребейза —
ожидаемо, см. «Как проверялось» п.1).
- Разбор того, что `ALLOWED_STATUS` не содержит `S3-spec`/`S4-spec-review` и
обычный (не `statusOptional`) путь не меняется — `CODE-REVIEW-753-r1.md`,
п.6 раздела «Как проверялось»; перепроверено по месту в текущем файле
(см. п.3 выше) и подтверждено прежним.
- Разбор того, что задача не вводит видимых пользователю величин —
`CODE-REVIEW-753-r1.md`, раздел «Что проверено и корректно»; задача не
затрагивает UI ни в r1, ни в r2.
---
<!-- material-anchors: заполняется конвейером (#414) -->
## Материал раунда
- Ветка: `issue/753-rule8-spec-statuses`, коммит `1a086aa611b6` (ровно он,
рабочая копия на нём).
- Диапазон: `origin/dev..HEAD` = `94192889`, `cafc57fe`, `1a086aa6`.
- Вердикт этого раунда: `green` · High 0 · Medium 0 · маршрут `fix`.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/753-rule8-spec-statuses`, коммит `1a086aa611b6` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `7a562b237ac83512a473e752e05098bba55cde46`
```
git log --all --format='%H %T' | grep 7a562b237ac8
```
- Тело issue: `6ed6d6796ac50ee54325c0f740dc43953899f6c0b846c8bdc7ea2d41767a498f`
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
<!-- hp:usage input_tokens=5054 output_tokens=16919 cache_creation_input_tokens=77090 cache_read_input_tokens=1534880 num_turns=33 -->