docs: review document for #594

Issue: #594
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-18 19:59:37 +00:00
parent 7ce9e6437f
commit df7a62c82e
+191
View File
@@ -0,0 +1,191 @@
# SPEC-REVIEW-594-r2
Issue: https://github.com/Matysh/houseplan-card/issues/594
Этап: ревью ТЗ (PROCESS.md §2.4), заход r2, лимит циклов 4 (полный трек — меток
`small`/`trivial` на issue нет).
## Материал раунда
- Тело issue #594 в текущем виде (создано 2026-09-18T19:37:30Z комментарием-заведением,
далее **ни разу не редактировалось** — в `gh api .../issues/594/events` нет ни одного
события `edited`; единственные события — labeled/unlabeled и два `commented`).
- `sha256` нормализованного тела на этом прогоне (из `review-prepared/prepared.json`,
сгенерировано конвейером при применении текущей метки `S4-spec-review` в 19:43:22):
`material_issue_body = 97f5a0277d2aee81abd986c24d874aa94949902428cc33bd2eb845990d48b37b`,
`material_sha = 7ce9e6437f2584198fef3e3618173a885e825044` (рабочая копия репозитория),
run_id `35387520162`, `cycle: "2"` — совпадает с заходом r2 в заголовке задачи.
- **Ключевой факт раунда: дельты с материалом r1 нет.** Комментарий Matysh 19:43:19
("Редакция ТЗ по уточнению владельца 18.09... Возвращаю на ревью ТЗ") текстуально
описывает содержимое, которое уже присутствует в теле issue с момента его создания
(К5, К6, AC11 и т. д. — сверено построчно), а не отдельную правку тела: событий
`edited` после создания нет. Значит вердикт r1 (комментарий ниже) и этот раунд
разбирают **один и тот же байт-в-байт текст**.
## Вердикт предыдущего раунда (r1) — как он найден
`docs/reviews/SPEC-REVIEW-594-r1.md` в репозитории не найден ни в одной ветке
(`git log --all --diff-filter=A -- '*SPEC-REVIEW-594*'` — пусто) и не найден на диске
CI-раннера: это ожидаемо и не является дефектом (см. преамбулу задачи — документ
некоммитнутого раунда живёт вне репозитория и не обязан переживать раунд). Материалом
для сверки служит вердикт-комментарий:
> **Вердикт: жёлтый · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 1 → в задаче**
> (комментарий `github-actions[bot]`, 2026-09-18T19:48:40Z,
> https://github.com/Matysh/houseplan-card/issues/594#issuecomment-5735359281)
**Находка процесса (не блокирует, фиксирую по инструкции раунда):** этот комментарий не
называет ни SHA материала, ни blob тела issue, ни ссылку на артефакт с анкорным блоком
из PROCESS.md §2.10 п.1 ("блок дописывает SHA ветки, дерево материала и блоб ТЗ").
Материал пришлось восстанавливать косвенно — через отсутствие `edited`-событий в
таймлайне issue и через `prepared.json` текущего запуска. Для ревью ТЗ (в отличие от
код-ревью) SHA ветки в принципе неприменим, но blob тела — применим и его стоило бы
называть в самом вердикт-комментарии, а не только в служебном JSON конвейера.
## Закрытие раунда r1
| # | Находка r1 | Чем закрыта | Где это видно |
|---|---|---|---|
| Medium (в скоупе) | Раздел «i18n» называет только 4 новых `*.help`-ключа для подсказок групп, но не называет ключи для текста самих заголовков групп («Основное», «Заливка», «Источники», «Размеры») — а это такой же пользовательский текст через `_t()`, как и всё остальное; ни один существующий `room.*` ключ не совпадает текстом ни с одним из четырёх заголовков | **Не закрыта.** Тело issue не редактировалось ни разу с момента создания (см. «Материал раунда» выше) | Раздел `### i18n` тела issue #594, текущий текст: *«Новые ключи только на справку заголовков групп: `room.basics.help`, `room.fill.help`, `room.sources.help`, `room.sizes.help`… Существующие ключи не трогаются»* — дословно тот же текст, который цитировал r1 |
| Low: раздел «Release-артефакты» ссылается на кадр `room-card` (View), а не на диалог настроек | Снята r1 решением ревьюера с записью, повторной проверки не требует | комментарий r1 |
| Low: раздел «Проблема» не выделен явным заголовком | Снята r1 решением ревьюера с записью («закрыт предшествующим `## Аналитика`») | комментарий r1 |
Раз тело не менялось, Medium-находка объективно не может быть закрыта в этом раунде —
это не новая находка, а тот же дефект ТЗ, ещё не исправленный автором. Верификация
собственным чтением (ниже) подтверждает: находка обоснована.
### Независимая проверка находки r1 (не просто доверие)
Прочитал текущую структуру диалога, чтобы находка не осталась голословной цитатой:
- `src/editors/room-settings-dialog.ts:60` — `room.settings_section` = «Настройки
комнаты (переопределяют пространство)» сейчас заголовком накрывает **весь** блок:
заливку **и** оба источника (temp/hum). ТЗ делит этот блок на два новых заголовка
«Заливка» и «Источники» — прямой реюз `room.settings_section` для одного из двух
новых заголовков без явного решения невозможен, нужен минимум один новый ключ.
- `src/editors/room-settings-dialog.ts:93` — `room.sizes_section` = «Размеры шрифтов»
(en: «Font sizes») — по смыслу близко к предложенному заголовку «Размеры» и мог бы
быть переиспользован **явным решением**, но ТЗ этого решения не фиксирует.
- Блок «Основное» (имя + область) сегодня заголовка вообще не имеет — это четвёртый
ключ, которого нет ни в существующем коде, ни в разделе i18n ТЗ.
- Итого: минимум 1, вероятно 3–4 новых `*_title`-ключа (плюс сопутствующие `en/ru/fr/de`,
как и у `.help`), которых в разделе i18n нет ни явно, ни как решение «переиспользовать
Х». DoR §2.5 требует «i18n: ключи en + ru перечислены» — список неполон, точно так же,
как записал r1.
Вывод: находка r1 не просто актуальна, а её независимая перепроверка кода только
усиливает — реального готового реюза на 3 из 4 заголовков нет, значит это не забытая
формальность, а недостающая проектная развилка, которая по DoR обязана быть решена до
`S5-ready`.
## Унаследовано из r1 (без повторной проверки состава, только точечная сверка)
Материал идентичен, поэтому эти пункты не разбираю заново по существу — я лишь выборочно
перепроверил чтением кода несколько наиболее рискованных, чтобы не просто доверять
чужому выводу (список ниже помечен, что именно сверено сейчас):
- К1 (ключи черновика `_nameSel`, `_areaSel`, `_roomFill`, `_roomCustomFill`,
`_roomTempMin/Max`, `_roomTempSrc/_roomHumSrc`, `_roomNameScale`, `_roomLabelScale`) —
унаследовано с r1, **не сверял повторно** (не риск для i18n-находки).
- `_renderRoomSource` — единственный потребитель — унаследовано с r1.
- К3 (`hp-color-opacity`, событие `hp-color-opacity-change`) — **сверено повторно**:
`grep` подтверждает событие и его контракт `{color, opacity}` используется тем же
образом в `room-settings-dialog.ts:80` и в остальных потребителях компонента
(`decor-image-editor.ts`, `houseplan-editor-runtime.ts`). Совпадает с выводом r1.
- Шесть вариантов заливки (АС/UX) — **сверено повторно**: `ROOM_FILL_MODES` в
`src/logic.ts:932` содержит 5 значений (`none, lqi, light, temp, custom`), плюс код
диалога добавляет вариант `''`/`fill.inherit` первым (`room-settings-dialog.ts:62`) —
итого 6, как заявляет ТЗ. Подтверждено.
- AC7: golden-сцены `room-temperature-dialog-{desktop-en,mobile-ru}` — **сверено
повторно**: `demo/golden/matrix.mjs:1016-1021` объявляет обе сцены с
`dialog: 'room-temperature'`, а `demo/golden/harness.mjs:1740-1767` для этого типа
сценария вызывает `card._openRoomEdit(room)` и ищет `hp-dialog.roomdialog` — это
ровно тот же диалог, который рендерит `renderRoomSettingsDialog` (класс `roomdialog`,
`room-settings-dialog.ts:34`). Заявленные эталоны действительно покрывают
редактируемую форму, а не отдельный мини-диалог с похожим именем.
- AC8/тест `editor-dialog-modules.test.mjs` — файл существует
(`test/editor-dialog-modules.test.mjs`), `INITIAL_VIEW_GZIP_CEILING` определён в
`scripts/bundle-budget.mjs:294` — **сверено повторно**, унаследованный вывод r1 верен.
- `hp-help` и паттерн `.help(.aria)` — унаследовано с r1, **не сверял повторно**.
- Техническая развилка стилей панель-строка / карточка-теги (К5, `cardStyles` как
синхронный граф, `houseplan-card.ts:13711`) — унаследовано с r1, не риск для
i18n-находки, не пересматриваю.
- Согласие ТЗ с обоими решениями владельца от 18.09 (набор+диалог одним issue; стили
панели не трогаются в этом шаге) — унаследовано с r1.
- Обе Low-находки r1 (снятые с записью) — унаследованы как закрытые, не пересматриваю.
Источник наследования: комментарий-вердикт r1,
https://github.com/Matysh/houseplan-card/issues/594#issuecomment-5735359281, материал —
тело issue #594, идентичное текущему (см. «Материал раунда»).
## Находки этого раунда
### Medium (в скоупе задачи, унаследована из r1, не закрыта)
**Раздел «i18n» ТЗ не называет ключи для текста заголовков четырёх новых карточек-групп**
(«Основное», «Заливка», «Источники», «Размеры»), хотя раздел «Что человек увидит»
и «UX» прямо вводят эти подписи как видимый пользователю текст, идущий, как и всё
остальное в диалоге, через `_t()`. Ни один существующий ключ `room.*` не покрывает все
четыре напрямую (см. «Независимая проверка находки r1» выше — `room.settings_section`
накрывает сразу два новых заголовка, `room.sizes_section` близок к одному, у «Основное»
реюза нет вовсе). DoR §2.5 требует полный список i18n-ключей en+ru до перехода в
`S5-ready` — список сейчас неполон.
**Воспроизведение:** открыть раздел `### i18n` тела issue #594 — там 4 ключа `*.help` (+
`.aria`), и не более. Раздел `### Контракт поведения`, пункт «После:» и раздел `### UX`
называют четыре подписи групп текстом, которого в i18n-разделе нет.
**Правка (описана уже r1, повторяю, так как не выполнена):** добавить в раздел i18n
явный список из 4 ключей заголовков (например `room.basics_title`/`room.fill_title`/
`room.sources_title`/`room.sizes_title`) для en/ru/fr/de **или** явно решить для каждого
заголовка «переиспользуем ключ X» — в том числе зафиксировать, что `room.settings_section`
для двух новых заголовков не подходит без переименования/расщепления, а `room.sizes_section`
можно оставить как есть только если текст «Размеры шрифтов» устраивает как заголовок
карточки «Размеры» (сейчас это не решено явно).
## Что проверено и корректно
- Материал раунда установлен точно (пустая дельта подтверждена таймлайном issue, а не
предположением).
- Находка r1 перепроверена независимым чтением кода, а не просто процитирована.
- Пять пунктов из унаследованного списка r1 сверены повторно точечно (см. выше) и
подтвердились без расхождений.
- ТЗ по-прежнему формально полно по остальным разделам §7.1 (сценарий, что человек
увидит, скоуп/не-скоуп, контракт К1–К7, UX, модель данных, AC1–AC11 с доказательством,
план автотестов, риски, откат, release-артефакты) — здесь не пересматриваю состав,
так как дельта их не касается и r1 их уже принял.
## Чего не проверял
- Полный повторный аудит AC1–AC11, К1–К7, рисков и release-артефактов «с нуля» — дельта
нулевая, они наследуются из r1 согласно PROCESS.md §2.10 п.4 (перепроверяются только
AC, которые задевает дельта; дельты нет, кроме отсутствия правки самой находки).
- Гейты кода (typecheck/test/build/golden/смоки) — этап spec, кода ещё нет, они
неприменимы к ревью ТЗ.
- Не связывался с владельцем и не запрашивал новых продуктовых уточнений: находка
этого раунда техническая (список i18n-ключей — «то, чего пользователь не наблюдает»
до факта показа формы; сами названия групп уже зафиксированы в ТЗ как факт, не как
открытый продуктовый вопрос), значит она решается автором и ревьюером, не владельцем.
## Вывод
Дельты со времени r1 нет: находка Medium не закрыта, потому что тело issue не
редактировалось. Верхнеуровневый разбор ТЗ сокращён по PROCESS.md §2.10 (дельта пуста),
но находка перепроверена по существу, а не унаследована слепо. Возврат автору для правки
раздела i18n; при следующем заходе ревью снова ограничится дельтой, если правка не
заденет ничего кроме этого раздела.
**Вердикт: жёлтый · заход r2 · блокирующих циклов 2/4 · High: 0 · Medium: 1 → в задаче**
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `dev`, коммит `7ce9e6437f25` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `257277214219bb8aac1bf3546c47cebe7615b709`
```
git log --all --format='%H %T' | grep 257277214219
```
- Тело issue: `97f5a0277d2aee81abd986c24d874aa94949902428cc33bd2eb845990d48b37b`
- Вердикт конвейера: `yellow` · High 0