Files
houseplan-card/docs/reviews/SPEC-REVIEW-337-r1.md
T
2026-08-28 05:40:28 +00:00

15 KiB

SPEC-REVIEW-337-r1

  • Issue: https://github.com/Matysh/houseplan-card/issues/337
  • ТЗ: docs/specs/337-lazy-editor-chunk.md, commit 6e7ab6b7 (ветка issue/337-lazy-editor-chunk, HEAD detached)
  • Трек: полный (обоснование в аналитике: производительность + несколько поверхностей/public asset contract — критерий §5 назван, small корректно отклонён)
  • Этап: spec-review, заход r1, блокирующих циклов израсходовано 0/4
  • Вердикт: зелёный

Скоуп

Задача переносит View/editor границу frontend в реальную модульную границу (src/editors/runtime/), делает multi-asset build/раздачу/CI/HACS-контракт и безопасно минифицирует статические CSS-литералы, чтобы initial View graph уложился в ≤256 000 B gzip. Данные/layout/геометрия/UX/touch policy не меняются, только: (а) до входа в редактор код редакторов не грузится, (б) при редкой ошибке загрузки чанка показывается новое локализованное сообщение, а View остаётся рабочим.

Проверка по docs/SCOPE.md: работа не добавляет функциональность — она инфраструктурно защищает J1/J6 (быстрый рабочий View для kiosk/tablet-персон, которые являются «the product» по SCOPE) и не задевает ни один пункт out-of-scope. Отдельный вопрос владельцу не нужен: видимое поведение не меняется, кроме двух явно описанных добавлений (индикатор ожидания, сообщение об ошибке), и автор прямо заявил в комментарии, что продуктовых вопросов нет — это соответствует действительности, разночтений о персоне/сценарии в ТЗ я не нашёл.

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

Ревью документа на этом этапе не имеет кода для гейтов (typecheck/test/build неприменимы — commit 6e7ab6b7 меняет только docs/specs/337-lazy-editor-chunk.md). Вместо этого каждое фактическое утверждение ТЗ, которое можно спутать с непроверенной догадкой, сверено с текущим репозиторием на HEAD:

Утверждение ТЗ Проверка Результат
dist/houseplan-card.js 1 353 147 B raw / 378 335 B gzip, src/houseplan-card.ts ≈1052 KiB, View+3 редактора в одном классе wc -c src/houseplan-card.ts → 1 071 305 B (22 809 строк) согласуется с заявленным порядком величины
custom_components/houseplan/__init__.py раздаёт один точный файл StaticPathConfig(FRONTEND_URL, ...) без auth прочитан файл целиком подтверждено; новый asset-route не вводит новый класс уязвимости — паритет с текущим
GUI config editor (houseplan-card-editor) сейчас eager grep "import './editor'" в houseplan-card.ts:190 — статический импорт подтверждено, AC11 закрывает реальный источник веса
Существующий mode-transition CSS-класс переиспользуется под loading surface найден в plan.styles.ts/houseplan-card.ts, уже используется как de-emphasis coordinate правдоподобно, а конкретная реализация прямо отнесена к §18 «принято предположительно»
«Старый браузер, способный исполнять текущий ESM bundle, способен исполнять native dynamic import» (§12) tsconfig.json target es2021, без даунлевелинга; в коде 811 использований ?. и 110 ?? — уже требуется ES2020+ движок верно: минимальный движок, способный распарсить нынешний бандл, уже новее движков без import() (Chrome 63/FF 67/Safari 11.1) — вычислено, не принято на веру
Ручная установка сегодня — это копирование папки custom_components/houseplan, а не одного JS (README.md:109-112, USER-GUIDE.ru.md:97-102) прочитаны оба файла подтверждено — multi-asset дерево не ломает существующий документированный manual-install путь; отдельный top-level houseplan-card.js GitHub-asset никогда не был этим путём
docs/specs/README.md/PROCESS.md §7.1 обязательные разделы построчная сверка ТЗ §1–§18 все присутствуют по содержанию (см. ниже)
Трейлеры коммита 6e7ab6b7 git log -1 --format=%B Issue: #337 / User-Visible: no, корректно — ТЗ не является пользовательским изменением
#34 (направление декомпозиции, на которое ссылается §7.1) gh issue view 34 #34 сам в S3-spec, ещё не утверждён; его текущий целевой tree (editors/plan/, editors/devices/, editors/render/, …) и «безопасный порядок» (render-слои → диалоги → контроллеры, маленькими слайсами) не совпадают дословно с editors/runtime/ из #337

Дополнительно сверены обязательные разделы ТЗ (PROCESS.md §7.1): сценарий (§1) · что человек видит (§2) · проблема (§3) · скоуп/не-скоуп (§4–§5) · контракт поведения и UX (§6) · архитектурный контракт (§7) · модель данных и миграция (§12) · i18n (§11) · AC1…AC13 с доказательством (§13) · план автотестов (§14) · риски (§15) · откат (§16) · release-артефакты (§17) · блок «принято предположительно» (§18). Все присутствуют по существу, не только по названию.

Находки

