From 2b98a70fa9b0dfb4277493dccb555d1c59f9f7d7 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 05:06:51 +0000 Subject: [PATCH] docs: review document for #580 Issue: #580 User-Visible: no --- docs/reviews/SPEC-REVIEW-580-r2.md | 199 +++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-580-r2.md diff --git a/docs/reviews/SPEC-REVIEW-580-r2.md b/docs/reviews/SPEC-REVIEW-580-r2.md new file mode 100644 index 00000000..0467ccf7 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-580-r2.md @@ -0,0 +1,199 @@ +# SPEC-REVIEW-580-r2 + +**Issue:** #580 «Солнечные лучи от внешних углов проходят сквозь толстые стены» +**Этап:** ТЗ на ревью (`S4-spec-review`), трек — полный продуктовый +**Заход:** r2 · блокирующих циклов израсходовано 1/4 (r1 был жёлтым и списал +1 цикл; зелёный вердикт цикл не образует — §4) +**Материал:** тело issue #580, раздел `## ТЗ`, на момент комментария автора +«Исправления по SPEC-REVIEW-580-r1 внесены в тело ТЗ» (id `5674992378`, +2026-09-15T05:00:25Z; `updated_at` issue = 05:00:27Z — тело правилось прямо +перед этим комментарием). Продуктового кода по-прежнему нет: ветка +`issue/580-outer-sun-wall-occlusion` не продвинулась дальше +`d37b2c9f8a4369082fec6970117cc97dd1e303c7` (сверено: `git log` ветки и +`git diff d37b2c9f..origin/issue/580-outer-sun-wall-occlusion --stat` — +пусто, только коммит с документом ревью попал в общую историю). + +## Дельта раунда + +Единственный источник изменений — комментарий автора `5674992378`, который +объявляет пять правок по находке M1 из SPEC-REVIEW-580-r1 плюс правку L1. +Сверка по телу issue (текущий полный текст получен `gh issue view --json +body`) подтверждает все пять и шестую: + +1. добавлен раздел `### Пользовательский сценарий`; +2. добавлен раздел `### Что человек увидит до и после` (буллеты «До»/«После» + без терминов реализации типа `sun_ray_origin`); +3. добавлен раздел `### Влияние и риски` с явными строками `Touch:`, + `Производительность:`, `i18n: нет`, `Основные риски:`; +4. риски из комментария «Аналитика» перенесены в тело ТЗ (та же + формулировка, детализированная под конкретные AC); +5. п.4 контракта переписан без хеджирующего «может» (было: «свет внутри + доступной части туннеля может оставаться видимым»; стало: «В туннеле + остаётся только участок света от внешней плоскости до места, где его + полностью перекрывает откос»); +6. AC2 расширен явным условием: «...туннельная часть заканчивается на + блокирующем откосе и остаётся непустой, если луч успевает войти во + внешний пролёт» — снимает саму неопределённость, а не просто убирает + слово. + +Остальной текст ТЗ (диагноз «Проблема», контракт п.1–3/5–6, «Технический +подход», AC1/AC3–AC7, «Затронутые файлы», «Совместимость и откат», +«Принятые предположения») по утверждению автора не менялся; ниже это +принято как унаследованное из r1, см. раздел «Унаследовано из r1». + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| **M1** (Medium, в скоупе): нет разделов «Сценарий»/«До-после», нет `i18n`, нет влияния на touch и производительность, риски не перенесены в тело ТЗ — DoR §2.5 формально не проходится | Все пять пунктов добавлены отдельными разделами/строками в тело `## ТЗ` | `### Пользовательский сценарий`; `### Что человек увидит до и после`; `### Влияние и риски` → `Touch:`, `Производительность:`, `i18n: нет`, `Основные риски:` (текст issue, текущая версия) | +| **L1** (Low, на усмотрение автора): контракт п.4 использует «может» про свет в туннеле на предельно косом угле, AC это не проверяет | Хедж убран, контракт п.4 переформулирован как безусловное правило с явной оговоркой про вход луча во внешний пролёт; AC2 добавил проверку этого же условия | Контракт, п.4 (текст «В туннеле остаётся только участок…») + `AC2`, фраза «...остаётся непустой, если луч успевает войти во внешний пролёт» | + +Обе находки закрыты по существу, не косметически: M1 была про отсутствие +текста DoR-пунктов — текст добавлен и отвечает по существу (а не заглушками +вроде «TBD»); L1 была про модальность контракта — модальность убрана, а не +просто переформулирована в другую хедж-форму. + +## Унаследовано из r1 + +Без повторной проверки в этом раунде принято всё, чего дельта не касалась — +см. SPEC-REVIEW-580-r1.md (документ этого репозитория, коммит `a18e41e2`), +раздел «Что проверено и корректно», на состоянии тела issue до правки +(комментарий `IC_kwDOTOcLQM8AAAABUkBntg` / `5674919862`, 2026-09-15T04:52:39Z) +и коде на `d37b2c9f8a4369082fec6970117cc97dd1e303c7`: + +- диагноз бага соответствует коду `computeSunRays()` (`src/sun.ts:402-459`) — + комнатная и туннельная часть луча в режиме `outer` строятся двумя + независимыми клипами одного `quad`, без пересечения друг с другом; +- технический подход реализуем на существующих входных данных + (`wallDepthByOpening`, координаты/угол/длина окна, контур комнаты) без + новой геометрии стен; +- регрессионный периметр (контракт п.3, п.5) верно называет существующие + тесты `#577` (`test/sun.test.mjs:468,495`) и `DEV-EB173-01` + (`test/sun.test.mjs:509`), которые нельзя сломать; +- `docs/USER-GUIDE.ru.md` не нуждается в правке — таблица «Поведение» уже + описывает целевое, исправленное поведение режима «внешние углы»; +- AC1, AC3–AC7 однозначны, каждому назван способ доказательства + (unit ×2, browser smoke, golden, гейты, review) — эти AC дельта не + трогала, повторно не разбирались; +- «Принятые предположения» оформлены по правилу §7.1 явным блоком, оба + технические, эскалация владельцу не нужна — текст не менялся; +- не-скоуп (взаимное затенение стен/крыльев) назван явно и совпадает с + зафиксированным лимитом `docs/SUN.md`; +- track-решение «полный продуктовый трек» обосновано названным критерием + (сложность/риск выше 3) — раздел не менялся. + +## Как проверялось (по дельте) + +1. Получено текущее тело issue (`gh issue view 580 --json body`) и все + комментарии с их id и временем (`gh api .../issues/580/comments`), чтобы + отделить дельту от унаследованного текста без доступа к истории правок + issue (GitHub API не отдаёт диффы тела issue напрямую — сверка велась по + явным цитатам находок в SPEC-REVIEW-580-r1.md и по перечню правок в + комментарии автора). +2. Построчно сверены пять правок из комментария автора с текущим текстом + ТЗ — все пять присутствуют по существу, не формальными заглушками + (раздел «Дельта раунда» выше). +3. Перечитан `docs/SUN.md`, раздел «The rim — a hairline along the sides» + (строки 315-354), чтобы оценить риск «неверная боковая обводка после + сужения», который автор добавил в «Основные риски». Архитектурно rim + выводится «for free» из уже клипованного полигона луча + (`rayRimEdges()` режет стороны из ALREADY clipped polygons, `rimStops()` + возвращает `rayStops()` по идентичности) — то есть после исправления + геометрии комнатной части rim скорректируется автоматически, без + отдельной правки кода и без отдельного AC. Это подтверждает корректность + контракта п.5 («боковой rim... сохраняют существующий контракт») и + снимает первоначальное опасение, что риск rim остался без покрытия + тестами — он структурно исключён самой архитектурой, а не нуждается в + отдельном AC. +4. Перепроверена логическая непротиворечивость нового текста контракта + п.4 и обновлённого AC2 — противоречий нет, AC2 добавляет ровно ту + оговорку (полный блок луча у самого входа в пролёт), которую общее + правило контракта не проговаривает явно. +5. Сверено, что новый раздел «Влияние и риски» не расширяет и не сужает + скоуп: `Touch: не меняется`, `i18n: нет`, `Производительность:` явно + ограничивает правку одним пересечением полигонов в уже пересчитываемом + пути и запрещает новые циклы по пикселям/кадрам — совпадает с тем, что + уже было верно по коду в r1 (r1 констатировал горячий путь, но не + ограничение сложности; теперь ограничение сформулировано явно самим + автором, а не мной за него). +6. Проверено, что AC1, AC3, AC4–AC7 и остальной контракт (п.1-3,5,6) + текстуально не менялись относительно того, что уже было разобрано и + принято в r1 — заново геометрию не проверял (см. «Унаследовано из r1»). + +Гейты (`tsc`/`test`/`build`/`check-docs`/инварианты/смоки/golden) не +прогонялись: продуктового кода в этом раунде по-прежнему нет (см. +«Материал» выше) — их не над чем гонять, аналогично r1. + +## Находки + +Не найдено. Обе находки r1 (M1, L1) закрыты по существу; дельта нового +Medium/High не вносит. Замечание про rim (см. «Как проверялось», п.3) +не стало находкой: после чтения `docs/SUN.md` выяснилось, что риск +структурно закрыт архитектурой rim (`rayRimEdges()`), а не пробел в ТЗ. + +## Что проверено и корректно + +- M1 закрыта по существу: все пять пунктов DoR §2.5 (сценарий, до/после, + i18n, touch, производительность) и перенос рисков в тело ТЗ присутствуют + как содержательный текст, а не формальные заглушки. +- L1 закрыта по существу: контракт п.4 больше не хеджирует поведение + словом «может», а AC2 явно проверяет обе ветки предельно косого случая + (пустая комнатная часть + непустая/пустая туннельная в зависимости от + входа луча). +- Новый раздел «Влияние и риски» согласован с остальным ТЗ: перечисленные + риски покрываются названными AC (AC1-AC3 — численные вырождения и + сохранение полного пролёта/неизменности `inner`, AC5 — шов на внутренней + плоскости через golden-снимок; риск по боковому rim закрыт архитектурно, + см. выше, а не отдельным AC — это корректно, а не пропуск). +- Дельта не меняет контракт по существу (диагноз, подход, AC1/AC3-AC7), + поэтому наследование выводов r1 обосновано согласованностью текста, а не + просто заявлением автора. +- Track-решение, не-скоуп и ссылка на `docs/USER-GUIDE.ru.md` не требуют + повторной проверки — дельта их не касается. + +## Чего не проверял + +- Не проверял `npx tsc --noEmit` / `npm test` / `npm run build` / + `check-docs` — продуктового кода всё ещё нет, гонять нечего (то же, что в + r1). +- Не прогонял браузерные смоки, golden и инварианты модели — актуальны на + код-ревью, когда появится реализация AC1-AC5. +- Не проверял `python -m pytest tests_backend` — задача не касается + `custom_components/**/*.py`. +- Не выполнял заново геометрический разбор `computeSunRays()` — контракт и + диагноз, к которым он относится, дельта не трогала; разбор унаследован из + r1 (см. выше). + +## Вердикт + +Зелёный: находки r1 (M1, L1) закрыты по существу, новых High/Medium дельта +не вносит. ТЗ отвечает на все обязательные пункты §7.1/DoR §2.5, контракт +однозначен, AC1-AC7 у каждого указан способ доказательства. Готово к +переходу в `S5-ready`. + +## Материал раунда + +- Issue: #580, репозиторий Matysh/houseplan-card. +- Материал ТЗ: тело issue, раздел `## ТЗ`, на момент комментария автора + `5674992378` (2026-09-15T05:00:25Z, «Исправления по SPEC-REVIEW-580-r1 + внесены в тело ТЗ»); `updated_at` issue = 2026-09-15T05:00:27Z. +- Ветка `issue/580-outer-sun-wall-occlusion`, без продуктовых изменений + относительно `d37b2c9f8a4369082fec6970117cc97dd1e303c7` (сверено `git + diff --stat` на момент ревью). +- Заход r2, предыдущий документ — `docs/reviews/SPEC-REVIEW-580-r1.md` + (коммит `a18e41e2`). Раздел «Закрытие раунда r1» и «Унаследовано из r1» + выше. + +--- + + + +## Материал раунда + +- Ветка: `issue/580-outer-sun-wall-occlusion`, коммит `a18e41e20168` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `3bb62e0b2a0f871bcf276f0f130957e7ba048130` + ``` + git log --all --format='%H %T' | grep 3bb62e0b2a0f + ``` +- Тело issue: `558be5cfc33a8fe1f475fbc5a0210392339265c20fad0c22e82858b57c96b848` +- Вердикт конвейера: `green` · High 0