13 KiB
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— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
22e667a9118166033cd5f1a1fd2f2a2287c7b924git log --all --format='%H %T' | grep 22e667a91181 - Тело issue:
cd8ce90eb1d3e249c9aca6c38257d69e533d0e4b030cd6f4681f385c407ab264 - Вердикт конвейера:
green· High 0 · маршрутfix