mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 12:18:51 +00:00
@@ -0,0 +1,148 @@
|
||||
# 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 либо прогнаны лично, либо
|
||||
законно не требуются.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/738-rule10-epochs`, коммит `021a94959856` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `22e667a9118166033cd5f1a1fd2f2a2287c7b924`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 22e667a91181
|
||||
```
|
||||
- Тело issue: `cd8ce90eb1d3e249c9aca6c38257d69e533d0e4b030cd6f4681f385c407ab264`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
Reference in New Issue
Block a user