15 KiB
SPEC-REVIEW-337-r1
- Issue: https://github.com/Matysh/houseplan-card/issues/337
- ТЗ:
docs/specs/337-lazy-editor-chunk.md, commit6e7ab6b7(ветка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, ревьюер снимает их с записью (правка необязательна, вносить можно по желанию автора в этом же цикле без отдельного возврата):
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. Если авторы решат вынести и его — не помешает, но не является требованием этого ТЗ.- Число/размер editor-чанков не ограничено. Формально ТЗ можно закрыть набором очень мелких чанков, что било бы по числу HTTP-запросов при первом входе в редактор, хотя раздел «Риски» уже фиксирует намерение «переносить законченными typed slices». Снято: нет продуктового контракта на задержку входа в редактор кроме «не выглядит зависшим» (150 ms порог, §15), а именно этим и ограничен риск.
- Имя
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-находки
сняты с записью выше. Статус — «Готово к разработке».