Files
2026-09-30 20:30:04 +00:00

15 KiB
Raw Permalink Blame History

SPEC-REVIEW-718-r1

Issue: #718 · «Луна: видна при любом фоне, а в общих настройках — статус «сейчас была бы видна / не видна (причина)»» · трек ask · заход r1.

Материал: тело issue #718 (раздел ## ТЗ, решения владельца от 30.09), состояние репозитория на 3e38de07b3f6ef955b5c683bbafe962d6373eecd (dev, на момент ревью).

Скоуп ревью

Ревью ТЗ (PROCESS.md §2.4, §7.1): полнота обязательных разделов, однозначность и доказуемость каждого AC, отсутствие догадок, выданных за факт, соответствие терминологии docs/USER-GUIDE.ru.md, принадлежность задачи docs/SCOPE.md. Код не читался как реализация (её ещё нет) — читался как источник фактов, которыми ТЗ оперирует, чтобы проверить, что описанная в «Проблеме» и К1–К10 картина соответствует действительности, а не пересказу по памяти.

Как проверялось

Построчно сверил технические утверждения ТЗ с текущим кодом (не для правки — чтобы убедиться, что «Проблема» и контракт К1–К10 не галлюцинируют):

  • src/moon.ts — moonView, moonShownAt, moonPosition, moonIllumination, константы MOON_ELEVATION_MIN/MOON_MIN_ILLUMINATION, округление k.
  • src/sun.ts — resolveDayCycle, dayCyclePhaseFromSun (ровно 6°/−6°), dayCyclePhaseFromMinutes (08:00–18:00 = день), dayCycleSunOf, sunStateOf, bgModeOf, BG_MODES.
  • src/houseplan-card.ts — _dayCycleState() (null при _effBgMode() !== 'daynight'), _syncDayCycleClock/_dayCycleTick (тикер по dayCycleFingerprint, только при source === 'clock'), _sunGlobal().
  • src/moon-gate.ts — текущий гейт: moonLayer(host, settings, state), отпечаток сборки ENTRY_BUILD_FINGERPRINT, ретрай не чаще 30 с.
  • src/moon-runtime.ts — MOON_CSS (.hp-day-cycle-env{container-type:size}, без filter/will-change/z-index).
  • src/styles/plan.styles.ts, src/space-card.ts — .zoomwrap{z-index:1}, .hp-static-stage > svg{z-index:1}, .devlayer{z-index:2}, .hp-paper-outline-svg{z-index:0}.
  • src/editors/form-kit.ts — toggleRow: caption?: string | TemplateResult, единый captionId в aria-describedby.
  • src/editors/general-form-state.ts, src/houseplan-editor-runtime.ts — generalDraftKey, HouseplanEditorHostPort, _openSettingsDialog.
  • scripts/bundle-manifest.mjs, scripts/bundle-budget.mjs — __HOUSEPLAN_MOON_RETRY_ASSET__ (ровно одно вхождение, moonReplacements !== 1 — ошибка), lazyMoonFiles, существующие проверки пересечения с initialViewFiles (проверки с lazyEditorFiles для lazyMoonFiles пока нет — AC13 просит её завести).
  • test/moon.test.mjs — текущая проверка «static → нет окружения → нет луны» (#661 AC2), которую АС15 просит инвертировать.
  • demo/golden/matrix.mjs — существование сцен day-cycle-night-moon-gibbous- dark, day-cycle-dusk-moon-crescent-south-dark, general-color-popover- desktop-en, settings-help-zoom-200-{en-light,ru-dark}, которые АС8 называет как соседей новых сцен.
  • docs/SUN.md (Moon), docs/USER-GUIDE.ru.md §15 «Луна», docs/CONFIG-COMPATIBILITY.md (Moon) — текущий канон, с которым ТЗ обещает свести правки release-артефактов; сверил дословные фразы («При фоне „Следует за Солнцем"», строка «Пространство с собственным статическим фоном»), которые ТЗ называет для замены — они существуют дословно.
  • Issue #661 (тело) — контракт C1–C9, на который ссылается ТЗ («кроме того, что меняется ниже»); сверил, что К2 («без изменений») и К4/К6 («уточнение») действительно меняют только названное, остальное C1–C9 остаётся как было.

Гейты (tsc, npm test, npm run build) не прогонялись и не требовались: этап — ревью ТЗ (§2.4), не код-ревью; продуктового кода для этой задачи ещё нет, §8-таблица гейтов относится к этапу code. Смоки/golden/мутанты — из плана ТЗ, тоже не запускались по той же причине (нечего запускать).

Находки

Не найдено ни одной находки, для которой не выдержана проверка: все проверяемые технические утверждения ТЗ (константы, имена функций, CSS-правила, z-index, существующие golden-сцены, существующая проверка test/moon.test.mjs, формат toggleRow.caption, требование bundle-manifest.mjs к ровно одному вхождению ретрай-токена) подтвердились чтением кода один в один. Ни одного утверждения о поведении, которого не было бы ни в коде, ни в docs/SUN.md/ docs/USER-GUIDE.ru.md и не помеченного как предположение, не обнаружено.

High: 0. Medium: 0. Low: 0.

Что проверено и корректно

  • Обязательные разделы (§7.1) все на месте: сценарий (персона + поверхность из docs/SCOPE.md), «что человек увидит до/после» без терминов реализации, проблема (со ссылками на код, все подтвердились), скоуп и не-скоуп, контракт поведения К1–К10, UX-тексты, модель данных и миграция, i18n, шесть классов риска (§2.6) — все представлены хотя бы одной строкой, AC1…AC16 с указанием способа доказательства (smoke/golden/unit/ревью кода), план автотестов, затронутые файлы, риски, откат, release-артефакты.
  • DoR (§2.5): i18n-ключи en+ru перечислены дословно (de/fr — на этапе реализации, это разрешено процессом); миграция и compatibility решены со ссылкой на правку docs/CONFIG-COMPATIBILITY.md; влияние на perf/бюджет названо числом (924 Б остатка, цель ≤500 Б); touch — явное «нет» с обоснованием; откат — явный (выключить переключатель либо revert); открытых продуктовых вопросов нет — они закрыты «Решениями владельца 30.09» в начале issue, ссылки на них в тексте ТЗ точные.
  • Технические решения, не наблюдаемые пользователем, корректно вынесены в блок «Принято предположительно» (9 пунктов) вместо того, чтобы быть утверждёнными как факт или эскалированными владельцу — ровно то разделение, которое требует §7.1 («где гвард, именование, механика миграции — решают агенты»). Ни один пункт не выглядит продуктовым вопросом, ушедшим под видом технического.
  • AC9 (таблица unit) — построчно пересчитана вручную против реальной логики dayCyclePhaseFromSun/moonShownAt/Math.round: пороги 6,0° (день), 3°/3 % (граница «показывается» включительно), приоритет причин (нет_дома → день → низко → новолуние, включая нарочную строку «высота −3°, k 0,01» — проверяет именно порядок «low» раньше «new»), зажим min(round,2) для 2,6°/2,6 % — все числа в таблице сходятся с кодом, ни одной внутренней нестыковки не нашёл.
  • К8 «одно число — один источник» зафиксирован верно и проверяем: АС10 требует поточечной эквивалентности статуса и moonView(...).visible на сетке часов/городов/высот; это само по себе защита от двух реализаций одной логики.
  • Release-артефакты называют точные фразы для правки в docs/USER-GUIDE.ru.md («При фоне „Следует за Солнцем"» → «При любом фоне»; строка «Пространство с собственным статическим фоном» → «Луна та же») — обе фразы существуют в файле дословно, терминология не изобретена.
  • Риски (8 штук) покрывают именно те точки, где тонко: бюджет (с планом отступления в moon-gate/moon-runtime), видимое изменение у старых установок (это цель, не баг, названо прямо), контраст на сером фоне (решение владельца принято явно, без вариантов дизайна), нестабильные golden от асинхронной строки (защита — ожидание [data-moon-status]), ложное «изменено» в диалоге (защита — К7 + AC11), лишние рендеры тикера (разбор именно той функции _dayCycleTick, которая сейчас сравнивает полный dayCycleFingerprint, а не фазу — риск реальный, и К5 его закрывает явным «сравнивать только фазу»).

Чего не проверял

  • Не проверял наличие дизайнерского ассета под светлый фон (тёмный контур #2b3138 50 %) — это решение владельца 2, файл assets/moon/houseplan- 1.0.0 не открывал построчно (растровые/векторные данные, не текст ТЗ).
  • Не проверял вручную все 12 строк AC9 через интерпретатор (считал по формулам dayCyclePhaseFromSun/Math.round в уме/на бумаге) — для двух граничных строк (6,0° и −0,4°) можно перепроверить исполнением юнит-теста на реализации, когда она появится; на этапе ТЗ код ещё не существует.
  • Не оценивал, действительно ли фикстуры settings-help-zoom-200-* и general-color-popover-desktop-en физически прокручивают диалог до секции «Солнце и Луна» в текущем golden-харнессе — не нашёл в материале, что именно попадает в кадр этих сцен (вне ТЗ, это деталь существующей golden инфраструктуры, а не предмет этой задачи).
  • Не прогонял и не был обязан прогонять тесты/сборку — на этапе ревью ТЗ кода нет, гейты код-ревью (§8) к этому этапу не относятся.
  • Не запрашивал у владельца ничего — открытых продуктовых вопросов, которые требовали бы его решения, не нашёл: все развилки, которые похожи на продуктовые, уже закрыты «Решениями владельца 30.09» в начале issue, а оставшиеся — технические, для них ТЗ либо даёт явный ответ (К1–К10), либо честно помечает их «принято предположительно» и оставляет мне право оспорить (не оспариваю ни один — обоснования состоятельны, см. выше).

Вердикт

Зелёный. ТЗ проверяемо, внутренне непротиворечиво, каждое AC имеет способ доказательства, технические утверждения о текущем коде подтвердились дословно, продуктовые вопросы закрыты владельцем, технические — обоснованно решены автором с правом реализатора их поменять. Готово к разработке.


Материал раунда

  • Ветка: dev, коммит 3e38de07b3f6 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: cc4d5d8d0d600399659cd3d3b0c28214c66c3f1d
    git log --all --format='%H %T' | grep cc4d5d8d0d60
    
  • Тело issue: 71a4be01f5dd57a0c50deb9ea5df0a86585f54efef75a9f66ba7a87d99ce9059
  • Вердикт конвейера: green · High 0