Files
2026-10-01 05:52:18 +00:00

13 KiB
Raw Permalink Blame History

CODE-REVIEW-738-r1

Issue: #738 — «process-gate, правило 10: код из S3 после reclassify не судится» Трек: show · заход r1 · блокирующих циклов использовано 0 из 2 Материал раунда: ветка issue/738-rule10-epochs, один коммит 021a94959856c81c7fafac90f8f84fb87cc2a1c2 поверх origin/dev bc59917ea473635fe3a2f22893afd28513d37131 (merge-base 76558bf2a0bf72dcfed369743639c989b4099450). Диапазон ревью — git diff origin/dev...HEAD.

Скоуп

Чистая правка процессного гейта: scripts/process-gate.mjs (правило 10, checkCommitEraStatuses), test/process-gate.test.mjs, PROCESS.md §10.2. Файлов класса A нет, продуктовый код (src/**, custom_components/**) не тронут. User-Visible: no — верно: правка видна только конвейеру.

Критерии маршрута §5 (route): complexity — одна чистая функция, низкий риск; surfaces — одна поверхность (правило 10 гейта); migration — нет; ux-contract — нет; perf-touch — нет; undocumented — ожидаемое поведение зафиксировано правилом №1, §2.5 и #726, подтверждено владельцем в комментарии трека. Все критерии пройдены → route: fix, reclassify не требуется.

Что сделано (по диффу)

checkCommitEraStatuses раньше сравнивал authorDate коммита только с первым событием labeled из allowed (readyAt). Теперь строится шкала статусных событий (statusEvents): метки allowed открывают эпоху «можно писать код», PRE_READY_STATUS (S1-new…S4-spec-review) её закрывают, остальные метки (blocked, track:*, review-4, S8-merged при --no-merged) в шкалу не попадают вовсе. Статус на момент w — statusIndexAt: последнее событие с at ≤ w. Для коммита: если на его authorDate эпоха открыта — чисто; если нет и готовности вообще не было — старый текст «до первого достижения…»; если готовность была, но закрылась — новый текст называет статус на authorDate, время возврата (первое закрывающее событие после последней готовности) и следующую готовность или «ещё не достигнут».

PROCESS.md §10.2 получил пункт 10, точно описывающий эту модель (эпохи, закрывающие метки, warn без таймлайна).

Как проверялось

Гейт Статус Как
npx tsc --noEmit, полный npm test, npm run build + сверка бандла не перегонялся Validate на 021a9495 зелёный (run 36821163281) — §8 позволяет не дублировать на этом SHA
test/process-gate.test.mjs (точечно) прогнан лично node --test test/process-gate.test.mjs → 38/38 ok, включая старый тест rule 10 (#311) и три новых (#738)
Тест умеет падать (AC1, AC2) проверено лично Временно подменил scripts/process-gate.mjs на версию origin/dev, прогнал тот же тестовый файл: старый тест (#311) остаётся зелёным, три новых теста (#738) красные (not ok 36/37/38). Рабочую копию восстановил из git сразу после, git status — чисто
node scripts/mutation-gate.mjs --check прогнан лично предупреждений mutation registry: 3, browser guards 200/200 — совпадает с заявленным «как на dev»
node scripts/smoke-select.mjs --base origin/dev --head HEAD прогнан лично «Исполняемого frontend-диффа нет (src/**/*.ts не тронут)» — смоки не выбираются, выбирать нечего (src/** не менялся)
python -m pytest tests_backend не требуется custom_components/**/*.py не тронут
npm run invariants не требуется геометрия и ссылки на неё не тронуты
npm run golden:verify не требуется метки ci:golden на issue нет, рендер не тронут
performance-профили не требуется не названы в AC
Побочное наблюдение из ТЗ (не AC): риск для открытых веток S5…S7 частично gh issue list по меткам S5-ready/S6-in-progress/S7-code-review — живые кандидаты: #729, #731, #735, #736, #737, #739, #740, #741, #742 (и сам #738). По их текущим меткам ни один не стоит в S3-spec/S4-spec-review, то есть тривиального кейса «сейчас в пред-готовом статусе» нет. Полную проверку (process-gate --range origin/dev..<ветка> --issues --report по каждой из этих веток, с разбором таймлайна на предмет скрытого возврата S5+→S3/S4 в прошлом) не гонял — это явно не-AC наблюдение из самого ТЗ, и объём трека show его не требует

Проверка AC по тексту ТЗ

  • AC1 (эпоха после возврата) — доказан test/process-gate.test.mjs:905-988. Лично проверил сценарий таблицы ТЗ (S5 t1→S6 t2→S7 t3→S3 t4→S4 t5→S5 t6): коммит t2+1ч чист, t4+1ч красит с текстом про S3-spec/t4/t6, t5+1ч — про S4-spec-review/t4/t6, t6+1ч чист, t1-1ч — старый текст без «после возврата». Два возврата подряд и «возврат без новой готовности → ещё не достигнут» — второй тест файла, тоже зелёный на HEAD и красный на dev. Доказан автотестом, тест умеет падать — проверено лично.
  • AC2 (совместимость и границы) — третий новый тест: старый тест #311 не тронут и зелёный; таймлайн только из allowed даёт прежние вердикты; класс B/C не красит; blocked/track:ask не меняют статус; S8-merged со STRICT_STATUS не открывает и не закрывает эпоху; неотсортированные события дают тот же результат; authorDate == S3-spec уже в S3. Доказан автотестом, тест умеет падать — проверено лично (тот же red/green прогон).
  • AC3 (канон и гейт) — PROCESS.md §10.2 действительно называет эпохи, S1…S4 как закрывающие и warn без таймлайна — прочитано лично (PROCESS.md:1186-1202). gate:small и mutation-gate --check: второе прогнано лично (см. таблицу), gate:small не перегонялся отдельно — его состав (typecheck/test/lint) покрыт зелёным Validate на этом SHA. Проверено чтением канона + частичным исполнением.

Защитный AC (AC1/AC2 — гард против невидимого нарушения DoR): таблица «AC · чем доказан · чем краснеет» в теле issue не пустая и подтверждена мной лично (red-run на origin/dev-версии функции), а не только заявлением автора.

Находки

Нет High. Нет Medium.

  • Low (не блокирует, снято): автор сознательно не завёл мутанта в реестр (demo/guard) для новой ветки checkCommitEraStatuses, аргументируя тем, что функция чистая и тест уже содержит богатый набор отрицательных случаев. Для трека show это ровно «бухгалтерия» — отсутствие записи в реестре, а не неподтверждённая защита (защита подтверждена исполнением red/green выше). Снимаю без действия.

Что проверено и корректно

  • Логика эпох (statusEvents/statusIndexAt/checkCommitEraStatuses) разобрана построчно и прогнана на сценарии из ТЗ лично — поведение совпадает с описанием «Что меняется» и с обоими текстами находок.
  • Обратная совместимость с правилом 10 до #738 (#311) подтверждена неизменным зелёным тестом и логически: при таймлайне без возвратов lastReady всегда -1, так что ветка кода схлопывается к прежнему поведению (readyAt = firstReady.at).
  • Трейлеры коммита: Issue: #738, User-Visible: no — верно, changelog не требуется. Один коммит, ветка issue/738-rule10-epochs соответствует номеру issue. Класса A файлов нет — отдельного ТЗ-AC на трейлер не теряет силу.
  • Одно число — один источник (§8): список PRE_READY_STATUS объявлен один раз как константа и используется и в коде, и неявно описывается в PROCESS.md (текстом, не импортом) — это документация поведения, а не второй независимый источник истины; расхождения нет, проверено построчной сверкой текста канона с кодом.
  • PRE_READY_STATUS экспортирован, но нигде не импортируется (ни тестом, ни другим скриптом) — стилистически не отличается от уже существующих ALLOWED_STATUS/STRICT_STATUS, не находка.

Чего не проверял

  • Полный npm test, npx tsc --noEmit, npm run build целиком — не перегонял, положился на зелёный Validate этого SHA (run 36821163281); точечно сам прогнал только изменённый тестовый файл.
  • Browser-смоки — не прогонял: smoke-select.mjs не выбрал ни одного (нет фронтенд-диффа).
  • Исчерпывающий обход таймлайнов всех открытых веток S5…S7 на предмет скрытого прошлого возврата S5+→S3/S4 — не AC, трек show не требует этого объёма; сделана только лёгкая проверка по текущим меткам (см. таблицу гейтов).
  • Свежесть скриншотов документации — не гейт задачи, не проверялась.

Вердикт

Зелёный. Код делает ровно то, что заявлено в ТЗ, оба новых и прежний тест проверены лично на предмет «умеет падать», граница трека show (route: fix) соблюдена, трейлеры в порядке, гейты по диффу и AC либо прогнаны лично, либо законно не требуются.


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

  • Ветка: issue/738-rule10-epochs, коммит 021a94959856 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 22e667a9118166033cd5f1a1fd2f2a2287c7b924
    git log --all --format='%H %T' | grep 22e667a91181
    
  • Тело issue: cd8ce90eb1d3e249c9aca6c38257d69e533d0e4b030cd6f4681f385c407ab264
  • Вердикт конвейера: green · High 0 · маршрут fix