Files
houseplan-card/docs/reviews/SPEC-REVIEW-580-r2.md
T
2026-09-15 09:05:58 +03:00

17 KiB
Raw Blame History

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