docs: review document for #709

Issue: #709
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-29 20:14:55 +00:00
parent a8321e32cc
commit 920e626948
+193
View File
@@ -0,0 +1,193 @@
# CODE-REVIEW-709-r1
Материал раунда: `git log --oneline origin/dev..HEAD` = один коммит
`a8321e32cc8299a521657b71aba6c43f41d93e6b` поверх `dev`@`18c9f8e7`.
Заход r1, трек `show`, блокирующих циклов израсходовано 0 из 2.
## Скоуп
Класс B (инфраструктура — `scripts/**`, `.github/**`, `PROCESS.md` и её
конспекты). Файлов класса A нет. Задача убирает прогон мутантов по диффу из
разработки на всех треках: `resolveTrack().mutants` всегда `false`,
`mutantsRequested()` всегда `false`, `pre-push-gate.mjs` не гоняет мутанты ни в
ручном режиме, конвейер (`_process.yml`, `validate.yml`) по умолчанию
диспатчит Validate без мутантов. Канон (`PROCESS.md`, `AUTHOR.md`,
`REVIEWER.md`, `TESTING.md`, `AGENTS.md`) переписан под новое правило; в
`PROCESS.md` §8 добавлены правила скорости для `ship`/`show` (AC3). Это не
продуктовая задача — она не закрывает и не должна закрывать ни одну строку
`docs/SCOPE.md`; относится к самому конвейеру ревью, поэтому первый вопрос
ревьюера («какую работу из SCOPE она обслуживает») здесь неприменим по
конструкции задачи (инфраструктура процесса, не продукт).
## Как проверялось
Дельта — первый раунд, разбор полный.
По AC:
- **AC1** (`resolveTrack`/`mutantsRequested` всегда `mutants=false`; Validate
не запрашивает job мутантов ни на dispatch, ни на PR; ночной реестр не
меняется). Прочитан код: `scripts/process-track.mjs` (`const mutants =
false`), `scripts/classify-changes.mjs` (`mutantsRequested()` без аргументов,
всегда `false`), `scripts/ci-proof.mjs` (комментарий и политики не
изменились по значениям — верно, это не входит в AC1). Прогнаны
`test/classify-changes.test.mjs`, `test/process-track.test.mjs` — 39/39,
зелёные. Тест умеет падать: перед патчем `mutants = track === 'ask' ||
labels.includes('ci:mutants')` — новый тест «#709: мутантов в разработке нет
ни на одном треке» упал бы на `track:ask`; аналогично старая ветка
`mutantsRequested` с `eventName === 'pull_request' → true` красит тест
«#709: Validate не запрашивает мутантов…». Оба случая — реальные мутанты в
`scripts/mutation-registry.mjs` (`dev-mutants-requested-again`,
`track-pays-for-mutants-again`), статически проверены `node
scripts/mutation-gate.mjs --check` → `ok` по обоим id, 0 FAIL (3
предсуществующих WARN о `--test-name-pattern` с `${…}`-именами, #650, не
относятся к этой задаче). Ночной реестр (`mutation-gate.yml`) в диффе не
тронут — проверено чтением: `.github/workflows/` не содержит правок этого
файла. **AC1 доказан.**
- **AC2** (канон говорит одно; `ci:mutants` снята; ревьюер мутанты не
применяет). Прочитаны все правки `PROCESS.md` (§2.7, §5.1, §10.4, метка
снята из таблицы модификаторов), `docs/process/AUTHOR.md`,
`docs/process/REVIEWER.md`, `docs/TESTING.md`, `AGENTS.md` —
формулировки согласованы **кроме одного места**, см. находку Medium ниже.
`test/process-digests.test.mjs` (сверяет цитаты `REVIEWER.md` ↔ `PROCESS.md`)
прогнан — зелёный, но он проверяет только внесённый в `KEY_RULES` список
цитат, не весь файл `TESTING.md`, поэтому находка ниже мимо него прошла.
**AC2 доказан частично** — с находкой Medium, в скоупе.
- **AC3** (правила скорости `ship`/`show`: попутный флак — отдельное issue,
одно доказательство на пункт ТЗ, `gate:small -- --smokes` не обязателен на
`ship`). Прочитаны новые абзацы `PROCESS.md` §8 (строки ~767–777) и
`docs/process/AUTHOR.md` (раздел handoff). Флаг `--smokes` — реальный,
существующий (`scripts/gate-small.mjs:34`), не изобретён. Проверка чтением,
не исполнением — это формулировка процесса, а не код с автотестом; для неё
автотеста и не требуется (правило адресовано автору/ревьюеру, не коду).
**AC3 доказан чтением.**
### Гейты — что прогнано и что нет
| Гейт | Прогнан | Результат |
|---|---|---|
| `node --test test/classify-changes.test.mjs test/process-track.test.mjs test/process-digests.test.mjs` | да | 39/39 зелёные |
| `node --test test/pre-push-gate.test.mjs test/validate-workflow.test.mjs test/merge-candidate.test.mjs` | да | 65/65 зелёные |
| `node scripts/mutation-gate.mjs --check` | да | 0 FAIL, 3 предсуществующих WARN (#650, вне скоупа) |
| `npx tsc --noEmit`, полный `npm test`, `npm run build` + сверка бандла | **нет** | не перегонялись — Validate на этом SHA (`a8321e32`) уже зелёный, run 36623839784 (#343 разрешает не дублировать) |
| Смоки/golden/`pytest tests_backend`/инварианты модели/performance | **нет** | правок `src/**`, Python, геометрии, `demo/golden/**` в диффе нет — гейты неприменимы по AC и по дельте |
| `smoke-select.mjs --base --head` | **нет** | дифф не содержит исполняемого продуктового кода (класс B/C), браузерный смок не назван в теле issue (#696); трек `show` не ставит Chromium без такого указания |
| `actionlint`, `process-gate --range` | нет, со слов автора | автор заявил «чисто» / «0 предупреждений» в хендоффе; не переисполнял отдельно — дешёвый повторный прогон не даёт нового сигнала при уже зелёном Validate на этом SHA, решил положиться на комбинацию Validate + собственный прогон юнитов/mutation-gate |
## Находки
### Medium (в скоупе задачи, возвращается автору) — canon TESTING.md противоречит себе
`docs/TESTING.md`, раздел «Локальный набор перед пушем»:
- строка 267 (добавлена этим коммитом): «Ручной `node scripts/pre-push-gate.mjs`
из этого раздела — расширенный прогон: типы, юниты и смоки; **мутантов в
нём с #709 нет**.»
- но строки 276–277 (не тронуты этим коммитом) в примере команд:
```
node scripts/pre-push-gate.mjs --no-smokes --no-mutants
node scripts/pre-push-gate.mjs --max-smokes=3 --max-mutants=1
```
- и следом, строка 280–282 (не тронуты): «Что прогоняется: … смоки, выбранные
`scripts/smoke-select.mjs` по диффу, **и мутанты, выбранные
`scripts/mutation-gate.mjs --changed` по тем же файлам**.»
Воспроизведение: `scripts/pre-push-gate.mjs` больше не парсит `--max-mutants`
(флаг убран из диффа этой же задачи, `manualGate()` больше не объявляет
`maxMutants`) и безусловно пишет `skipped.push('мутанты — в разработке не
гоняются (#709)…')` — секция «мутанты по диффу» из ручного режима удалена
целиком. Автор сам поправил тот же паттерн чуть ниже по файлу (строка 308:
«Лимит по умолчанию — шесть смоков; мутантов ручной режим с #709 не
гоняет.» — раньше было «шесть смоков и два мутанта»), но пропустил
идентичное по смыслу место двумя абзацами выше. Ровно то, что AC2 требует
исключить: «Канон (PROCESS, AUTHOR, REVIEWER, TESTING) говорит одно» — здесь
`TESTING.md` говорит разное в двух соседних абзацах одного раздела, и это не
размечено как история (в отличие от блока «До #709 в CI `changed_mutants`
бежал…» чуть выше по файлу, который прямо помечен историческим).
Почему это не поймал `process-digests.test.mjs`: тест сверяет только цитаты,
явно занесённые в `KEY_RULES`, а не весь текст файла — отсутствие записи не
значит отсутствие противоречия.
Классификация: Medium, в скоупе (тот же файл, что уже правит эта задача,
тривиальная правка — убрать `--no-mutants --max-mutants=1` из примера и
переписать «Что прогоняется» без мутантов). Без High это жёлтый вердикт по
правилам §3 п.8 / §2.7 — блокирующий цикл не расходуется по нему одному,
но раунд возвращается автору.
## Что проверено и корректно
- Логика `resolveTrack`/`mutantsRequested`/`ci-proof` согласована между собой
и с обновлёнными тестами; якоря новых мутантов реестра совпадают с текущим
текстом файлов побайтово (проверено `mutation-gate --check`, 0 FAIL).
- `.github/workflows/_process.yml` и `validate.yml`: дефолты `MUTANTS:-false`
везде, где раньше был `MUTANTS:-true` (шаг Validate на материале ревью и
шаг слияния кандидата) — оба места правлены синхронно, несогласованности
между «жди Validate с мутантами» и «дефолт без мутантов» нет.
`mutants`-вход `validate.yml` оставлен намеренно (описание помечено
«не действует с #709»), обоснованно — старые `-f mutants=…` вызовы не
падают; это явно названо временным до отдельной уборки (#622), не находка.
- `pre-push-gate.mjs`: секция мутантов убрана из `manualGate`, `--no-mutants`/
`--max-mutants` больше не влияют ни на что — согласуется с самим текстом
header-комментария файла (`* node scripts/pre-push-gate.mjs --no-smokes` без
`--no-mutants`), который был обновлён корректно.
- `PROCESS.md` §2.7: формулировка «мутант пишется, но в разработке не
гоняется… якоря реестра сверяет статический `mutation-gate --check`…
поимку проверяет только ночной полный прогон» согласована с
`docs/process/REVIEWER.md` («Мутанты в разработке не гоняются ни на каком
треке — ревьюер их тоже не применяет; проверяет, что защита названа
мутантом в реестре») и с `docs/process/AUTHOR.md`. Таблица модификаторов
меток (`PROCESS.md`, раздел §5.1/§9) больше не содержит строку `ci:mutants`
ни в одной из двух таблиц, где она раньше встречалась — сверено обоими
местами диффа.
- AC3: новый раздел §8 «Цена ship и show — без добровольных надбавок»
корректно ссылается на реально существующий флаг `--smokes`
(`scripts/gate-small.mjs:34`) и не вводит несуществующих команд.
- Трейлеры коммита: `Issue: #709`, `User-Visible: no` — верно, изменение не
меняет поведение продукта, changelog не тронут, и это корректно (не найдено
ни одного пользовательского числа/поведения, «видимого дважды»: задача не
трогает `src/**`, только процесс и CI).
- Метка `ci:mutants` не удалена из GitHub (описание сменено на «Retired»,
решение об удалении оставлено владельцу) — соответствует тому, что написал
автор в хендоффе, и не противоречит AC2 (AC2 требует снять метку **из
процесса**, не обязательно удалить сам label-объект).
- `legacy/specs/510-*.md` и старые `docs/reviews/*` с упоминаниями
`mutants=true` не трогались и не должны — это архив прежних раундов, не
канон (§2.3, `docs/specs/` и `docs/reviews/` не входят в список AC2).
## Чего не проверял
- Полный `npx tsc --noEmit`, `npm test`, `npm run build` + троекратную сверку
бандла — не перегонял отдельно; опирался на зелёный Validate на этом же SHA
(`a8321e32`, run 36623839784, см. #343). Точечно перепроверил только
тесты, которые правит дифф, плюс смежные (`pre-push-gate`,
`validate-workflow`, `merge-candidate`) — 65/65.
- `actionlint` и `node scripts/process-gate.mjs --range` не переисполнял —
положился на заявление автора в хендоффе (`actionlint — чисто;
process-gate --range — 0 предупреждений`); эти гейты не относятся к
списку «обязательно перепрогнать ревьюеру» (§8) при уже зелёном Validate.
- Смоки/golden/backend/инварианты модели/performance — не применимы: дифф не
трогает `src/**`, Python, `demo/golden/**` или геометрию; `smoke-select`
не запускал, так как исполняемого фронтенд/бэкенд-кода в диффе нет и тело
issue не называет смоук или браузер (условие "по диффу и AC" не
выполняется ни по одному критерию).
- Не проверял, действительно ли ночной `mutation-gate.yml` в текущем виде
подхватит все мутанты реестра без прогона по диффу в течение дня —
вопрос эксплуатации ночного расписания, не этой задачи, и он не входит ни
в один AC709 (ночной реестр прямо назван неизменным в AC1).
- Не проверял историю прежних раундов по этой задаче — раунд первый,
раздела «Унаследовано из r0» и «Закрытие раунда r0» нет по правилам §2.10.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/709-mutants-nightly-only`, коммит `a8321e32cc82` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `f1cb9e76e348f568523a765dc393c9cf4c6383f2`
```
git log --all --format='%H %T' | grep f1cb9e76e348
```
- Тело issue: `914787f126c442dc2e4cacb96385538eb2f0e315dbaa828e3e0241a2a9ba81e5`
- Вердикт конвейера: `yellow` · High 0