docs: review document for #647

Issue: #647
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-25 08:10:38 +00:00
parent 02b374f504
commit 27d78801d0
2 changed files with 236 additions and 1 deletions
+2 -1
View File
@@ -1,10 +1,11 @@
# Индекс ревью
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1046, issue: 368. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1047, issue: 368. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|---|---|---|---|---:|---:|---|---|
| #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 | — | — |
| #646 | [CODE-REVIEW-646-r1.md](CODE-REVIEW-646-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
| #645 | [SPEC-REVIEW-645-r1.md](SPEC-REVIEW-645-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 2 | Отсутствует обязательная строка Touch editor: … из docs/TOUCH-SUPPORT.md → «Documentati…; ТЗ не учитывает существующую зависимость live-подписей Resize от позиции кнопки «Настро…; / Low | `docs/TOUCH-SUPPORT.md` `docs/reviews/SPEC-REVIEW-449-r1.md` `docs/specs/359-furniture-placement-preview.md` `docs/specs/449-double-fit-all.md` `src/houseplan-editor-runtime.ts` `src/houseplan-card.ts` `src/resize-labels.ts` `docs/process/REVIEWER.md` |
| #645 | [SPEC-REVIEW-645-r2.md](SPEC-REVIEW-645-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — |
+234
View File
@@ -0,0 +1,234 @@
# SPEC-REVIEW-647-r2
- **Issue:** https://github.com/Matysh/houseplan-card/issues/647
- **Этап:** `S4-spec-review` (ревью ТЗ, PROCESS.md §2.4)
- **Трек:** `small` (лёгкий), по аналитике автора в комментарии «Аналитика»
- **Материал:** тело issue #647, раздел `## ТЗ`, редакция r2 (снимок на момент
этого ревью, 2026-09-25); предыдущий комментарий-ответ автора «ТЗ r2 —
ответ на SPEC-REVIEW-647-r1»
- **Заход:** r2 · блокирующих циклов израсходовано 1 из 2 (лёгкий трек)
- **Роль:** ревьюер ТЗ (не автор)
## Скоуп ревью
Редакция r2 — прямой ответ на жёлтый вердикт SPEC-REVIEW-647-r1 (0 High,
2 Medium, оба в скоупе, закрываются правкой текста). Дельта локальна: автор
переписал п.4 «Скоупа», добавил К5/К6 в «Контракт поведения» и AC5/AC6 в
таблицу доказательств, расширил «Release-артефакты» (`docs/UX-MODES.md`) и
уточнил «UX, i18n» по touch-контракту; заодно поправил абзац «Проблема (по
коду)», испорченный в r1 форматированием (вложенные обратные кавычки).
Остальные разделы ТЗ (сценарий, «что человек увидит», не-скоуп, план
автотестов, риски, откат, «принято предположительно») не менялись по
существу.
По правилу «объём разбора по дельте» (PROCESS.md §2.10) разбор ниже
сосредоточен на: (а) действительно ли новый текст закрывает Medium-1 и
Medium-2 из r1, (б) не создали ли сами правки новой неоднозначности или
непроверяемого AC. Разделы, не задетые дельтой и уже проверенные в r1 (состав
обязательных §7.1, точность описания кода «как есть», удаление ключа
`count.devices`, не-скоуп, план автотестов, трейлеры), приняты без повторной
проверки — см. «Унаследовано из r1» ниже.
## Как проверялось
1. Сопоставлен текст комментария автора «ТЗ r2 — ответ на
SPEC-REVIEW-647-r1» построчно с находками r1 (Medium-1, Medium-2) —
заявленные правки существуют в текущем теле issue дословно там, где автор
их называет.
2. Перечитан весь текущий раздел `## ТЗ` целиком (не только изменённые
абзацы), чтобы делта не читалась в отрыве от контекста — противоречий
между новыми К5/К6/AC5/AC6 и остальным текстом не найдено.
3. Проверено закрытие Medium-1 (риск: новый слот наследует
`@media (max-width: 1100px) { .head .count { display: none } }` и прячет
крестик на обычной ширине):
- п.1 «Скоупа» теперь явно удаляет само правило `.head .count` вместе со
счётчиком («оно станет мёртвым»), а не просто оставляет его висеть;
- п.2 явно требует для слота «собственный класс... **не** `.count` и без
наследования его правил»;
- п.4 переписан: «слот виден и занимает своё место на любой ширине, где
видна группа кнопок режимов (в том числе 721–1100 px, где счётчик
скрывался)»;
- добавлен К6 и AC6 с прямой проверкой видимости/клика × на 390/768/1000/
1400 px через `elementFromPoint`, с мутантом «слоту правило скрытия
как у `.count`» → смок красный на 1000 и 768 px. 1000 px лежит внутри
диапазона 900–1100 px, который r1 просил проверить явно.
Три независимых слоя защиты (переписанный скоуп, явный запрет
наследования, тестируемый АС с мутантом) закрывают находку с запасом.
4. Проверено закрытие Medium-2 (риск: контракт hit-target ≥24×24 px из
`docs/UX-MODES.md:41-44` не упомянут в ТЗ и не защищён AC, документ не
входит в Release-артефакты):
- новый К5: «Кликабельная зона × — не меньше 24 × 24 CSS px
(`getBoundingClientRect()`...), глиф — 13 px; клик в точку, отстоящую
от центра глифа на 10 px..., закрывает редактор (как в #195)» —
дословно воспроизводит контракт из UX-MODES.md и метод регрессионной
проверки из истории #195;
- новая строка AC5 в таблице с named-мутантом «размер слота 13 px
(переменная) → смок красный» — защитный AC теперь имеет непустой
третий столбец;
- «Release-артефакты» теперь называют `docs/UX-MODES.md` явно: «строка
про panel-host (убрать «device count»...) и абзац про × (× — в
отдельном слоте..., hit target ≥ 24 × 24 px сохранён)»;
- «UX, i18n» теперь содержит явное обоснование вместо голого
утверждения: «Touch: размер кликабельной зоны × не уменьшается
(≥ 24 × 24, как сейчас)...» — это уже не непроверенное заявление из
«Аналитики» r1, а требование ТЗ со своим AC.
5. Прочитан `docs/UX-MODES.md` ещё раз (строки 1–50) и сверен построчно с
планом Release-артефактов r2: строка 14 («...device count, zoom and
actions remain») и абзац строк 33–44 (крестик как часть кнопки-режима,
«hit target of at least 24 × 24 px without changing the tab's layout
footprint») — оба фрагмента действительно устареют после правки и оба
поимённо покрыты планом автора («строка про panel-host» и «абзац про
×»). Расхождений между тем, что попросил ревью r1, и тем, что реально
устареет в документе, нет.
6. Проверено состояние кода на материале ревью (SHA `1ba4c23a`, `git show
--stat HEAD`, `git branch -a`, `git log --oneline --all | grep 647`):
для #647 в дереве нет ничего, кроме коммита `docs: review document for
#647` (добавляет только сам документ r1 и строку в `docs/reviews/
INDEX.md`); ветка `issue/647-toolbar-stable-width` в этом чекауте
отсутствует — код ещё не написан. Это подтверждает, что на этапе `spec`
гейты (`tsc`, `npm test`, `npm run build`, `check-docs.mjs`, смоки,
`golden`) неприменимы: сверять их не с чем, `src/**` в материале не
меняется. Ровно так же поступил ревьюер r1 (см. его «Чего не проверял»).
7. Перепроверены факты кода, на которые опирается r2 (не только цитаты
ТЗ, а сам код): `src/styles/dialogs.styles.ts:27-29` (правило `.head
.count`, `max-width: 1100px`), `src/styles/chrome.styles.ts:154-172`
(`.modetab .closex`, 24×24 хит-зона через отрицательные поля),
`src/houseplan-card.ts:10811,10820` (крестик внутри активной кнопки,
`<span class="count">` отдельным элементом) — совпадает с описанием
«Проблема (по коду)» дословно, включая уже исправленный в r2 абзац
(нет разрушенных обратных кавычек, текст читается корректно).
8. Проверен `docs/reviews/INDEX.md` — строка `#647 | SPEC-REVIEW-647-r1.md
| spec · r1 | 🟡 жёлтый | 0 | 2 | ...` присутствует и соответствует
документу r1; смежные подсистемные записи (`#195` code · r1/r2 — оба
🟢, `#437` — источник сводной панели) подтверждают исходные ссылки ТЗ
на историю контрактов.
9. Перечитаны `docs/SCOPE.md` и `docs/process/REVIEWER.md` заново для этого
захода (без изменений в применимости выводов r1: задача обслуживает
J1/J6 как polish уже принятого механизма переключения режимов, вне
скоупа не выходит).
Гейты не гонялись — этап `spec`, материал ревью текстовый (тело issue), в
дереве материала (SHA `1ba4c23a`) для #647 нет диффа `src/**`, `test/**`
или `demo/**`: код появится только после перехода в `S5-ready`/`S6-in-progress`
и будет предметом код-ревью. Это не сокращение объёма, а соответствие
самому этапу — гейты §8 привязаны к диапазону коммитов, а не к тексту
issue.
## Находки
Не найдено. Оба Medium из r1 закрыты правкой текста ТЗ, новых
неоднозначностей, непроверяемых AC или противоречий делта не внесла.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium-1: п.4 ТЗ дословно предлагал унаследовать `.head .count`'s `@media (max-width: 1100px){display:none}`, крестик мог исчезнуть на обычной ширине 721–1100 px, ни один AC это не ловил | П.1 «Скоупа» удаляет само правило `.head .count`, а не наследует его; п.2 явно запрещает слоту класс `.count` и наследование его правил; п.4 переписан («слот виден... в том числе 721–1100 px, где счётчик скрывался»); добавлен К6 + строка AC6 с мутантом «правило скрытия как у `.count` → красный на 1000 и 768 px» | Тело issue #647, раздел «Скоуп» п.1–п.2, п.4 «Адаптивность»; раздел «Контракт поведения» К6; таблица «AC · чем доказан · чем краснеет», строка AC6 |
| Medium-2: контракт hit-target ≥24×24 px (`docs/UX-MODES.md:41-44`, issue #195) не упомянут в ТЗ, нет защищающего AC, `docs/UX-MODES.md` не в Release-артефактах, «Аналитика» заявляла «hit area прежние» без обоснования | Добавлен К5 (дословно воспроизводит контракт ≥24×24 px и метод проверки как в #195); добавлена строка AC5 с мутантом «размер слота 13 px (переменная) → смок красный»; «Release-артефакты» теперь называют `docs/UX-MODES.md` (обе строки: про panel-host и про ×); «UX, i18n» содержит явное обоснование вместо голого утверждения | Тело issue #647, раздел «Контракт поведения» К5; таблица AC, строка AC5; раздел «Release-артефакты»; раздел «UX, i18n, модель данных» |
## Унаследовано из r1 (принято без повторной проверки)
Материал: `docs/reviews/SPEC-REVIEW-647-r1.md`, SHA дерева `973c05543e3f...`
(якорь того раунда). Делта r2 не касается перечисленного ниже, поэтому
повторно не перепроверялось:
- Обязательные разделы §7.1 присутствуют все (сценарий, «что человек
увидит до/после», проблема, скоуп/не-скоуп, UX/i18n/модель данных, план
автотестов, риски, откат) — r1, раздел «Что проверено и корректно».
- Описание бага «по коду» и границы правки совпадают с
`src/houseplan-card.ts:10797-10820` — r1, п.6 «Как проверялось» (в r2
перепроверено повторно в п.7 этого документа, поскольку абзац
редактировался; расхождений нет).
- Безопасность удаления ключа `count.devices` (единственное место чтения,
сводная панель #437 использует другой источник) — r1, п.7 «Как
проверялось».
- AC1–AC3 однозначны и привязаны к способу доказательства с непустой
колонкой «чем краснеет» — r1, «Что проверено и корректно» (нумерация
AC1–AC3 в r2 не изменилась по содержанию, только сдвинулась таблица
вниз добавлением AC5/AC6).
- Не-скоуп сформулирован явно, без пересечения с #437 — r1, «Что проверено
и корректно».
- План автотестов ссылается на реально существующие механизмы
(`test/core-file-budget.test.mjs`, `scripts/smoke-links.mjs`,
`scripts/mutation-registry.mjs`, `scripts/smoke-select.mjs`, фасад
`data-hp="mode-tab"`) — r1, п.10 «Как проверялось».
- Трейлеры `User-Visible: yes` и требование обоих changelog в одном
коммите — r1, «Что проверено и корректно».
- Открытых продуктовых вопросов владельцу нет — r1, «Что проверено и
корректно»; в r2 не появилось новых.
## Что проверено и корректно
- Оба Medium из r1 закрыты по существу (не декларативно): каждое —
переписанным текстом скоупа/контракта **и** новым тестируемым AC с
названной мутацией, а не только обещанием в комментарии автора.
- Новые К5/К6 и AC5/AC6 однозначны, ссылаются на конкретный метод
измерения (`getBoundingClientRect`, `elementFromPoint`, смещение 10 px
от центра глифа) и называют мутацию, на которой тест обязан покраснеть —
колонка «чем краснеет» не пустая ни в одной новой строке.
- Правка Release-артефактов называет обе фактически устаревающие строки
`docs/UX-MODES.md` (строка 14 про panel-host/device count, абзац
33–44 про крестик и его футпринт) — проверено построчным сравнением с
текущим содержимым файла, а не на слово автора.
- Исправление абзаца «Проблема (по коду)» (вложенные обратные кавычки r1)
не изменило фактического содержания — код-цитаты и номера строк те же.
- Дельта не создала противоречий с неизменёнными разделами: «принято
предположительно» по-прежнему корректно описывает размер слота как одну
переменную, совпадающую с прежней кликабельной зоной (24 px), что теперь
явно требуется К5.
- На материале ревью (SHA `1ba4c23a`) для #647 отсутствует какой-либо код
— подтверждено `git show --stat` и `git log`; риск «текст ТЗ разошёлся с
уже написанным кодом» (типичная причина находки на код-ревью) здесь не
применим.
## Чего не проверял
- Гейты (`tsc`, `npm test`, `npm run build`, `check-docs.mjs`, смоки,
`golden`, инварианты, `smoke-select.mjs`) — не прогонял: код для #647 ещё
не написан на материале ревью, диапазон ревью — текст ТЗ, а не диапазон
коммитов. Предмет код-ревью после реализации.
- Не проверял браузером в реальном рендере поведение на 1000/900 px —
вывод о том, что мутант «правило скрытия как у `.count`» действительно
покраснит смок, сделан чтением плана AC, а не исполнением ещё не
написанного смока; это неизбежно на этапе `spec` и будет прямой
обязанностью код-ревью (проверить, что `demo/smoke_toolbar_stable_width.mjs`
умеет падать на названной мутации).
- Не переоценивал заново трек `small`/критерии лёгкого трека — не задеты
делтой r2 (добавление двух AC не меняет ни сложность ≤3, ни «одну
поверхность», ни отсутствие миграции конфига), и в r1 они не были
находкой.
- Не проверял golden-кадры и скриншоты документации — правка кода ещё не
существует; риск golden-регресса уже учтён в разделе «Риски» ТЗ
(принято в r1 без замечаний).
## Вердикт
Найдено 0 High, 0 Medium. Оба Medium из r1 закрыты по существу текстом
редакции r2 — каждое явной правкой формулировки контракта/скоупа и новым
тестируемым AC с названной мутацией. Новых неоднозначностей или
непроверяемых AC делта не внесла. ТЗ готово к разработке.
---
<!-- material-anchors: заполняется конвейером (#414) -->
## Материал раунда
- SHA материала: `1ba4c23a5813d0cf51fb010d79e45416a15facf2` (рабочая копия
ревью).
- Тело issue #647, редакция r2 — снимок на момент этого ревью,
2026-09-25.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `dev`, коммит `1ba4c23a5813` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `b5de29ae951c3df446606e8324139fdb919ff0e1`
```
git log --all --format='%H %T' | grep b5de29ae951c
```
- Тело issue: `96f3d23ef7e626083567418cc5d5c098150d97627da79dc8ebe77b949f39a1c1`
- Вердикт конвейера: `green` · High 0