Ничего в статусе High или Medium-в-скоупе, требующего возврата автору. Три наблюдения Low, ревьюер снимает их с записью (правка необязательна, вносить можно по желанию автора в этом же цикле без отдельного возврата):

  1. houseplan-space-card не упомянута в границе runtime. У неё есть собственный GUI config editor (src/space-editor.ts, статически импортированный в space-card.ts:39, 93 строки/3.3 KB raw). ТЗ §7.1/§6.2.6 описывает границу и AC11 только для houseplan-card. Снято: вклад в gzip пренебрежимо мал (на два порядка меньше бюджета), «Обе карточки в одном файле» и обе регистрируются надёжно — п.6.1.1 это покрывает; не наблюдается риска для AC1/AC2. Если авторы решат вынести и его — не помешает, но не является требованием этого ТЗ.
  2. Число/размер editor-чанков не ограничено. Формально ТЗ можно закрыть набором очень мелких чанков, что било бы по числу HTTP-запросов при первом входе в редактор, хотя раздел «Риски» уже фиксирует намерение «переносить законченными typed slices». Снято: нет продуктового контракта на задержку входа в редактор кроме «не выглядит зависшим» (150 ms порог, §15), а именно этим и ограничен риск.
  3. Имя src/editors/runtime/ разойдётся с целевым деревом #34 (editors/plan/, editors/devices/, editors/decor/, render/, dialogs/ — сам #34 ещё в S3-spec, не утверждён). Это два разных среза: #34 — про читаемость и единственный источник состояния, #337 — про то, что статически не импортируется в entry; частичное совпадение целей не значит, что нужно ждать #34. Снято: §18 прямо относит имена внутренних модулей и форму typed host port к «принято предположительно, можно менять свободно» — реальной привязки к продукту нет, а сведение выполнимости и проверяемости ТЗ не страдает.

Ни одна из трёх не задевает выполнимость или проверяемость ни одного AC1…AC13, поэтому они не поднимаются выше Low и не создают жёлтый вердикт.

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

  • Числовой бюджет непротиворечив: «250 KiB» (§4.2) и «256 000 B» (issue, AC1/§13) — один и тот же порог (250×1024=256000), никакого двойного источника значения нет.
  • Каждый AC1…AC13 имеет явный, разный и проверяемый способ доказательства (unit/manifest-тест/Playwright-smoke/backend-тест/golden/статический гейт); ни один не сформулирован как «проверено ревьюером на глаз».
  • Не-цели (§5) корректно исключают геометрию, config/layout, polyclip-ts, lazy i18n, backend API/SVG-вычисления и automatic idle-prefetch — согласуется с docs/SCOPE.md (никакой новый функционал сверх заявленной работы) и не противоречит docs/CONFIG-COMPATIBILITY.md (миграции нет, контракт не сформулирован — не нужен, раз stored data не меняется). docs/WALL-THICKNESS.md/CANVAS.md не затронуты (геометрия explicitly вне скоупа) — глубокая сверка с ними не требовалась.
  • §6.4 (failure/retry/fingerprint) и §10 (fingerprint/cache) описывают ровно одну попытку retry, запрет auto-hard-reload и явную обработку mismatch — внутренне непротиворечиво и без недосказанных веток.
  • Формулировки пользовательских сообщений (§6.2.3, §6.4.2) — новый текст, а не изобретённая замена существующей терминологии USER-GUIDE.ru.md: там нет готовой фразы под этот сценарий (grep пуст), так что это не нарушение правила «UI не говорит на языке разработчика».
  • Блок «принято предположительно» (§18) корректно отделяет технические решения (имена модулей, формат manifest, реализация delayed-surface, механизм инвалидации manifest, gzip-параметры сборки, разбиение на коммиты) от того, что зафиксировано как продуктовое решение и менять нельзя (URL ресурса, отсутствие auto-reload, сохранение рабочего View при ошибке, отсутствие prefetch) — ровно то разделение, которого требует PROCESS.md §7.1.
  • Трек и метка (S4-spec-review, полный трек) корректны для задачи со сложностью 9/10 и влиянием на public asset contract.

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

  • Гейты npx tsc --noEmit / npm test / npm run build / bundle:sync / check-docs.mjs / инварианты геометрии — не запускал: на этом этапе нет продуктового кода, диапазон коммита r1 — один файл в docs/specs/. Они становятся обязательными на этапе код-ревью (§2.7), когда появится реализация.
  • Достижимость бюджета ≤256 000 B самой декомпозицией — это инженерный риск, который ТЗ само называет негарантированным («если модульная декомпозиция не доводит граф до бюджета, задача не считается выполненной») и оставляет измеримым на этапе реализации; ревью ТЗ не может предсказать фактический результат code-splitting, только то, что критерий сформулирован проверяемо.
  • Полное содержание docs/ARCHITECTURE.md, docs/DEVELOPMENT.md, docs/TOUCH-SUPPORT.md не перечитывалось построчно — сверены только фрагменты, релевantные конкретным утверждениям ТЗ (раздел «Как проверялось»); геометрия/touch/config не в скоупе задачи, поэтому глубокого разбора WALL-THICKNESS.md/CANVAS.md/CONFIG-COMPATIBILITY.md не требовалось.

Итог

ТЗ выполнимо и проверяемо, разделы полны, продуктовых вопросов владельцу нет и не появилось при ревью, скоуп соответствует docs/SCOPE.md. Три Low-находки сняты с записью выше. Статус — «Готово к разработке».