mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Волна 5 эпика #674, перенос документов ревью (класс C), сделан инструментом: `node scripts/reviews-archive.mjs --through=v1.77.0 --apply`. 965 документов 332 задач разложены по `legacy/reviews/<тег>/` (v1.63.0 … v1.77.0) — 330 задач доказаны трейлерами своей линии, два документа без трейлера (#68, #94, работа до правила трейлеров) — по линии, где их добавили. В `docs/reviews/` остались 154 документа задач с трейлером после v1.77.0 — текущая линия v1.78.0 — и INDEX.md, пересобранный тем же построителем. История не переписана: SHA-якоря «Материала раунда» живы. Счёт раундов (`reviewRounds` по живому каталогу и архиву) совпадает до и после переноса: 694 пары «этап:задача». Строка в `legacy/README.md`. Issue: #682 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
339 lines
30 KiB
Markdown
339 lines
30 KiB
Markdown
# SPEC-REVIEW-146-r1
|
||
|
||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/146
|
||
- **ТЗ под ревью:** `docs/specs/146-four-phase-sun-background.md` (коммит
|
||
`558dae9`, ветка `issue/146-four-phase-sun-background`)
|
||
- **Роль:** ревьюер ТЗ (не автор), этап `S4-spec-review`
|
||
- **Трек:** обычный (не `small`/`trivial`) — сложность/риск 8/10, множество
|
||
поверхностей (full View, kiosk, статическая карточка, defaults, storage
|
||
migration, import/export, i18n, golden/performance), файл ТЗ в
|
||
`docs/specs/` создан корректно.
|
||
- **Цикл:** r1/4
|
||
|
||
## Скоуп ревью
|
||
|
||
Проверялось соответствие ТЗ:
|
||
|
||
- `docs/SCOPE.md` — попадание в Core user jobs (J1), отсутствие расширения
|
||
скоупа за пределы декоративного фона;
|
||
- `PROCESS.md` §2.4, §2.5 (DoR), §7.1 (обязательные разделы), §3/§12
|
||
(запреты, в т.ч. «догадка вместо решения»);
|
||
- `AGENTS.md` — классы файлов, ветка, трейлеры коммита ТЗ;
|
||
- каноническому документу подсистемы `docs/SUN.md` (действующий непрерывный
|
||
`dayPhase()`, компас-гейт, `planDim`, wedge-контракт, которые ТЗ обязано
|
||
либо заменить, либо явно сохранить);
|
||
- `docs/USER-GUIDE.ru.md` — терминология «Следует за солнцем», раздел
|
||
«15. Солнце и фон день/ночь»;
|
||
- `docs/TOUCH-SUPPORT.md` — контракт View/kiosk/editors;
|
||
- `docs/CONFIG-COMPATIBILITY.md` — паттерн «materialize», идемпотентная
|
||
миграция, preview vs apply, same-instance/foreign import;
|
||
- `docs/ARCHITECTURE.md` — существование `#101` (`src/mode-transition.ts`) и
|
||
`#131` (cold-start), на которые ссылается ТЗ;
|
||
- полному тексту issue #146 (тело + 5 комментариев: два уточнения владельца,
|
||
аналитика с Q1–Q3, решение владельца по Q1–Q3, хендофф автора);
|
||
- приложенным к issue файлам (`SPECIFICATION.md`, `interactive-prototype.html`,
|
||
`README.md`) — на предмет того, что численные визуальные токены ТЗ (палитра,
|
||
контур, положение декоративного света) не выдуманы, а прослеживаются к
|
||
реальному источнику, при этом текст issue сохраняет приоритет там, где он
|
||
расходится с вложениями (сам issue это оговаривает явно).
|
||
|
||
## Как проверялось
|
||
|
||
1. Прочитан весь тред issue #146 через `gh issue view --json body,comments`:
|
||
исходное описание, два уточнения владельца («текст issue приоритетен над
|
||
вложениями»; «если высота недоступна — ориентируемся по времени суток»),
|
||
аналитика с тремя батчированными продуктовыми вопросами Q1–Q3 (каждый с
|
||
явным default), решение владельца «принимаю все предложенные defaults»,
|
||
финальный хендофф автора со ссылкой на коммит `558dae9`. Вопросы заданы
|
||
корректно — только продуктовые («как различать рассвет/сумерки», «чем
|
||
управлять положением света», «что делать с существующими планами»), ни
|
||
одного технического вопроса владельцу не эскалировано.
|
||
2. Сверены обязательные разделы ТЗ (§7.1 PROCESS.md) построчно — таблица
|
||
ниже.
|
||
3. Прочитан `docs/SUN.md` целиком: подтверждено, что действующий
|
||
`dayPhase()` — непрерывная интерполяция по `BG_STOPS`, зависящая от
|
||
`north_deg`, с `planDim` (`brightness(.9)` на весь `.zoomwrap` ночью) и
|
||
45-секундным CSS transition. ТЗ §3 корректно описывает это как исходную
|
||
техническую базу для замены (не голословно) и явно требует удаления
|
||
`planDim`-потребителей (§10, §14.1) и снятия compass-гейта именно с фона
|
||
(§4.5, §11.4), сохраняя compass-гейт для оконных лучей (§7.1 отдельно,
|
||
§11.4).
|
||
4. Скачаны и прочитаны все три вложения issue (`SPECIFICATION.md`,
|
||
`interactive-prototype.html`, `README.md`) для проверки, что численные
|
||
визуальные токены ТЗ не изобретены заново:
|
||
- все 14 hex-цветов §9 ТЗ (`#aabdd1`, `#e8c8b7`, `#dce9ef`, `#cbdce3`,
|
||
`#48536c`, `#9a7380`, `#111a27`, `#1f2f3e` и др.) присутствуют дословно
|
||
в CSS `interactive-prototype.html`;
|
||
- все rgba-токены (`horizon`, `sun`, `vignette`, три уровня outline)
|
||
таблиц §9 сверены построчно с `--hp-horizon`, `--hp-sun-color`,
|
||
`--hp-vignette`, `--hp-shadow-core/soft` и `--hp-outline-glow`
|
||
прототипа для каждой из четырёх фаз (`day` — базовый блок,
|
||
`[data-time="dawn"]`, `[data-time="dusk"]`, `[data-time="night"]`) —
|
||
совпадение полное и в цвете, и в привязке near/mid/far к
|
||
core/soft/glow;
|
||
- размер декоративного света `250 CSS px` (§8.3) найден буквально
|
||
(`width: 250px; height: 250px`) в CSS прототипа;
|
||
- константы клок-дуги §8.2 (`8 + progress·84`, `78 − sin(progress·π)·64`,
|
||
диапазон `05:00–21:00`) совпадают дословно с `SPECIFICATION.md` §7.1
|
||
(`sunrise=300`, `sunset=1260`, те же формулы) — не изобретены;
|
||
- переходная длительность `1100 ms` и `cubic-bezier(.22, .61, .36, 1)`
|
||
(§11.1) совпадают дословно с `SPECIFICATION.md` §7;
|
||
- обнаружено, что в CSS прототипа определены (но нигде не применяются)
|
||
переменные `--hp-plan-filter`/`--hp-plan-opacity` с `brightness/
|
||
contrast/saturate/hue-rotate` по фазам — то есть в самом прототипе
|
||
есть мёртвый код, который менял бы план. ТЗ (§10, инвариант
|
||
неизменного плана) корректно **не** переносит это в контракт и прямо
|
||
запрещает ровно такой набор фильтров на дереве плана — соответствует
|
||
тексту issue («сам план не тонируется») и `SPECIFICATION.md` §5/§12,
|
||
а не тому единственному месту прототипа, которое им противоречит.
|
||
5. Прочитан `docs/CONFIG-COMPATIBILITY.md` и `docs/specs/050-config-export-
|
||
import.md`: паттерн «materialize», «same-instance/foreign import»,
|
||
«preview не пишет storage» — не изобретены заново, это термины уже
|
||
существующей подсистемы, ТЗ §12 использует их правильно.
|
||
6. Прочитан `docs/ARCHITECTURE.md:968` (`## View/editor transition
|
||
ownership (#101)`) и `:720` (`#131`, «initial snapshot does not depend on
|
||
live-sync subscriptions») — оба issue, на которые ссылается §11.3/§14.9
|
||
ТЗ, реальны и описывают именно то поведение, которое ТЗ обязывает
|
||
сохранить.
|
||
7. Прочитаны действующие i18n-ключи (`src/i18n/ru.json`, `en.json`):
|
||
`gs.bg_daynight`, `gs.bg_daynight_hint`, `gs.sun_missing`, `gs.north_hint`
|
||
существуют буквально с теми именами, которые ТЗ §13 требует обновить —
|
||
ключи не выдуманы, а текущий текст хинта («Needs the compass below»)
|
||
действительно противоречит новому «работает без компаса» и корректно
|
||
включён в release-артефакты (§18) как подлежащий правке в том же
|
||
коммите.
|
||
8. Прочитан `docs/USER-GUIDE.ru.md` §15 («Солнце и фон день/ночь», строка
|
||
899: «Для солнечных функций нужны `sun.sun` и направление севера»).
|
||
Подтверждено намеренное расхождение с новым контрактом: ТЗ прямо
|
||
требует обновить этот раздел в release-артефактах (§18) — не пропущено.
|
||
9. Проверено наличие тестовой инфраструктуры для заявленных способов
|
||
доказательства: `test/i18n.test.mjs` существует (AC12 реалистичен),
|
||
`demo/smoke_sun*.mjs` (5 файлов) существуют как база для «targeted
|
||
production-bundle smoke» (§16.3), `npm run golden:verify`/`golden:accept
|
||
-- --reviewed` — существующие команды (AGENTS.md, PROCESS.md §8) —
|
||
доказательства AC не ссылаются на несуществующие механизмы.
|
||
10. Пересчитаны границы контракта фазы (§7.2) и fallback (§7.3) на
|
||
непротиворечивость: `(-∞,-6]` night, `(-6,6)` dawn/dusk по `rising`,
|
||
`[6,+∞)` day — полное покрытие без пересечения; `[300,480)` /
|
||
`[480,1080)` / `[1080,1260)` / остальное — то же самое для минут суток.
|
||
Обе шкалы математически корректны и совпадают с §4 (решение владельца).
|
||
11. Найдено единственное реальное расхождение внутри самого ТЗ — см.
|
||
Medium-1 ниже; проверено, что оно не отражено в §21 («принятые
|
||
технические предположения»), то есть не помечено как оспоримое
|
||
предположение.
|
||
12. Проверены трейлеры и class-принадлежность: `git diff --stat
|
||
origin/dev...HEAD` показывает только `docs/specs/146-four-phase-sun-
|
||
background.md` и `docs/specs/README.md` (класс C, ни одного файла
|
||
класса A — продуктовый код не тронут до `S5-ready`, правило №1
|
||
AGENTS.md соблюдено); коммит `558dae9` несёт `Issue: #146` и
|
||
`User-Visible: no` — корректно для документа ТЗ.
|
||
|
||
## Обязательные разделы (§7.1 PROCESS.md)
|
||
|
||
| Раздел | Есть | Комментарий |
|
||
|---|---|---|
|
||
| Сценарий (персона/поверхность/момент) | ✅ | §1 — домашний администратор/kiosk, View и kiosk, ежедневный взгляд на дом |
|
||
| Что человек увидит до/после | ✅ | §2, «До:»/«После:» — см. Low-2 (длина и термины реализации) |
|
||
| Проблема (с подтверждённой причиной) | ✅ | §3, семь пунктов, все сверены с `docs/SUN.md` (см. «Как проверялось» п.3) |
|
||
| Скоуп / не-скоуп | ✅ | §5 / §6, явные границы (без нового mode-токена, без geo/weather API, без editor-контракта) |
|
||
| Контракт поведения | ✅ | §7 (источник/фаза) + §8 (декоративный свет) + §9 (визуал) + §10 (инвариант плана) + §11 (переходы/surfaces) |
|
||
| Модель данных и миграция | ✅ | §12 — schema не расширяется, идемпотентная миграция, import/export матрица |
|
||
| UX, i18n, accessibility, touch | ✅ | §13 — существующие ключи названы поимённо, touch/forced-colors учтены — см. Low-3 |
|
||
| AC1…ACn с доказательством | ✅ | §15, 16 штук, у каждого назван способ доказательства и исполнитель |
|
||
| План автотестов | ✅ | §16, разбит на unit/backend/smoke/golden с конкретными сценариями |
|
||
| Риски | ✅ | §19, таблица вероятность/влияние/мера, 11 строк |
|
||
| Откат | ✅ | §20 — пользовательский (выбрать static) и технический (revert) отдельно |
|
||
| Release-артефакты | ✅ | §18, конкретный список документов и оба changelog в одном `User-Visible: yes` коммите |
|
||
|
||
Все обязательные разделы присутствуют и содержательны. Дополнительно есть
|
||
раздел «Решения владельца» (§4, дословно фиксирует принятые Q1–Q3) и явный
|
||
блок «Принятые технические предположения — можно менять без продуктового
|
||
ревью» (§21, 12 пунктов) — именно то разделение продуктового и технического,
|
||
которого требует PROCESS.md §7.1. Формулировка §21.12 «Открытых продуктовых
|
||
вопросов нет» подтверждается содержанием: все три вопроса из аналитики
|
||
(различение dawn/dusk, источник позиции декоративного света, судьба
|
||
существующих конфигов) закрыты явными owner-решениями до написания этого
|
||
файла.
|
||
|
||
## Находки
|
||
|
||
### Medium-1 — `azimuth` тайно расширяет owner-решение о fallback-триггерах на саму фазу
|
||
|
||
**Файл:** `docs/specs/146-four-phase-sun-background.md:123-134` (§7.1),
|
||
`:422-425` (AC2) против `:64-69` (§4.1-4.2) и `:603-608` (§21.1-21.2)
|
||
|
||
Решение владельца (issue #146, комментарий 2026-08-14T13:28:11Z) и его
|
||
дословный пересказ в §4.1-4.2 ТЗ называют ровно два условия полного
|
||
clock-fallback: «Если elevation или rising отсутствуют/некорректны». Формула
|
||
самой фазы (§7.2) действительно использует только `elevation` и `rising` —
|
||
`azimuth` в ней не участвует вовсе, он нужен исключительно для позиции
|
||
декоративного света (§8.1).
|
||
|
||
Однако §7.1 («Валидный real-sun sample») вводит **третье** условие,
|
||
отсутствующее в owner-тексте: невалидный/нечисловой `azimuth` тоже
|
||
«атомарно» отправляет в clock-fallback **всю** day-cycle — то есть и фазу,
|
||
которую он математически не определяет. AC2 закрепляет это как обязательный
|
||
unit-тест («отсутствие/garbage любого из elevation/azimuth/rising атомарно
|
||
включает clock-fallback»), делая расширение постоянной частью контракта.
|
||
|
||
**Воспроизведение:** `sun.sun` с валидными `elevation=20` и `rising=true`
|
||
(должно быть `day`, если бы `azimuth` не гейтил фазу отдельно), но
|
||
`azimuth=NaN` (например, временный сбой конкретной интеграции, которая
|
||
считает elevation/rising отдельно от azimuth) — по букве §7.1/AC2 card
|
||
покажет фазу **по местным часам браузера**, а не `day`, хотя есть
|
||
корректные реальные данные для однозначного определения фазы. Владелец
|
||
такой случай не разбирал: его ответ на Q1 говорит только о недоступности
|
||
высоты или направления движения.
|
||
|
||
Это ровно тот класс дефекта, о котором предупреждает PROCESS.md §7.1:
|
||
«Догадка, записанная как факт, — худший вид дефекта: она проходит ревью,
|
||
потому что выглядит решением». Расширение не отмечено в §21 как «принятое
|
||
техническое предположение, можно менять свободно» — то есть выдано за
|
||
решённый факт, а не за предположение, которое ревьюер вправе оспорить.
|
||
|
||
На практике реальный `sun.sun` от ядра HA всегда обновляет `azimuth` и
|
||
`elevation` одним циклом (оба поля или есть, или оба недоступны при
|
||
`unavailable`), поэтому вероятность живого расхождения низкая — это и
|
||
удерживает находку на уровне Medium, а не High: она не ломает заявленный
|
||
сценарий и не требует возврата ТЗ на цикл.
|
||
|
||
**Решение ревьюера:** Medium, заведён отдельный issue
|
||
[#147](https://github.com/Matysh/houseplan-card/issues/147) со ссылкой на
|
||
#146, метки `bug`/`P3`/`S1-new`. Не блокирует `S5-ready`; решается либо
|
||
уточнением владельца, либо явным переносом пункта в §21 при реализации.
|
||
|
||
### Low-2 — «что человек увидит» длиннее одной фразы и использует термины реализации
|
||
|
||
**Файл:** `docs/specs/146-four-phase-sun-background.md:30-42` (§2)
|
||
|
||
PROCESS.md §7.1 требует «одной фразой, без терминов реализации». Раздел
|
||
написан четырьмя предложениями и содержит конкретные implementation-термины
|
||
(«1100 ms», «alpha-aware контур», «локальные часы браузера»). По существу
|
||
требование выполнено — читатель понимает, что видно до/после, без
|
||
двусмысленности — но это дальше от буквы правила, чем прецедент в
|
||
`SPEC-REVIEW-141-r1` (тот был просто «два предложения вместо одного», без
|
||
числовых деталей реализации).
|
||
|
||
**Решение ревьюера:** Low, не блокирует. Косметическая правка на усмотрение
|
||
автора при следующей редакции.
|
||
|
||
### Low-3 — нет буквальной touch-editor метки по `docs/TOUCH-SUPPORT.md`
|
||
|
||
**Файл:** `docs/specs/146-four-phase-sun-background.md:369-389` (§13)
|
||
|
||
`docs/TOUCH-SUPPORT.md` требует явную метку `Touch editor: supported` /
|
||
`best effort` / `not exposed` от «новых спецификаций editor-фич». Задача
|
||
#146 editor-фичей не является (editors явно в не-скоупе, §6, и §13 прямо
|
||
говорит «Editor остаётся desktop-first и не получает новых действий») —
|
||
формально требование правила не адресовано этому ТЗ буквально. Тем не менее
|
||
одна строка `Touch editor: not exposed` сняла бы даже формальное сомнение.
|
||
|
||
**Решение ревьюера:** Low, не блокирует. Необязательная косметическая
|
||
правка.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- **Соответствие `docs/SCOPE.md`:** задача закрывает **J1** («показать дом
|
||
одним взглядом» — фон как декоративный временной контекст без искажения
|
||
цветов пола/стен/устройств) и не расширяется на смежные Core user jobs;
|
||
явно не трогает J2/J3/J5/J7 и не создаёт нового публичного mode-токена
|
||
сверх утверждённого `static | daynight` (§6).
|
||
- **Легитимность полного трека:** сложность/риск 8/10, множество
|
||
поверхностей, влияние на миграцию/i18n/perf/touch — критерии `small`/
|
||
`trivial` (§5/§5.1 PROCESS.md) не выполняются ни по одному пункту, полный
|
||
трек и файл в `docs/specs/` выбраны верно.
|
||
- **Продуктовые вопросы закрыты по процессу, без утечки технических
|
||
вопросов владельцу:** Q1 (dawn/dusk внутри одного диапазона высоты), Q2
|
||
(источник позиции декоративного света), Q3 (судьба существующих
|
||
конфигов) — каждый в форме «что неясно · что изменится · default»,
|
||
batched одним комментарием, с явным `blocked`+`S3-spec` до ответа.
|
||
Технических вопросов владельцу не задано ни одного.
|
||
- **Технический диагноз §3 не голословен** — все семь пунктов сверены с
|
||
`docs/SUN.md` и совпадают (см. «Как проверялось» п.3).
|
||
- **Визуальные токены §9 не выдуманы** — построчно прослежены к
|
||
`interactive-prototype.html` (см. «Как проверялось» п.4); опасный
|
||
побочный путь прототипа (`--hp-plan-filter` на плане) правильно
|
||
проигнорирован, а не перенесён в контракт.
|
||
- **Инвариант неизменного плана (§10)** прямо запрещает весь набор
|
||
color-фильтров и overlay на дереве плана и требует удаления
|
||
`dayPhase().planDim` — устраняет главный риск регресса, названный в
|
||
таблице рисков (§19, строка 1).
|
||
- **Совместимость (§12)** корректно использует существующий паттерн
|
||
«materialize» вместо runtime-fallback (`docs/CONFIG-COMPATIBILITY.md`);
|
||
явно разведены три сценария (существующий global без поля → `static`;
|
||
явный `daynight` → новая семантика того же токена; новое пространство в
|
||
старой установке → `daynight`) — ровно то, что запросил владелец в Q3, без
|
||
скрытой пятой ветки.
|
||
- **Import/export (§12.4)** использует существующую терминологию подсистемы
|
||
(`docs/specs/050-config-export-import.md`: preview/apply, same-instance/
|
||
foreign) корректно, не изобретая параллельный механизм.
|
||
- **Архитектурные ссылки на #101/#131 точны** — оба существуют в
|
||
`docs/ARCHITECTURE.md` и описывают именно то поведение (owner transition
|
||
timeline; cold-start без второго рендера), которое ТЗ обязывает сохранить.
|
||
- **i18n (§13, §18)** называет существующие ключи (`gs.bg_daynight`,
|
||
`gs.bg_daynight_hint`, `gs.sun_missing`, `gs.north_hint`) поимённо и
|
||
корректно определяет, что их текущий текст («нужен компас») противоречит
|
||
новому контракту и должен быть обновлён — без добавления третьего
|
||
публичного режима.
|
||
- **Non-scope (§6)** корректно отсекает соседние соблазны: геолокация/
|
||
weather API, ручной phase selector, изменение геометрии/порогов оконных
|
||
лучей, day/night в редакторах, персистентность вычисленной фазы,
|
||
production `?time=` — каждый с обоснованием, почему не эта задача.
|
||
- **AC1–AC16 однозначны и снабжены способом доказательства** из
|
||
допустимого по §2.5 PROCESS.md набора (`unit`/`backend`/`smoke`/`golden`/
|
||
«ревью кода», плюс «backend migration tests» и «pixel regression» как
|
||
уточнённые подвиды `backend`/`golden`); ни один AC не оставляет открытым,
|
||
чем именно он доказывается.
|
||
- **Release-артефакты (§18)** перечисляют конкретные существующие
|
||
документы (`SUN.md`, `USER-GUIDE.ru.md`, `ARCHITECTURE.md`,
|
||
`CONFIG-COMPATIBILITY.md`, `TESTING.md`) и оба changelog в одном
|
||
`User-Visible: yes` коммите — соответствует правилу 11 PROCESS.md; golden
|
||
корректно ограничен `golden:accept -- --reviewed` по полному Linux-
|
||
артефакту (§16.4), perf/golden/smoke верно отнесены к пре-релизному, а не
|
||
implementation-гейту (AC16, §8/§11.4 PROCESS.md).
|
||
- **Откат (§20)** корректно опирается на отсутствие необратимой миграции:
|
||
явный `static` — немедленный пользовательский откат, revert
|
||
implementation-коммита — технический, без потери данных.
|
||
- **Трассируемость:** `docs/specs/README.md:50` обновлён тем же коммитом;
|
||
ветка `issue/146-four-phase-sun-background` и трейлеры (`Issue: #146`,
|
||
`User-Visible: no`) корректны для документа класса C. `git diff --stat
|
||
origin/dev...HEAD` не содержит ни одного файла класса A — продуктовый код
|
||
не тронут до `S5-ready` (правило №1 AGENTS.md).
|
||
|
||
## Чего не проверял
|
||
|
||
- Не проверял реализуемость «одного pure resolver» (§14.1) как конкретной
|
||
структуры данных/API, конкретных имён helper-функций, CSS custom
|
||
properties или способа crossfade (registered custom properties vs два
|
||
bounded layer, §21.5) — по тексту ТЗ это явно свободное техническое
|
||
решение автора кода, не предмет ревью ТЗ.
|
||
- Не запускал автотесты, `golden`, `performance` или browser-смоки — на
|
||
этапе `spec` это не требуется; существование тестовой инфраструктуры
|
||
(`test/i18n.test.mjs`, `demo/smoke_sun*.mjs`, команды `golden:verify`/
|
||
`golden:accept`) проверено чтением файловой системы и `package.json`, а не
|
||
исполнением.
|
||
- Не проверял осуществимость «одного shared fallback ticker» на несколько
|
||
карточек (§21.9) по реальному коду `space-card.ts`/`houseplan-card.ts` —
|
||
это явно помечено в ТЗ как свободное техническое предположение,
|
||
подлежащее доказательству тестами на этапе реализации/код-ревью.
|
||
- Не проверял точность числовых оценок аналитики (7/10 · 4/10 · 8/10 · P1)
|
||
по существу — это поле владельца (PROCESS.md §2.2), уже принято явным
|
||
решением владельца до написания ТЗ.
|
||
- Не проверял детали алгоритма определения «внешней стены» и геометрии
|
||
оконных лучей (`RAY_MIN_COS`, `RAY_FADE_END` и т.д.) — задача explicitly
|
||
не меняет эту геометрию (§6), затронута только независимость фона от
|
||
`north_deg`, что и было предметом проверки.
|
||
- Не проверял корректность реализации `--hp-plan-filter`/`--hp-plan-opacity`
|
||
в самом прототипе как продуктового кода — это чужой одноразовый макет
|
||
(вложение issue), а не часть репозитория; проверено только то, что ТЗ
|
||
не унаследовало этот фрагмент в свой контракт.
|
||
|
||
## Вердикт
|
||
|
||
Зелёный. High: 0, Medium: 1 (заведён отдельным issue
|
||
[#147](https://github.com/Matysh/houseplan-card/issues/147), не блокирует),
|
||
Low: 2 (косметика, не блокируют, оставлены с записью в этом документе). ТЗ
|
||
решает заявленный сценарий J1 полностью, визуальные токены прослежены к
|
||
источнику, а не изобретены, продуктовые вопросы закрыты владельцем по
|
||
процессу без утечки технических вопросов.
|