From 13d8df55541fef9cbbf86d1060c7660a8ce5fa84 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 10:47:04 +0300 Subject: [PATCH] docs: review document for #780 Issue: #780 User-Visible: no --- docs/reviews/INDEX.md | 3 +- docs/reviews/SPEC-REVIEW-780-r2.md | 101 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100755 docs/reviews/SPEC-REVIEW-780-r2.md diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index cdadd92e..1bb6f044 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,12 +1,13 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 284, issue: 141. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 285, issue: 141. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| | бета v1.79.0-beta.2 | [SHIP-REVIEW-v1.79.0-beta.2.md](SHIP-REVIEW-v1.79.0-beta.2.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — | | бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — | | #780 | [SPEC-REVIEW-780-r1.md](SPEC-REVIEW-780-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 5 | · Medium — в редакторе устройств нет «существующего контекстного лотка» и модели выделения; · Medium — поведение бэкенда на висящую ссылку не определено и ломает сохранение «старо…; · Medium — запрет поднимать бюджеты исполним только ленивой загрузкой, а ТЗ её не требует; · Medium — смещение от грани не определено для стен нулевой толщины и смешанных лент; · Medium — AC17 не проверяем: нет порогов; · Low — D назван «диаметром устройства пространства», а такой величины нет | `validation.py` `scripts/bundle-budget.mjs` `types.ts` `houseplan-card.ts` | +| #780 | [SPEC-REVIEW-780-r2.md](SPEC-REVIEW-780-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — | | #775 | [CODE-REVIEW-775-r1.md](CODE-REVIEW-775-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #772 | [CODE-REVIEW-772-r1.md](CODE-REVIEW-772-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #765 | [CODE-REVIEW-765-r1.md](CODE-REVIEW-765-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | завершающий авторский разделитель теряется при повторной записи якорей | `scripts/review-doc-guard.mjs` | diff --git a/docs/reviews/SPEC-REVIEW-780-r2.md b/docs/reviews/SPEC-REVIEW-780-r2.md new file mode 100755 index 00000000..385fe43c --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-780-r2.md @@ -0,0 +1,101 @@ +# SPEC-REVIEW-780-r2 — LED-ленты: рисование, свечение вдоль ленты, управление + +Вердикт: 🟢 **зелёный** · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0 · Low: 0 + +Ревью ручное, по поручению владельца (модель конвейера без лимита; прогон +[36978687659](https://github.com/Matysh/houseplan-card/actions/runs/36978687659) +остановился до вердикта). Ревьюер тот же, что в r1, автором ТЗ не является; +черновика реализации нет. + +## Скоуп и материал + +- Повторный раунд — разбор по дельте (§2.10). Материал r1 — тело с хешем + `f9f67c2c8cbd…` (якорь [SPEC-REVIEW-780-r1](SPEC-REVIEW-780-r1.md)); тело r1 + восстановлено из истории правок issue (`userContentEdits`, правка + 2026-10-02T07:03:10Z) и сверено тем же `issueBodyDigest` — хеш совпал. +- Материал r2 — тело на 2026-10-02T07:29:20Z, хеш `f03a6e1feee8…`, плюс + комментарий автора 07:27:49Z с таблицей исправлений. +- Дельта: `git diff --no-index -U0` тела r1 → r2 — 22 блока, +59/−23 строк. + Все изменения лежат в разделах, которые называли находки r1 (§3, §4.7–4.8, + §5, §6, §9, AC1/3/6/8/12/15/17/18/19, §12, §13.1–13.2, §14, §15). Продуктовые + решения (редактор устройств, преобразование, скрытая форма) не тронуты. +- Дельта локальна: новый контракт не вводится, подсистемы те же. Полный + повторный разбор не требуется; дельту читал целиком, а не по заявлению автора. + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| M1 — нет лотка/выделения в Devices | Новая LED-ветка вторичного лотка на общем `_editorSecondary`, без перехода в Plan/Decor; выделение — состояние сессии; снятие Esc/фон/инструмент/пространство/выход; клик по значку при выделенной ленте снимает выделение и открывает диалог значка; pan/pinch выделение не сбрасывают | §4 п.7–8; AC3 (smoke «выделить → лоток → настройки → закрыть»), AC6 («выделить ленту → кликнуть значок») | +| M2 — висящая ссылка и «то же пространство» | Порядок backend: проверка структуры/лимитов/дублей → нормализация сироты в `marker:null, active:true` с сохранением точек → ссылочная проверка, одной транзакцией с CAS; отклоняются неверный тип, лимит, повторная привязка, **непустой чужой** `space`; пустой `space` существующего маркера получает id пространства формы; привязка пишет `marker.space` явно; счётчики нормализации без id | §5, §9 (два новых пункта), AC1, AC15 («реальный старый writer… удаление маркера active:true/false») | +| M3 — 501 Б запаса | Ленивая граница: начальный граф — только проверка наличия и loader; загрузка при первой отображаемой **активной** ленте; static с `light_pools:false` не тянет линейное поле; без вспышки старого значка; fail-dark и отмена устаревшего import; существующие потолки не поднимаются, новый чанк — свой бюджет «измерение + 10 %, до 1 KiB» | §13.1; AC17 (network smoke без лент и только с `active:false`, неизменённые бюджеты) | +| M4 — смещение не определено | Поучастковое правило `t/2` / 0 / 0 (грань толстого тела / пол / ось нулевой стены); принадлежность грани — `epsilonGeom = 0,001 см`, не экранный магнит; скруглённый переход «грань → пол» со стороны пола; один производный путь для штрихов, hit/focus и 2.5D; излучение не зависит от `t/2` | §3, §6; AC8 (pixel smoke смешанной ленты и двух нулевых стен), AC12 (расстояния от видимого пути) | +| M5 — AC17 без порогов | Профиль `led-strips-v1` на фикстуре `large-house-interaction-v1`; 10×5 и 50×50; таблица потолков для median и p95; recompute = 0 за 100 тиков/шагов; лимиты кэшей 50/50/2500; рост 0 за 20 циклов; heap ≤ 64 MiB; zero-LED контроль относительно base | §13.2; AC17 | +| L1 — `D` | `D = (card.icon_size / 100) × iconUnit(space)`, у `houseplan-space-card` — свой `icon_size` | §3; AC8 (разные `icon_size` основной и static карточек) | +| L2 — docs-снимки и #697 | `docs/images/**` переснимает бот беты; автор передаёт список затронутых кадров | AC18, §14 | +| L3 — «второй клиент» | Backend write → закрытие соединения → новое соединение read; две demo-вкладки прямо исключены как доказательство | AC19, §12 | + +## Проверка новых утверждений дельты по коду + +| Утверждение | Где проверено | Итог | +|---|---|---| +| Потолки 10×5 — действующие абсолютные потолки interaction-профиля | `demo/performance/budgets-large-house-interaction.json`: `firstStableRenderMs` 3400, `spaceSwitchMs` 1500, `stateUpdateMs` 1000, `panZoomMs` 500 | совпадает с таблицей §13.2 | +| Фикстура: 200 устройств, 60 комнат, 100 проёмов | `demo/performance/README.md:4` | верно | +| Контекстный прогон Full performance | run 36905760140: «Полные бенчмарки производительности», `4dd3ce37`, success, 2026-10-01 | существует; числа p95 автор подаёт как контекст базы, не как измерение LED — так и записано | +| Запас начального графа 501 Б | замер r1 (`node scripts/bundle-budget.mjs` на `d0c13bc5`) | процитирован верно и помечен как исходное измерение | +| Бэкенд не теряет неизвестный массив пространства | `validation.py` `SPACE_SCHEMA … extra=vol.ALLOW_EXTRA` (r1) | ветка «если старый writer выкидывает массив» условна и доказывается AC15 | + +## Что проверено и корректно + +- Все 20 AC сохранены; изменённые AC согласованы с разделами, на которые + ссылаются, и у каждого есть способ доказательства, способный покраснеть. +- AC1 и §5/§9 больше не противоречат друг другу: создание с плохой ссылкой + отклоняется, последствие удаления маркера старым клиентом нормализуется. +- Нормализация `space` не переопределяет непустое чужое значение и не ищет по + реестру HA на бэкенде — совместимость старого формата отделена от правки. +- Ленивая граница проверяема сетевым журналом, а не «без необходимости»; + загрузка привязана к **отображаемой активной** ленте, а не к наличию массива. +- Числовые пороги §13.2 помечены как требования, а не как результат — + догадки, записанной как факт, нет. +- §15 честно перечисляет принятые автором по замечаниям r1 технические решения как + изменяемые на код-ревью при сохранении пользовательского контракта. + +## Замечания без находки + +- В §13.2 пороги применяются и к median, и к p95 при 7 образцах: p95 из семи + фактически равен максимуму. Это строже существующих профилей (там `median`) — + осознанный выбор автора для нового тяжёлого сценария, не дефект ТЗ. +- Ветка §9 «если старый writer выкидывает неизвестный массив» сейчас, по коду + r1, не нужна: фронтенд правит конфиг на месте. Условная формулировка и AC15 + доказывают это исполнением — достаточно. + +## Унаследовано из r1 + +Принято без повторной проверки, по [SPEC-REVIEW-780-r1](SPEC-REVIEW-780-r1.md) +(материал `d0c13bc5`, тело `f9f67c2c8cbd…`): сверка с кодом существующих +механизмов света (`glow-scene.ts`, `logic.ts`, `docs/LIGHT.md`), полей маркера, +`light_pools`/`live_states`, position-only истории Devices, каталога «На плане», +remap импорта и projection «Только план», полнота обязательных разделов §7.1 и +отсутствие открытых продуктовых вопросов. Дельта r2 этих разделов не меняет. + +## Чего не проверял + +- Архив дизайнера и Figma — как и в r1: соответствие макету докажет AC8 + парными кадрами на код-ревью. +- Исполнимость конкретных потолков 50×50 — это требование до кода; проверит + профиль `led-strips-v1` на код-ревью. +- Код, тесты, смоки и golden не запускались: реализации нет. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `9e1a2f4a0777` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `1188eedbdff29a9020c562dacd62c8a326e36c84` + ``` + git log --all --format='%H %T' | grep 1188eedbdff2 + ``` +- Тело issue: `f03a6e1feee86651814cded98be897addb777c833bac6966d5bc33c4ba662b34` +- Вердикт конвейера: `green` · High 0 · маршрут `fix`