Files
2026-10-01 14:03:19 +00:00

12 KiB
Raw Permalink Blame History

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.


Материал раунда

  • Ветка: issue/753-rule8-spec-statuses, коммит 23447c361277 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: e94227ed9fa22ff494cba779cfcc30dd43bb390a
    git log --all --format='%H %T' | grep e94227ed9fa2
    
  • Тело issue: 6ed6d6796ac50ee54325c0f740dc43953899f6c0b846c8bdc7ea2d41767a498f
  • Вердикт конвейера: green · High 0 · маршрут fix