Files
houseplan-card/docs/reviews/SPEC-REVIEW-594-r2.md
T
2026-09-18 19:59:37 +00:00

19 KiB
Raw Blame History

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