diff --git a/docs/reviews/CODE-REVIEW-448-r2.md b/docs/reviews/CODE-REVIEW-448-r2.md new file mode 100644 index 00000000..2542a6df --- /dev/null +++ b/docs/reviews/CODE-REVIEW-448-r2.md @@ -0,0 +1,89 @@ +# CODE-REVIEW-448-r2 + +- Issue: [#448](https://github.com/Matysh/houseplan-card/issues/448) +- Материал: `git diff 658f284b..HEAD` (докоммиты `ed4ac972`), плюс наследуемый диапазон r1 `origin/dev..658f284b` +- SHA материала: `ed4ac972b3784a0120710e81f3392907709fb5dc` (сверено `git rev-parse HEAD` перед выводом) +- Заход: r2 (код-ревью) · блокирующих циклов израсходовано 1 из 4 — r1 был жёлтым (тратит бюджет), это ревью зелёное и цикла не образует (§4, #227) +- Вердикт: **зелёный** + +## Скоуп раунда + +Разбор по дельте (PROCESS.md §2.9/2.10): r1 (`docs/reviews/CODE-REVIEW-448-r1.md`, SHA `658f284b`) вернул жёлтый вердикт с двумя Medium в скоупе. Автор ответил единственным коммитом: + +- `ed4ac972` — `docs: close alpha review findings` (`Issue: #448`, `User-Visible: no`) — правит `docs/RELEASE-NOTES.md` и `AGENTS.md`, плюс кладёт в дерево `docs/reviews/CODE-REVIEW-448-r1.md` (артефакт публикации r1, не предмет этого раунда). + +Класс изменения — **C (документация)**: ни один файл класса A (`src/**`, `custom_components/houseplan/**/*.py`, `manifest.json`, `hacs.json`, i18n) и класса B (тесты/скрипты/CI) не тронут. `git diff 658f284b..HEAD --stat` подтверждает: только `AGENTS.md`, `docs/RELEASE-NOTES.md` и добавление `docs/reviews/CODE-REVIEW-448-r1.md`. Продуктовый код, тесты и бандл, зелёные в r1, дельтой не задеты — Validate на `ed4ac972` зелёный (см. вводные условия раунда), пересобирать и перегонять typecheck/test/build не требуется: диф не трогает `src/**`, `test/**`, `scripts/**`. + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| **M1** — `docs/RELEASE-NOTES.md` молча потерял пункт #447 в обеих языковых секциях (заменён пунктом #448 вместо добавления) | Пункт #447 возвращён в обе секции; чтобы удержать лимит «не более четырёх пунктов» (проверяется `validateReleaseNotes` из `scripts/release-contract.mjs`, тест `test/release-contract.test.mjs:111` — `/at most four bullets/`), #152 и #447 объединены в один пункт с деталями обеих задач и обеими ссылками | `git diff 658f284b..HEAD -- docs/RELEASE-NOTES.md`: RU-секция «## Основное» и EN-секция «## Highlights» — по 4 пункта каждая, `[#152](...)` и `[#447](...)` присутствуют в обеих; `grep -n '#447' docs/RELEASE-NOTES.md` → 2 совпадения (RU+EN) | +| **M2** — `AGENTS.md` §«Labs flags» не обновлён: описывал активацию `?hp-labs=`/`-`/`off` и обязательные `since`/`expires`, которых в контракте `hp_alpha` больше нет | Раздел переименован в «Alpha experiments», текст переписан под единый `hp_alpha=1/0` (query/hash, persisted), явно называет отсутствие per-feature ключей и `since`/`expires`, фиксирует, что legacy `hp-labs`/`houseplan_card_labs_v1` игнорируются и не мигрируются | `git diff 658f284b..HEAD -- AGENTS.md` (строки 402-416); чтением сверено с фактическим `LabsFlag` в `src/labs.ts` (лишён `since`/`expires` уже в `169fed01`, дельта этого раунда код не трогает) — текст раздела теперь соответствует коду | + +Обе находки r1 были Medium в скоупе задачи — по PROCESS.md §2.7/§4 отдельный issue не заводился, чинились в этой же задаче; здесь подтверждено предметно, а не по заявлению автора. + +## Унаследовано из r1 + +Без повторной проверки — документ `docs/reviews/CODE-REVIEW-448-r1.md`, материал SHA `658f284b44610fbb583cc795e12a3b4fae798f9c` (дерево `417fc35379c08ddc060ba43fd37e6c5b835d6446`): + +- Все 13 AC (AC1–AC13), включая три защитных (AC4, AC6, AC9) и таблицу «чем краснеет» — дельта этого раунда не трогает `src/labs.ts`, `src/houseplan-card.ts` ни один тестовый/smoke/golden-файл, поэтому доказательства AC не могли быть задеты. +- Гейты r1: `npx tsc --noEmit`, `npm test` (1907/1908, 1 skipped), `npm run build` + побайтовая сверка `dist`↔`custom_components/houseplan/frontend`, `bundle-tree.mjs`, `bundle:sync`, `no-new-any.mjs`, `check-docs.mjs`, `bundle:budget`, 10 прямых smoke-совпадений + `smoke_isometric_contract`/`smoke_isometric_live_touch`, `npm run golden:verify` (157/157, включая 7 isometric-сценариев) — все зелёные на `658f284b`, дельта их не инвалидирует (docs-only diff вне `src/**`/`test/**`). +- Раздел «Что проверено и корректно» r1 (precedence резолвера, единственный источник `LabsSnapshot.alpha`→`active`, kiosk/редакторы без проекции, регрессионный барьер golden-harness, запрет legacy-полей в матрице контрактным тестом, changelog RU+EN в том же коммите `169fed01`). +- Раздел «Чего не проверял» r1 (`benchmark:large-house-isometric` не запускался — тяжёлый гейт вне минимума; `pytest tests_backend` не запускался — Python не тронут; `model-invariants.mjs` не запускался — геометрия/`layout`/`marker.space`/`open_spans` не тронуты; 209/221 смоков не относятся к диффу; AC12 доказан только чтением). + +## Как проверялось в этом раунде — гейты + +| Гейт | Команда | Результат | +|---|---|---| +| Дешёвые гейты (typecheck/test/build) | не перегонялись | Validate зелёный на точном SHA `ed4ac972` (ссылка на прогон дана как условие раунда); диф этого раунда не трогает `src/**`/`test/**`/`scripts/**`, перегонять нечего | +| `node scripts/check-docs.mjs` | автор: `node scripts/check-docs.mjs` → `Documentation checks passed` (коммит `ed4ac972`) | pass — не обязателен для этого раунда (diff не трогает `src/**`), но выполнен автором и подтверждён | +| `node --test test/release-contract.test.mjs` | автор: 10/10 pass | подтверждает контракт `validateReleaseNotes` (маркер тега, RU/EN эквивалентность, лимит 4 пунктов) на синтетической фикстуре теста, не на самом `docs/RELEASE-NOTES.md` — фактический файл сверен ревьюером вручную (см. ниже) | +| Ручная сверка `docs/RELEASE-NOTES.md` | `sed -n '1,40p' docs/RELEASE-NOTES.md`, `grep -n '#447'` | RU и EN секции — по 4 пункта, #447 присутствует в обеих, RU/EN списки эквивалентны по числу пунктов, маркер тега `` и ссылки на CHANGELOG не изменены | +| Ручная сверка `AGENTS.md` | `git diff 658f284b..HEAD -- AGENTS.md`, `grep` по всему дереву на якорь `Labs flags`/`#labs-flags` | новый текст не содержит устаревших `since`/`expires`/`?hp-labs`; ссылок на старый заголовок раздела из активных (не-исторических) документов не найдено — только в замороженных ревью `SPEC-REVIEW-203-*` (исторический артефакт другой задачи, не правится) | +| Smoke/golden/backend/invariants | не перегонялись | не относятся к дельте — дельта не содержит кода, геометрии, Python или визуальных изменений | + +Защитных AC в дельте этого раунда нет (M1/M2 — не защитные находки: несоответствие текста документации фактическому контракту, не guard/limit/invariant), таблица «чем краснеет» не требуется по исключению PROCESS.md §2.7. + +## Находки + +Не найдено. High: 0, Medium: 0, Low: 0. + +## Что проверено и корректно + +- Обе находки r1 закрыты по существу, а не текстуально: M1 — числовое ограничение «не более четырёх пунктов» (тест `release-contract.test.mjs:111`) соблюдено объединением, а не удалением содержимого; #447 не потерялся дважды. M2 — раздел `AGENTS.md` теперь описывает ровно тот контракт, что в коде (`hp_alpha`, отсутствие `since`/`expires`, non-migration legacy). +- Дельта не расширяет скоуп задачи (PROCESS.md §2.6): оба файла были прямо названы находками r1, новых поверхностей не появилось. +- Трейлеры коммита `ed4ac972`: `Issue: #448`, `User-Visible: no` — корректно для чисто документационной правки без нового пользовательского поведения. +- RU/EN версии `RELEASE-NOTES.md` остаются симметричными по структуре и содержанию (одно и то же объединение #152+#447 сделано в обеих секциях). + +## Чего не проверял + +- Не перегонял `tsc --noEmit`, `npm test`, `npm run build` — дельта раунда docs-only, вне `src/**`/`test/**`, а Validate уже зелёный на точном SHA `ed4ac972` (условие раунда). Это решение по дельте (§2.10), а не пропуск. +- Не перегонял smoke/golden/backend/model-invariants — ни один не относится к дельте (без кода, геометрии, Python, визуальных изменений); полные наборы — предрелизный гейт (§8), не гейт ревью. +- Не проверял фактическое поведение `npm run release:prerelease` (генерация тела релиза из `RELEASE-NOTES.md`) — тег `v1.72.0-beta.1` ещё не опубликован, это отдельный релизный шаг вне код-ревью. + +## Материал раунда + +- SHA: `ed4ac972b3784a0120710e81f3392907709fb5dc` (сверено `git rev-parse HEAD` непосредственно перед выводом вердикта) +- Диапазон дельты: `658f284b..HEAD`, 1 коммит (`ed4ac972`) +- Дерево: `b55955d59283a59ecb751673f9d5d29094b7bc11` + ``` + git log --all --format='%H %T' | grep b55955d59283 + ``` +- Унаследованный материал r1: SHA `658f284b44610fbb583cc795e12a3b4fae798f9c`, дерево `417fc35379c08ddc060ba43fd37e6c5b835d6446`, документ `docs/reviews/CODE-REVIEW-448-r1.md` + +--- + + + +## Материал раунда + +- Ветка: `issue/448-alpha-switch`, коммит `ed4ac972b378` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `b55955d59283a59ecb751673f9d5d29094b7bc11` + ``` + git log --all --format='%H %T' | grep b55955d59283 + ``` +- ТЗ `docs/specs/448-alpha-switch.md`, блоб `951eaa1266d5845a7674a8ef61950cd78b8e140b` + ``` + git log --all --find-object=951eaa1266d5845a7674a8ef61950cd78b8e140b -- docs/specs/448-alpha-switch.md + ```