20 KiB
SPEC-REVIEW-662-r3
- Issue: https://github.com/Matysh/houseplan-card/issues/662
- Этап:
S4-spec-review(ревью ТЗ, PROCESS.md §2.4) - Трек:
ask, подтверждено в r1 и не пересматривается (новый UX-контракт, более одной поверхности, влияние на touch и на перф — критерии §5). - Материал:
- тело issue #662 в текущей редакции — последняя правка комментарием Matysh в 2026-10-01T20:22:58Z («Правки ТЗ по материалам дизайнера»); более новых правок тела на момент ревью нет;
- архив дизайнера
Issue-662-LED-light-spec-2026-10-01.zip, вложенный комментарием nikitaevfz-commits в 2026-10-01T15:47:33Z — скачан, SHA-256 всех 6 файлов сверен с его собственнымMANIFEST-SHA256.txtи совпал (README.md,TZ-issue-662-LED-strips.md,FIGMA-LINK.url,ISSUE-LINK.url,previews/Led-Off.png,previews/Led-On.png); - оба кадра
Led-Off.png/Led-On.pngоткрыты и просмотрены визуально; docs/reviews/SPEC-REVIEW-662-r1.md,-r2.md— вердикты и материал прошлых заходов;docs/reviews/CODE-REVIEW-679-r1.md,git logпо #679 — проверка актуальности путей документации, названных в AC14.
- Заход: r3 · блокирующих циклов израсходовано 1 из 4 (потрачен r1; r2 — зелёный, бюджет не увеличивает, PROCESS.md §4)
- Роль: ревьюер ТЗ (не автор)
Скоуп ревью
Без изменений по существу с r2: протяжённый источник света (LED-лента) —
ломаная вдоль стен вместо значка в точке, рисуется в редакторе плана
инструментом «LED-лента» (контракт цепочки стен), привязывается к обычному
light.* маркеру через диалог «Добавить устройство»; во View/киоске/
houseplan-space-card — капсульная полоса on/off/unavailable с хит-тестом по
всей длине, линейный источник в fill «Свечение», поднята в 2.5D; бэкенд —
схема led_strips, инвариант «один маркер — не более одной ленты», per-space
export/import, support package.
Правка 01.10 добавляет новый слой требований поверх этого контракта: визуальный эталон — макеты дизайнера, которым обязана соответствовать реализация (решение 11, AC20), фиксированный радиус свечения по умолчанию 50 см вместо «половины общего» (решение 12, заменяет решение 3), точный цвет ядра в заливке «Свечение» и вне её (решения 13–14), путь материалов (решение 15).
SCOPE-проверка не переоткрывается: r1 уже сверил задачу с J1/J7 и «никогда не строить» — правка 01.10 ничего не меняет в том, какую работу закрывает задача, только в том, как придирчиво сверяется её внешний вид.
Закрытие раунда r2
Вердикт r2 — зелёный, находок не было (High: 0, Medium: 0). Закрывать нечего; раздел ведётся для формы требования §2.10.
Унаследовано из r2 (не проверялось повторно)
Контракт C1–C5, C8–C12 без изменений текста с r2; C13 (стены) — также
без изменений текста, полный разбор был выполнен в r2 по правилу «дельта не
локальна». AC1, AC2, AC5, AC7–AC19 (кроме точечных уточнений, разобранных
ниже), UX-тексты, модель данных/миграция, i18n, риски и откат, относящиеся к
этим пунктам, — приняты без повторной проверки на основании
docs/reviews/SPEC-REVIEW-662-r2.md (зелёный, материал — тело issue после
комментария 6, закрывшего Medium-1/Low-1 из r1).
Разбор по дельте (правки 01.10)
Проверены все места, изменённые комментарием Matysh 2026-10-01T20:22:58Z: решения 11–15, раздел «Визуальный эталон», C3 (замыкание ленты по клику в первую точку), C6 (два штриха V1, сдвиг t/2 у грани V2), C7 (радиус по умолчанию 50 см), AC3/AC4/AC6 (уточнения), новый AC20, обновлённый список мутантов, дополнения в «Риски» и «Release-артефакты».
- Четыре сцены кадров в «Визуальном эталоне» (прямая на полу / прямая у стены
/ Г-образная / замкнутый прямоугольник) и их цвета (
#80D5FF,#E680FF,#FFEA80,#58FF58) дословно совпадают с перечнем и порядком вTZ-issue-662-LED-strips.md§2.1–§2.2 — сверено построчно, расхождений нет. - Замеры (ядро 6 px / обводка 3 px, линейное поле ≈100 px, D ≈ 68 px) в
issue совпадают с
TZ-issue-662-LED-strips.md§2.1/§3 («номинальная высота белого ядра — 6 px, внешняя обводка — 3 px», «линейное поле — ориентировочная глубина 86–102 px») — сверено, совпадает в пределах уже заявленной погрешности. - Оба кадра открыты визуально: включённая прямая лента на свободном участке
пола (кадр
Led-On.png) действительно рендерится белым тонким ядром внутри голубого ореола — подтверждает решение 13 («белое ядро» в заливке «Свечение») как прочтение именно кадра, а не текста ТЗ дизайнера (см. находку Medium-1 ниже о его тексте). - Мутанты
strip-glow-default-radius,strip-on-core-colored-in-glow,strip-face-render-offset-offцелятся ровно в новые нормы решений 12/13/V2 — соответствие есть. - Нумерация golden-кадров сходится: AC9 даёт 3 сцены, AC20 — ещё 2
(
led-strip-design-reference-{off,on}-light), итого 5 — ровно столько, сколько обещано в «Release-артефакты» («golden: +5 кадров»).
Находка Medium-1 — радиус по умолчанию: ТЗ дизайнера противоречит решению 12, расхождение не названо
Решение 12 (01.10) заменяет прежнее «половина общего радиуса» на
фиксированные 50 см, explicitly обосновывая это тем, что «при общих 3 м
половина дала бы поле втрое глубже макета» — то есть решение принято по
изображению кадра, а не по тексту дизайнера. Но committed-архив (который по
решению 15 целиком ляжет в docs/design/662-led-strips/ под лицензией
репозитория как материал постоянного хранения) в своём собственном
TZ-issue-662-LED-strips.md §9 говорит буквально обратное:
«Световой источник линейный: по сегментам строятся капсулы радиуса
glow_radius_cm, а при отсутствии персонального значения — половины общего радиуса.»
Это дословно формула решения 3, которое решение 12 отменяет
(«Радиус свечения без персональной настройки — половина общего. Заменено
решением 12»). Иными словами, письменное ТЗ дизайнера, которое вот-вот
ляжет в репозиторий как канонический референс (и на которое прямо ссылается
AC20 — «таблица… по V1–V6 и критериям 1–10 §11 ТЗ дизайнера»), содержит
значение по умолчанию, прямо противоречащее действующему контракту C7/AC4.
Ни в разделе «Визуальный эталон» (где перечислены «В продукт не переносятся:
поле поверх значков и подписей (V4), пик ≈0,95… (V5), шов… (V3), толщина
0,18 D… (C6)»), ни в AC14 (docs/design/662-led-strips/README.md — происхождение материалов), ни где-либо ещё в issue это конкретное
расхождение не названо и не объяснено. AC20 требует сравнения с «V1–V6 и
критериями 1–10 §11» дизайнерского документа — а §9 (формула радиуса) не
входит ни в V1–V6, ни в перечисленные 10 критериев §11, то есть у этого
конкретного, уже случившегося расхождения в принципе нет места в
деливерablз, где оно было бы зафиксировано.
Почему это находка, а не придирка: материал, который ляжет в репозиторий
как справочный документ происхождения дизайна, будет без всякой пометки
утверждать значение по умолчанию, обратное тому, что реализует код. Будущий
читатель docs/design/662-led-strips/TZ-issue-662-LED-strips.md (включая
код-ревьюера AC14) увидит «половина общего радиуса» рядом с кодом, который
делает «50 см, от общего не зависит», и не найдёт объяснения — ни в этом
файле, ни в README архива, ни в issue.
Что нужно: добавить одну строку — либо к решению 12/C7 в теле issue
(«ТЗ дизайнера §9 здесь заменено решением 12 по причине, см. «Риски»»), либо
явно поручить docs/design/662-led-strips/README.md (AC14) аннотировать это
расхождение при коммите архива. Любой из двух вариантов закрывает находку.
Находка Medium-2 — AC14 и раздел «Скоуп» называют документы, удалённые #679
AC14 требует правок документов «…LIGHT («Linear sources», «Strips and
walls»), DEVICE-LIGHT-SETTINGS-MATRIX, USER-GUIDE…, TESTING-DEMO
(сущность стенда)…». Та же ссылка на docs/TESTING-DEMO.md повторена в
### Скоуп: «сущность light.demo_led_strip… в seed стенда (demo/stand,
docs/TESTING-DEMO.md)».
Оба файла физически отсутствуют в репозитории:
$ find . -iname "DEVICE-LIGHT-SETTINGS-MATRIX*" -o -iname "TESTING-DEMO.md"
(пусто)
Оба удалены коммитами #679 (5a258f31, 03078038, смержено 2026-09-27,
после r1/r2 этой задачи, выполненных 26.09, — отсюда расхождение не
поймано раньше) и прочитаны/подтверждены в docs/reviews/CODE-REVIEW-679-r1.md:
«LIGHT.md ← DEVICE-LIGHT-SETTINGS-MATRIX.ru.md | файл удалён (-122
строки), прочитан перенесённый раздел… 36-строчная матрица» и «TESTING-DEMO.md
→ demo/stand/README.md | файл удалён (-469 строк)…». Содержимое матрицы
сейчас — раздел в docs/LIGHT.md (36-кейсовая таблица, тест
test/devices.test.mjs:1981 подтверждён в том же документе), содержимое про
демо-стенд — demo/stand/README.md (прочитан, актуален).
Правка AC14 на «DEVICE-LIGHT-SETTINGS-MATRIX» избыточна и невыполнима в
буквальном смысле: такого файла для правки не существует, а задача правки
матрицы уже покрыта соседним пунктом «LIGHT («Linear sources», «Strips and
walls»)» — после #679 это один и тот же файл. Для стенда правка должна
указывать на demo/stand/README.md, а не на docs/TESTING-DEMO.md.
Что нужно: убрать отдельный пункт «DEVICE-LIGHT-SETTINGS-MATRIX» из AC14
(поглощается пунктом «LIGHT»); заменить docs/TESTING-DEMO.md на
demo/stand/README.md в AC14 и в «### Скоуп».
Проверено и корректно
- Решения 11–15 внутренне согласованы друг с другом и с контрактом C6/C7/AC3/ AC4/AC20 (см. «Разбор по дельте» выше) — кроме двух находок.
- Нормы V1–V6 в «Визуальном эталоне» (толщина/цвет/поле/слои/интенсивность/
переключение) корректно ссылаются на существующие механизмы
(
resolveGlowAppearance,GLOW_FALLOFF,glowAlpha,GLOW_FADE_MS,clipCache,mix-blend-mode: lighten/screen) — все эти идентификаторы существуют вsrc/glow-scene.ts,src/logic.ts,src/glow-blend.ts(find/grepподтверждают присутствие). - Четыре геометрии и их цвета в описании кадров дословно совпадают между
issue и
TZ-issue-662-LED-strips.md— сверено построчно. - AC20 количественно проверяем: пороги названы числом (10 % на углу/стыке, r/2, r + перо) и методом (смок, golden, ACCEPTANCE.md) — не голословное «похоже на макет».
- Нумерация golden-кадров (3 из AC9 + 2 из AC20 = 5) сходится с «Release- артефакты».
- Ссылки
ARCHITECTURE.md«§Device markers» и «§Markup editor» (AC14) существуют как заголовки (docs/ARCHITECTURE.md:209,292) — не стале. docs/LIGHT.md«What stops light» существует (используется C13, унаследовано из r2, перепроверено заодно) —docs/LIGHT.md:20.- Путь материалов
docs/design/662-led-strips/следует соглашениюNNN-slug, уже занятому600-settings-dialogs,649-25d-stage6; имя скриптаcapture_design_pairs_662.mjsв «Плане автотестов» соответствует прецедентуdemo/capture_design_pairs_600.mjs— не придумано с нуля.
Чего не проверял
- Скриншоты/golden не существуют до реализации — машинные проверки V1–V4
в
smoke_led_strip_glow.mjs, сценыled-strip-design-reference-*иACCEPTANCE.mdне запускались и не могли: кода нет, это ревью ТЗ. Проверена только формулируемость и численная проверяемость критериев, не их фактическое исполнение. - Figma-макет напрямую не открывался (ссылка в архиве недоступна без логина, как и указано в issue) — нормы сверены только с растровыми кадрами и письменным ТЗ дизайнера, как и сам автор issue.
- Пиксельная точность радиуса 50 см (≈100 px при зуме 202 %, ±10 см погрешность) не перемерялась линейкой по кадру — проверено на глаз по открытым изображениям, цифра правдоподобна, но не промерена заново.
- Гейты кода (
tsc,npm test,npm run build, смоки, golden, мутанты, pytest) не прогонялись: на этапеspecкода нет, зависимости и Chromium не ставились (#696, см. также AGENTS.md). Это не пропуск гейта, а отсутствие предмета для него на этом этапе. - Содержимое
FIGMA-LINK.url/ISSUE-LINK.urlне открывалось — чисто навигационные файлы, не несущие норм.
Вывод
Два Medium в скоупе задачи, без отдельного issue (чинятся правкой тела issue): контракт радиуса по умолчанию расходится с письменным ТЗ дизайнера, которое вот-вот станет частью репозитория, без единого слова объяснения; AC14 и раздел «Скоуп» указывают на два документа, которых физически не существует с 27.09 (#679). Оба — находки о точности и исполнимости ТЗ, а не о скоупе или ценности задачи: редактор, бэкенд, визуальная механика и план автотестов по существу не меняются.
High: 0 · Medium: 2 (обе в скоупе) · Low: 0.
Вердикт: жёлтый.
Материал раунда
- Ветка:
dev, коммит8a3bf71ef19e— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
a76aefce86b8d8f7f8fff9dc26aff23eda74148bgit log --all --format='%H %T' | grep a76aefce86b8 - Тело issue:
126b0769cbcb4646a96257374bbb4e3a0ad5c64cf6db577a0360e76833e115b4 - Вердикт конвейера:
yellow· High 0 · маршрутfix