From df7a62c82ef0f320ac1367a1272761f479af2612 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:59:37 +0000 Subject: [PATCH] docs: review document for #594 Issue: #594 User-Visible: no --- docs/reviews/SPEC-REVIEW-594-r2.md | 191 +++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-594-r2.md diff --git a/docs/reviews/SPEC-REVIEW-594-r2.md b/docs/reviews/SPEC-REVIEW-594-r2.md new file mode 100644 index 00000000..b01bb777 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-594-r2.md @@ -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 → в задаче** + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `7ce9e6437f25` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `257277214219bb8aac1bf3546c47cebe7615b709` + ``` + git log --all --format='%H %T' | grep 257277214219 + ``` +- Тело issue: `97f5a0277d2aee81abd986c24d874aa94949902428cc33bd2eb845990d48b37b` +- Вердикт конвейера: `yellow` · High 0