mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,359 @@
|
||||
# CODE-REVIEW-648-r1
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/648 —
|
||||
«Sections: вертикальный resize карточки и container-owned высота плана»
|
||||
- **Этап:** `S7-code-review` (код-ревью, PROCESS.md §2.7)
|
||||
- **Трек:** полный (`P2`, см. SPEC-REVIEW-648-r1.md)
|
||||
- **Материал:** `git log --oneline origin/dev..HEAD` и
|
||||
`git diff origin/dev...HEAD`; вершина ветки —
|
||||
`b7fb7cf7e7bce13a44ef0e1af3b97541ddb0dffa`, база — `origin/dev` =
|
||||
`f68878cc44b818b6cfbdb3866302e6febaab2445`. Три коммита:
|
||||
`7f48e690` (feat, User-Visible: yes), `102b2ed7` (test, User-Visible: no),
|
||||
`b7fb7cf7` (test, User-Visible: no).
|
||||
- **Заход:** r1 · блокирующих циклов израсходовано 0 из 4 (первый раунд
|
||||
код-ревью; предыдущий раунд — ревью ТЗ, `docs/reviews/SPEC-REVIEW-648-r1.md`,
|
||||
зелёный)
|
||||
- **Роль:** ревьюер кода (не автор)
|
||||
|
||||
## Скоуп ревью
|
||||
|
||||
Диапазон меняет:
|
||||
|
||||
- `src/houseplan-card.ts` — новое публичное реактивное свойство `layout`
|
||||
(HA-сигнал), геттер `_containerOwnedHeight` (`panelHost || layout ===
|
||||
'grid'`), `getGridOptions()` → `{ columns: 'full', rows: 10, min_rows: 6 }`,
|
||||
замена `panelHost` на `_containerOwnedHeight` в четырёх местах расчёта
|
||||
высоты сцены (mode-transition target, `measuredCardHeaderHeight`,
|
||||
`settleSoftStageLayout`, inline `style="height:..."`);
|
||||
- `src/boot-soft-layout.ts` — переименование параметра `panelHost` →
|
||||
`containerOwnedHeight` в `measuredCardHeaderHeight`/`settleSoftStageLayout`
|
||||
(поведение не меняется, кроме нового источника `true`);
|
||||
- `src/styles/base.styles.ts` — CSS-селекторы `:host([layout="grid"])`
|
||||
добавлены рядом с существующими `:host([panel-host])`;
|
||||
- `demo/smoke_sections_resize.mjs` (новый, 221 строка) — browser smoke;
|
||||
`demo/smoke_houseplan_panel.mjs` — соседний regression-oracle (AC7);
|
||||
`test/houseplan-panel.test.mjs` — обновлён текстовый oracle контракта #486;
|
||||
- `scripts/mutation-registry.mjs` (4 новых мутанта), `scripts/smoke-links.mjs`
|
||||
(регистрация smoke по символам);
|
||||
- документация: `docs/ARCHITECTURE.md`, `docs/CHANGELOG.md`,
|
||||
`docs/CHANGELOG.ru.md`, `docs/STATUS-FEATURES.md`, `docs/TESTING.md`,
|
||||
`docs/USER-GUIDE.md`, `docs/USER-GUIDE.ru.md`;
|
||||
- `dist/**`, `custom_components/houseplan/frontend/**` (класс D, пересобранный
|
||||
бандл — сверено побайтно, см. «Как проверялось» п.2).
|
||||
|
||||
Первый вопрос — какую строку `docs/SCOPE.md` задача обслуживает: прямого
|
||||
Core-job нет, это инфраструктурная UX-правка поверхности, на которой живут
|
||||
J1–J7 для персоны Home admin (Sections — основной тип dashboard в HA,
|
||||
задача не расширяет функциональность плана и не входит в «Out of scope»).
|
||||
Ровно так же было принято ревьюером ТЗ в SPEC-REVIEW-648-r1.md — конфликта
|
||||
со SCOPE.md нет.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `docs/process/REVIEWER.md`,
|
||||
тело issue #648 (раздел `## ТЗ`, K1–K12, AC1–AC10), и
|
||||
`docs/reviews/SPEC-REVIEW-648-r1.md` (единственный предыдущий раунд —
|
||||
ревью ТЗ, зелёный, без Medium/High).
|
||||
2. Прочитан полный `git diff origin/dev...HEAD` по каждому изменённому
|
||||
файлу `src/**`, `demo/smoke_sections_resize.mjs`,
|
||||
`demo/smoke_houseplan_panel.mjs`, `test/houseplan-panel.test.mjs`,
|
||||
`scripts/mutation-registry.mjs`, `scripts/smoke-links.mjs`, всех
|
||||
изменённых `docs/*.md`.
|
||||
3. Пересобрал бандл (`npm run build` → `npm run bundle:sync`) на материале —
|
||||
`git status` после сборки чист: committed `dist/**` и
|
||||
`custom_components/houseplan/frontend/**` побайтно совпадают с
|
||||
пересобранными, обновлять было нечего.
|
||||
4. Прогнаны гейты (список — «Что прогнал» ниже); дешёвые (`typecheck`
|
||||
внутри `build`, `npm test`, `npm run build`) уже подтверждены зелёным
|
||||
Validate на этом точном SHA (см. ссылку в задании), их не переганивал;
|
||||
`check-docs.mjs`, `no-new-any.mjs`, `no-new-private-writes.mjs`,
|
||||
`bundle:budget` прогнал сам, так как диф трогает `src/**`, а инструкция
|
||||
не считает их покрытыми чужим прогоном за меня.
|
||||
5. Прогнал сам `smoke_sections_resize.mjs` и `smoke_houseplan_panel.mjs`
|
||||
(браузерные смоки Validate не гоняет вне `heavy`-условий — они не в
|
||||
материале, который мне назвали зелёным). Оба зелёные.
|
||||
6. Через `node scripts/mutation-registry.mjs --id=<id>` прогнал все четыре
|
||||
новых мутанта задачи (`sections-grid-falls-back-to-viewport-height`,
|
||||
`sections-editor-transition-uses-window-height`,
|
||||
`sections-grid-drops-stage-flex-chain`,
|
||||
`sections-resize-drops-stage-refit-observer`) — каждый краснит именно
|
||||
`smoke_sections_resize.mjs`, репозиторий чист после каждого прогона
|
||||
(скрипт сам возвращает мутант и пересобирает). Это заполняет колонку
|
||||
«чем краснеет» для защитных AC2/AC4/AC5/AC7/AC8 предметно, а не по
|
||||
заявлению автора.
|
||||
7. Прогнал `node scripts/smoke-select.mjs --base f68878cc4... --head
|
||||
b7fb7cf7e...` — «прямое совпадение» вернуло 19 смоков, включая оба
|
||||
названных в AC (`smoke_sections_resize.mjs`, `smoke_houseplan_panel.mjs`)
|
||||
и ряд смоков, делящих символы `_hdrH`/`_bootSoft`/`_stageEl`/`_warmSlot`
|
||||
с изменённым `boot-soft-layout.ts`. Из них выбрал и прогнал
|
||||
`smoke_render_invalidation.mjs` (единственный, читающий `_bootSoft`
|
||||
напрямую — сигнатура `settleSoftStageLayout` изменилась) и
|
||||
`smoke_warm_dialogs.mjs` (`_hdrH`+`_warmSlot`, соседняя soft-layout
|
||||
цепочка) как точечную regression-проверку рефактора параметра
|
||||
`panelHost → containerOwnedHeight`; оба зелёные. Остальные 15 прямых
|
||||
совпадений и 28 слабых связей не гонял — сочтено непропорциональным для
|
||||
рефактора, который для существующих layout (`layout` не установлен)
|
||||
математически не меняет значение `containerOwnedHeight` (было
|
||||
`panelHost`, осталось `panelHost || false`), см. «Чего не проверял».
|
||||
8. Экспериментально проверил (не для отчёта CI, а для собственной
|
||||
уверенности): вручную заменил `language: 'ru'` на `'de'` в фикстуре
|
||||
`smoke_sections_resize.mjs`, прогнал — все проверки, включая
|
||||
`minimumSixRowsStayContained`, прошли и на немецкой локали; откатил
|
||||
правку (`git status` после отката чист). Это ограничивает находку
|
||||
Medium-1 ниже: код сейчас не ломается на German, но CI никогда не
|
||||
узнает, если сломается.
|
||||
9. Проверил трейлеры всех трёх коммитов (`git log`) — `Issue: #648` на
|
||||
каждом, `User-Visible: yes` только на `7f48e690`, и оба changelog входят
|
||||
в этот же коммит (`docs/CHANGELOG.md`, `docs/CHANGELOG.ru.md` — видно в
|
||||
`git show --stat 7f48e690`).
|
||||
10. Сверил термины режимов (Plan/Devices/Backdrop → «План»/«Устройства»/
|
||||
«Подложка») со смоком, использующим внутренние имена `plan`/`devices`/
|
||||
`decor` — совпадает с существующим соответствием в `docs/USER-GUIDE.ru.md`
|
||||
(уже проверено ревьюером ТЗ).
|
||||
11. Проверил, что `houseplan-space-card` (`src/space-card.ts`) не получил
|
||||
ни `getGridOptions`, ни ссылок на новое свойство `layout` (grep) —
|
||||
юнит-тест это же утверждает через `assert.doesNotMatch`.
|
||||
12. Проверил «одно число — один источник» (§8): 10/6 фигурируют только как
|
||||
возврат `getGridOptions()` (единственный источник) и как проза в
|
||||
changelog/USER-GUIDE/ARCHITECTURE/STATUS-FEATURES/TESTING, дословно
|
||||
совпадающая с этим возвратом; отдельного хардкода этих чисел или
|
||||
пиксельных производных (≈632/≈376 из K2) в `src/**` или изменённых
|
||||
`docs/*.md` не нашёл (grep).
|
||||
|
||||
## Находки
|
||||
|
||||
### Medium-1 (в скоупе задачи). AC3 документально обещает browser smoke
|
||||
«RU/DE», а поставленный smoke проверяет минимальную высоту только на
|
||||
русской локали
|
||||
|
||||
**Файл:** `demo/smoke_sections_resize.mjs:64-101` (секция `minimumGeometry`),
|
||||
конфиг `card.setConfig(config)` строка 72.
|
||||
|
||||
**Что не так.** Таблица AC issue #648 для AC3 называет доказательство
|
||||
буквально: «Browser smoke RU/DE, geometry + scroll oracle» — для
|
||||
наблюдаемого результата «На минимальных 6 строках View при узкой ширине и
|
||||
**длинной локали** не выходит за slot; header доступен...». Раздел i18n
|
||||
того же ТЗ поясняет зачем: «Существующие RU/DE длинные подписи входят в
|
||||
визуальную проверку минимальной высоты» — RU и DE выбраны вместе не
|
||||
случайно: `docs/TESTING.md:484-485` фиксирует немецкую локаль как
|
||||
установленный в проекте эталон «длинных подписей», ломающих узкую/минимальную
|
||||
раскладку («German View... fit at desktop and 390 px without horizontal
|
||||
overflow or clipped actions»).
|
||||
|
||||
Фактически `card.setConfig(config)` в `demo/smoke_sections_resize.mjs:72`
|
||||
задаёт `language: 'ru'` один раз на весь смок — включая блок
|
||||
`minimumGeometry` (строки 91–101), который единственный проверяет минимум
|
||||
6 строк на узкой ширине 390 px. Немецкая локаль нигде в файле не
|
||||
упоминается (`grep -n "language\|'de'" demo/smoke_sections_resize.mjs` не
|
||||
находит `de`). Половина заявленного в AC3 покрытия не существует как
|
||||
исполняемый тест.
|
||||
|
||||
**Почему это находка, а не блокер существующей защиты.** Я не нашёл живого
|
||||
дефекта: ручной эксперимент (заменил `'ru'` на `'de'` в этом же файле,
|
||||
прогнал, откатил) показал, что на текущем коде `minimumSixRowsStayContained`
|
||||
и `headerContained`/`menuReachable` проходят и на немецкой локали. Это не
|
||||
регрессия сегодняшнего дня.
|
||||
|
||||
**Сценарий отказа.** Ближайшее изменение хедера/меню (например, более
|
||||
длинная подпись пункта меню, добавленная в рамках другой задачи) может
|
||||
сузить запас по немецкой локали на 390 px/6 строках, ничего не сломав по
|
||||
русской. Ни один автотест в этом дифе и ни один существующий golden/сценарий
|
||||
(проверено — `docs/golden`, `demo/docs` не содержат Sections/grid-сценария)
|
||||
это не заметит: `smoke_sections_resize.mjs` — единственный исполняемый
|
||||
свидетель AC3, и он проверяет только RU. Заявленная в согласованном ТЗ
|
||||
защита «длинная локаль не переполняет минимальный slot» наполовину не
|
||||
существует как код.
|
||||
|
||||
**Почему в скоупе и не блокирует зелёный.** Правка дешёвая — обернуть
|
||||
существующий блок `minimumGeometry` (или отдельно вызвать `setConfig` с
|
||||
`language: 'de'`) в цикл по `['ru', 'de']` и агрегировать оба результата в
|
||||
`minimumSixRowsStayContained`; список поверхностей и файлов не меняется, не
|
||||
требует новой инфраструктуры. Без High-находок это делает вердикт жёлтым, а
|
||||
не переоткрывает задачу отдельным issue (#202).
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- **AC1** (grid defaults + `getCardSize`): `getGridOptions()` возвращает
|
||||
ровно `{ columns: 'full', rows: 10, min_rows: 6 }` без `max_rows`
|
||||
(`src/houseplan-card.ts:3762`); подтверждено исполнением обоих браузерных
|
||||
смоков (`executableGridDefaults`, `sectionsDefaultsRemainAvailableInPanel`)
|
||||
и юнитом, не читающим монолит как единственное доказательство (юнит —
|
||||
дополнение к исполняемому свидетелю, не замена). `space-card.ts` не имеет
|
||||
`getGridOptions` — подтверждено grep и юнитом.
|
||||
- **AC2/AC3** (контейнерная высота, минимум 6 строк на 390 px): смок
|
||||
`smoke_sections_resize.mjs` реально измеряет `getBoundingClientRect()`
|
||||
`host`/`card`/`ha-card`/`header`/`stage` на живом собранном бандле —
|
||||
прогнан мной, зелёный (см. «Как проверялось» п.5). Кроме RU-ограничения
|
||||
из Medium-1, оракул содержательный: допуск 1 px, `stage.height > 0`,
|
||||
`cardScroll`/`haCardScroll` ≤ 1 (нет overflow/пустого хвоста).
|
||||
- **AC4** (серия 6→10→14→6, камера/аспект не сбрасываются, нет ошибок
|
||||
ResizeObserver): проверено исполнением; мутант
|
||||
`sections-resize-drops-stage-refit-observer` (отключение
|
||||
`_roViewport.observe(stage)`) краснит именно этот smoke — «чем краснеет»
|
||||
предметно подтверждено мной, не только заявлено автором.
|
||||
- **AC5** (переходы Plan/Devices/Backdrop не меняют внешний rect, нет
|
||||
busy-хвоста): смок ждёт реальный `_modeTransition.state` (не форсирует
|
||||
приватное состояние), проверяет `entering.to.stageHeight <=
|
||||
card.clientHeight + 1` на входе и выходе для всех трёх режимов при 10 и 6
|
||||
строках. Мутант `sections-editor-transition-uses-window-height`
|
||||
(возврат `innerHeight` вместо `containerOwnedHeight ? this.clientHeight`)
|
||||
краснит smoke — подтверждено прогоном.
|
||||
- **AC6** (explicit `grid_options` остаётся главным, config не мутируется):
|
||||
`Object.freeze(config)` в фикстуре + сверка `JSON.stringify(config) ===
|
||||
configBefore` и `card._config.grid_options === config.grid_options` по
|
||||
идентичности объекта — сильнее обычного deep-equal, ловит скрытое
|
||||
клонирование. Не отдельный юнит-файл, а часть browser smoke (ТЗ называет
|
||||
«Unit + browser smoke» как два способа доказательства; по факту это один
|
||||
исполняемый смок) — расхождение в названии способа доказательства не
|
||||
снижает фактическое покрытие и не поднимается до отдельной находки (по
|
||||
аналогии со снятыми Low ревью ТЗ).
|
||||
- **AC7** (без `layout=grid` — старое поведение; `space-card` без grid
|
||||
defaults): `card.layout = null` в смоке восстанавливает `100dvh` в
|
||||
реальном инлайн-стиле (`ordinaryCardKeepsViewportHeight`), проверено
|
||||
исполнением; `smoke_houseplan_panel.mjs` (panel-host, не grid)
|
||||
обновлён и прогнан мной отдельно — зелёный, панельная контейнерная
|
||||
высота не задета рефактором `panelHost → containerOwnedHeight`
|
||||
(математически `containerOwnedHeight === panelHost` когда `layout` не
|
||||
установлен).
|
||||
- **AC8** (resize не создаёт кликов/тапов, hit-coordinates верны после
|
||||
resize): `moreInfo` счётчик остаётся 0, `stableMode === 'view'`,
|
||||
`postResizeHitCoordinatesMatchCamera` сверяет реальную матрицу
|
||||
`getScreenCTM()` SVG после шторма resize с `card._view` — не заявление, а
|
||||
геометрическая проверка через реальный DOM.
|
||||
- **AC9** (30 изменений высоты без ResizeObserver loop/error): цикл из 30
|
||||
`frame()`-тиков с чередованием 6/14 строк, финальная геометрия и время
|
||||
(`stormElapsed < 3000`) проверены исполнением; `finish()` в
|
||||
`demo/serve.mjs` считает необработанные исключения карточки
|
||||
(`_pageErrors`) и красит прогон при их появлении — не только заявленные
|
||||
булевы поля.
|
||||
- **AC10** (документация + credit): `docs/CHANGELOG.md`/`.ru.md`,
|
||||
`docs/USER-GUIDE.md`/`.ru.md`, `docs/ARCHITECTURE.md`,
|
||||
`docs/STATUS-FEATURES.md`, `docs/TESTING.md` все обновлены и
|
||||
проверены чтением; `@pando80` упомянут в обоих changelog с ссылкой на
|
||||
#648. `check-docs.mjs --screenshots=warn` (режим обычного пуша) прогнан
|
||||
мной — зелёный (единственная находка — WARN о неизменном скриншот-
|
||||
отпечатке, ожидаемо: диф не меняет визуальные пиксели плана/chrome,
|
||||
ТЗ прямо разрешает это в «Плане автотестов» п.7).
|
||||
- **Трейлеры и changelog**: `Issue: #648` на всех трёх коммитах,
|
||||
`User-Visible: yes` только на `feat`-коммите и оба changelog редактируются
|
||||
именно в нём — соответствует AGENTS.md.
|
||||
- **Одно число — один источник** (§8): 10 и 6 строк существуют один раз —
|
||||
как возврат `getGridOptions()`; вся документация и тесты лишь
|
||||
переиздают это значение прозой/сравнением, вторичного независимого
|
||||
источника не заведено.
|
||||
- **Бандл воспроизводим**: пересборка (`npm run build && npm run
|
||||
bundle:sync`) на материале не породила диффа — закоммиченный `dist/**` и
|
||||
зеркала в `custom_components/houseplan/frontend/**`,
|
||||
`demo/srv/assets/**` побайтно совпадают с исходниками этого SHA.
|
||||
- **Гейты, специфичные для `src/**`-дифа**: `no-new-any.mjs` (0 новых
|
||||
`any` в 31 добавленной строке `src/**`), `no-new-private-writes.mjs`
|
||||
(0 новых записей в приватное состояние карточки из 223 добавленных строк
|
||||
смоков — только чтения, что разрешено), `bundle:budget` (initial View
|
||||
291761 B, в пределах потолка) — все прогнаны мной и зелёные.
|
||||
- **Юнит-тесты**: `npm test` — 3086 тестов, 3085 pass, 1 skip (не связан с
|
||||
этой задачей), 0 fail.
|
||||
- **Область изменений**: `space-card.ts`, `panel-host`, Masonry, kiosk не
|
||||
тронуты кодом (только упомянуты в документации как «не меняются») —
|
||||
подтверждено grep по всем изменённым файлам и фактическим отсутствием
|
||||
правок вне `houseplan-card.ts`/`boot-soft-layout.ts`/`base.styles.ts`.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- **Реальное поведение Home Assistant Sections вне этого репозитория.**
|
||||
Весь механизм задачи опирается на внешний контракт: что настоящий HA при
|
||||
размещении карточки в Sections/grid-дашборде действительно устанавливает
|
||||
на элементе свойство `layout = 'grid'` (K3/K11, оставлено ревью ТЗ как
|
||||
«принято предположительно, поменять свободно» — технический, не
|
||||
продуктовый вопрос). В этой песочнице нет ни реального HA, ни доступа к
|
||||
инструментам веб-поиска/GitHub-поиска (запрошенные `WebSearch` и
|
||||
`mcp__github__search_code` не были разрешены), поэтому свериться с
|
||||
исходником `home-assistant/frontend` я не смог. Все AC2–AC10 в этом
|
||||
дифе проверены только против синтетической фикстуры, которая
|
||||
устанавливает `card.layout = 'grid'` вручную (`demo/smoke_sections_resize.
|
||||
mjs:77`) — они доказывают, что *если* HA присылает этот сигнал, карточка
|
||||
ведёт себя правильно, но не доказывают, что HA действительно его
|
||||
присылает именно так (то же имя свойства, тот же момент жизненного цикла).
|
||||
Это прямой риск: если предположение неверно, весь фиче-код останется
|
||||
мёртвым в проде при полностью зелёных гейтах. Технически это ровно то
|
||||
место, которое ревью ТЗ явно делегировало код-ревью — фиксирую как
|
||||
открытый остаточный риск, а не как находку, потому что задача не может
|
||||
быть проверена исполнением без реального HA, а сам код внутри доступного
|
||||
материала последователен и не содержит внутренних противоречий.
|
||||
- **15 из 19 «прямых совпадений» и все 28 «слабых связей» `smoke-
|
||||
select.mjs`.** Прогнал только `smoke_sections_resize.mjs`,
|
||||
`smoke_houseplan_panel.mjs` (названы в AC), `smoke_render_invalidation.mjs`
|
||||
и `smoke_warm_dialogs.mjs` (точечно — единственные, трогающие изменённую
|
||||
сигнатуру `settleSoftStageLayout`/`_bootSoft` напрямую). Остальные не
|
||||
гонял: рефактор `panelHost → containerOwnedHeight` в
|
||||
`boot-soft-layout.ts` математически не меняет значение для существующих
|
||||
(не-`grid`) карточек, поэтому регрессия там маловероятна; полный прогон
|
||||
матрицы — предрелизная обязанность, а не гейт код-ревью (§8).
|
||||
- **`golden:verify`** — не прогонял. ТЗ прямо говорит: «Golden не
|
||||
требуется, если визуальные пиксели плана/chrome не меняются» — диф не
|
||||
трогает цвета/геометрию плана, только контейнерную высоту и CSS-flex;
|
||||
`check-docs.mjs` подтверждает отсутствие изменений в
|
||||
зафиксированных скриншот-сценариях документации (только WARN о
|
||||
фингерпринте, не ERROR).
|
||||
- **`npm run invariants`** — не прогонял: диф не меняет геометрическую
|
||||
модель плана (стены/комнаты/устройства) и не трогает ссылки на неё,
|
||||
только презентационный слой карточки.
|
||||
- **`python -m pytest tests_backend`** — не прогонял: диф не касается
|
||||
`custom_components/houseplan/**/*.py`.
|
||||
- **Performance-профили** — не названы в AC этой задачи; ТЗ прямо
|
||||
запрещает новый observer/polling, а не вводит его (новый постоянный
|
||||
наблюдатель не добавлен — использован существующий `_roViewport`).
|
||||
- **`typecheck`/`npm test`/`npm run build`/`golden`/`performance_smoke`/
|
||||
browser `smoke`-матрица целиком в CI** — доверился зелёному Validate на
|
||||
точном SHA `b7fb7cf7` (ссылка в задании) для `typecheck`/`test`/`build`;
|
||||
`npm test` и `npm run build` тем не менее перегнал сам (см. выше) для
|
||||
собственной уверенности перед прогоном смоков на пересобранном бандле —
|
||||
оба зелёные, совпадают с Validate.
|
||||
|
||||
## Вердикт
|
||||
|
||||
0 High, 1 Medium (в скоупе задачи, Medium-1 — неполное покрытие AC3
|
||||
браузерным смоком: заявлены RU/DE, реализована только RU). Без High-находок
|
||||
это жёлтый вердикт: автор дополняет `demo/smoke_sections_resize.mjs`
|
||||
немецкой локалью в проверке минимальной высоты и проходит повторный раунд
|
||||
код-ревью — отдельный issue не заводится (#202).
|
||||
|
||||
Всё остальное — AC1–AC2, AC4–AC10, трейлеры, changelog, гейты `typecheck`/
|
||||
`npm test`/`npm run build`/`no-new-any`/`no-new-private-writes`/
|
||||
`bundle:budget`/`check-docs`, четыре новых защитных мутанта и оба
|
||||
относящихся к задаче browser smoke — проверено исполнением и корректно.
|
||||
|
||||
**Жёлтый.**
|
||||
|
||||
---
|
||||
|
||||
Вердикт: жёлтый · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 1 → в задаче
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: подготовлено ревьюером -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: на момент ревью без явного имени в рабочей копии; вершина —
|
||||
`b7fb7cf7e7bce13a44ef0e1af3b97541ddb0dffa`.
|
||||
- База сравнения: `origin/dev` = `f68878cc44b818b6cfbdb3866302e6febaab2445`.
|
||||
- Дерево материала (`git rev-parse HEAD^{tree}` на момент ревью): снято на
|
||||
вершине `b7fb7cf7e7bce13a44ef0e1af3b97541ddb0dffa`, рабочая копия чиста
|
||||
до и после всех локальных гейтов/мутаций (`git status --porcelain`
|
||||
пуст).
|
||||
- Предыдущий раунд (другой этап): `docs/reviews/SPEC-REVIEW-648-r1.md`,
|
||||
вердикт `green`, High 0, Medium 0.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/648-sections-card-resize`, коммит `b7fb7cf7e7bc` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `a7fe21e21d802c04986cbfab31f3065266c8e9ff`
|
||||
```
|
||||
git log --all --format='%H %T' | grep a7fe21e21d80
|
||||
```
|
||||
- Тело issue: `8400466150bde494c01aef14b7d5961be36d721b08a28c69e800bd88ac645154`
|
||||
- Вердикт конвейера: `yellow` · High 0
|
||||
@@ -7,6 +7,7 @@
|
||||
| #649 | [SPEC-REVIEW-649-r1.md](SPEC-REVIEW-649-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 1 | в скоупе задачи (возвращается автору); принято ревьюером с записью, правки не требует | `lab.js` `houseplan-card.ts` |
|
||||
| #649 | [SPEC-REVIEW-649-r2.md](SPEC-REVIEW-649-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #648 | [SPEC-REVIEW-648-r1.md](SPEC-REVIEW-648-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | «Сценарий» не называет персону и; AC10 называет provenance-gate | `docs/SCOPE.md` `scripts/validate-commit-provenance.mjs` `validate.yml` |
|
||||
| #648 | [CODE-REVIEW-648-r1.md](CODE-REVIEW-648-r1.md) | code · r1 | 🟡 жёлтый | 0 | 1 | AC3 документально обещает browser smoke | `demo/smoke_sections_resize.mjs` `docs/TESTING.md` `smoke_sections_resize.mjs` |
|
||||
| #647 | [SPEC-REVIEW-647-r1.md](SPEC-REVIEW-647-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 2 | П.4 ТЗ переносит на новый слот прежнее; ТЗ не упоминает и не защищает документированный | `src/styles/dialogs.styles.ts` `src/styles.ts` `smoke_glow_blending.mjs` `smoke_test_facade.mjs` `smoke_unified_wall_tool.mjs` `docs/UX-MODES.md` `docs/reviews/CODE-REVIEW-195-r1.md` `src/styles/chrome.styles.ts` |
|
||||
| #647 | [SPEC-REVIEW-647-r2.md](SPEC-REVIEW-647-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #647 | [CODE-REVIEW-647-r1.md](CODE-REVIEW-647-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
|
||||
Reference in New Issue
Block a user