docs: review document for #690

Issue: #690
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-29 06:27:39 +00:00
parent 52a56430ab
commit 26763c7ca4
+134
View File
@@ -0,0 +1,134 @@
# CODE-REVIEW-690-r1
**Issue:** #690 · **Этап:** code (`S7-code-review`) · **Трек:** show (инфраструктурный) ·
**Заход:** r1 · **Блокирующих циклов:** 0 из 2 · **Материал:** ветка
`issue/690-visual-minimum`, ровно `52a56430abbf98f66233b9637a5f7c78cc8d0600`
(рабочая копия на нём; `git rev-parse HEAD` сверен).
## Скоуп
Три AC из ТЗ (тело issue, п. 1′/4/попутно, решения владельца 2026-09-28):
- **AC1.** `smoke-select` при исполняемом диффе без доказанной связи печатает и
отдаёт в JSON фиксированный «визуальный минимум» (5–8 смоков режимов, слоёв,
отрисовки, среди них `smoke_modes`); `gate:small -- --smokes` гоняет его
вместе с выборкой; при доказанной связи или без исполняемого диффа минимума
нет.
- **AC2.** Правило для дефектов растра/резкости/композитинга — свидетель,
красный на старом коде по симптому владельца, подтверждение в реальном
GPU-браузере — в PROCESS §7.1 и `docs/process/AUTHOR.md`.
- **AC3.** `task-packet.mjs` описывает прежнюю метку `trivial` как продуктовый
поток, читаемый как `track:show` (§5.1), а не как «короткий трек без ТЗ».
Диффа класса A нет (только `PROCESS.md`, `docs/TESTING.md`,
`docs/process/AUTHOR.md`, `scripts/gate-small.mjs`,
`scripts/mutation-registry.mjs`, `scripts/smoke-select.mjs`,
`scripts/task-packet.mjs`, `test/smoke-select.test.mjs`,
`test/task-packet.test.mjs`) — класс B+C, `User-Visible: no` в единственном
коммите корректен (видимого пользователю поведения карточки нет). Трейлер
`Issue: #690` на месте.
## Как проверялось
Дешёвые гейты подтверждены зелёным Validate на этом SHA (run 36528250333,
`typecheck`+`npm test`+`npm run build`+`bundle-policy --verify`) — не
перегонялись повторно.
Дифф по `smoke-select` на самом материале:
```
$ node scripts/smoke-select.mjs --base origin/dev --head HEAD
Исполняемого frontend-диффа нет (src/**/*.ts не тронут).
Browser-smoke этим диффом не выбираются...
```
`noExecutableDiff: true` — ни один из названных в АС1 смоков, ни визуальный
минимум задачей не требуется: сама задача не трогает `src/**`. Браузерные
смоки не гонялись — по выводу инструмента они не выбраны, а тело issue не
называет смок отдельно для этого прогона.
По каждому AC — что проверено и как:
| AC | Чем доказан | Чем краснеет | Прогон |
|---|---|---|---|
| AC1 | `test/smoke-select.test.mjs` (`#690 п.1′: …`, 2 новых теста) + 3 именованных мутанта | `visual-minimum-silent-again` (обнуляет `visualMinimum`), `visual-minimum-on-proven-link` (минимум течёт по одному факту исполняемости, не по недоказанности), `gate-small-skips-visual-minimum` (убирает минимум из `smokesToRun`) | Прогнал сам: baseline зелёный (`node --test --test-name-pattern="#690" test/smoke-select.test.mjs` — 2/2 pass); применил патч каждого из трёх мутантов вручную — все три ломают ровно ожидаемый тест (проверено построчно, дифф отменён после каждой пробы). `node scripts/mutation-registry-check.mjs` — 0 (реестр непротиворечив, `find`-строки совпадают с текущим кодом) |
| AC2 | Текст в PROCESS §7.1 (строки 693–696) и `docs/process/AUTHOR.md` (раздел ТЗ) | защитный AC текстового/процессного рода — «чем краснеет» не применимо к формулировке правила самой по себе; доказательство — точное соответствие формулировке владельца из комментария 2026-09-28 | Проверено чтением, не исполнением: сверил текст правила в обоих файлах с формулировкой владельца дословно — совпадает; место в §7.1 логически стоит рядом с «Размытое место не додумывается» (тот же смысловой блок про доказательства до кода), не конфликтует с соседним текстом |
| AC3 | `test/task-packet.test.mjs` (обновлённое `productFlowEvidence` ожидание), `scripts/mutation-registry.mjs` (`find`/`replace` синхронизированы с новой строкой) | тот же мутант `task-packet-trivial-is-product-flow`, `because` тоже обновлён, чтобы не противоречить #695 | `node --test test/task-packet.test.mjs` — 16/16 pass; сверил формулировку с уже принятым #695 (`scripts/process-track.mjs:39`, `PROCESS.md:935`) — согласовано, не изобретает нового понятия |
Дополнительно проверено:
- `node --test test/smoke-select.test.mjs` — 9/9 pass (полный файл, не только `#690`-подмножество).
- `node --test test/gate-small.test.mjs` — 5/5 pass.
- `git diff --stat` — бандл (`dist/**`) не тронут, `Release:`-трейлер не нужен.
- Единственное число, дублирующееся в диффе, — «восемь» смоков визуального
минимума: один источник (`VISUAL_MINIMUM.length` в `scripts/smoke-select.mjs`),
PROCESS.md и `docs/TESTING.md` его лишь цитируют текстом, не хардкодят
отдельно; `test/smoke-select.test.mjs` проверяет диапазон 5–8, а не точное
число, так что смещение массива само по себе не расходится с документами
сильнее допустимого. Все 8 файлов `demo/smoke_*.mjs` из `VISUAL_MINIMUM`
существуют (проверено `existsSync`, тест это же утверждает).
## Находки
Нет. Изменение узкое, три AC разобраны по коду и тестам, мутанты
воспроизведены вручную и действительно красные на инвертированном
поведении, документный AC2 текстуально совпадает с решением владельца, AC3
согласован с уже принятым #695 и не вводит расхождений.
## Что проверено и корректно
- `VISUAL_MINIMUM` — 8 существующих смоков, включает `smoke_modes.mjs`
(именно его не хватило #687 по тексту issue); список заморожен
(`Object.freeze`).
- `selectSmokes()`: `visualMinimum` заполняется только при `unproven`, при
доказанной связи (прямой или зарегистрированной) и при `noExecutableDiff`
остаётся пустым — подтверждено фикстурами `unproven.diff`,
`234-chain-thickness.diff`, `docs-only.diff`.
- `smokesToRun()` в `gate-small.mjs` включает `visualMinimum` в список для
прогона наравне с `direct`/`registered`, с дедупликацией через `Set`.
- CLI (`report()`) печатает визуальный минимум отдельной громкой строкой
внутри ветки `НЕОПРЕДЕЛЁННОСТЬ», не подменяя её.
- `gate-small.mjs` итоговый лог называет причину («связь не доказана — …
визуальный минимум (#690)») отдельно от обычного случая.
- Мутант `task-packet-trivial-is-product-flow` обновлён синхронно с
изменением текста в `scripts/task-packet.mjs` — `find`-строка совпадает,
`mutation-registry-check.mjs` подтверждает.
- Единственный коммит, трейлеры `Issue:`/`User-Visible:` корректны,
ветка от актуального `dev` (`6e073134`), файлов класса A нет.
## Чего не проверял
- Полный `npm run gate:small`, `npm test`, `npm run build`,
`golden:verify`, `pytest tests_backend`, `npm run invariants` — не
прогонял: Validate зелёный на этом SHA закрывает дешёвые гейты
(typecheck/test/build/bundle-verify), диф не трогает Python и геометрию,
`ci:golden` не выставлена.
- Браузерные смоки (включая сам `VISUAL_MINIMUM`) — не гонял: диф не
трогает `src/**`, `smoke-select.mjs --base origin/dev --head HEAD` на
материале прямо отвечает `noExecutableDiff`, обязательного смока в АС нет.
- Мутанты по диффу как отдельный обязательный гейт ревью — не запрашивались
(трек `show`, #690/REVIEWER.md «Трек show»); три названных в АС1 мутанта
всё же проверены вручную вручную, потому что AC1 защитный и без третьей
колонки таблицы «чем краснеет» находка была бы Medium.
- Performance-профили — не названы в AC, не гонял.
- Поведение конвейера `_process.yml`/меток `trivial` на реальных открытых
issue — не проверял вживую; ограничился текстовым сравнением с уже
принятым #695.
## Вердикт
Зелёный. AC1–AC3 выполнены и доказаны каждый своим способом (тест+мутант,
чтение текста, тест); находок нет.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/690-visual-minimum`, коммит `52a56430abbf` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `3e5463d83784c360485d89dd297cbd4cbb816e5c`
```
git log --all --format='%H %T' | grep 3e5463d83784
```
- Тело issue: `4796e50b141f022b6ef98e61809bd29d3dd30e0dcf87f368da80b697565b156b`
- Вердикт конвейера: `green` · High 0