mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
13 KiB
13 KiB
SPEC-REVIEW-32-r1
- Issue: https://github.com/Matysh/houseplan-card/issues/32
- Этап: ревью ТЗ (PROCESS.md §2.4), заход r1
- Материал:
docs/specs/032-unified-danger-confirmation.mdна SHA206bcd1a(коммит «docs: refresh danger confirmation spec»), тело issue #32, все комментарии (актуализации 2026-08-14, 2026-08-30, occupation-комментарий, комментарий о готовности ТЗ на SHA206bcd1a) - Трек: полный (владелец снял
small2026-08-30: не проходит критерии «одна поверхность» и «нет нового UX-контракта», задета touch) - Бюджет: заход r1, блокирующих циклов израсходовано 0 из 4 (лимит 4, полный трек)
Скоуп проверки
ТЗ описывает замену восьми прямых browser confirm() единым
hp-confirm-компонентом поверх hp-dialog с promise-based host API,
race-safety-контрактом (revalidation после await), touch/i18n-требованиями и
границами со специализированными диалогами (комната, стена с проёмами, декор,
backup/optimize, Tap confirmation).
Проверялось:
docs/SCOPE.md— соответствие J3/J6 и lock-инварианту («единственная разрешённая поверхность актуации замка — кнопка в карточке проёма, которая дополнительно подтверждает перед unlock»);AGENTS.md,PROCESS.md§2.4/§2.5/§7.1/§4 — обязательные разделы ТЗ, критерии DoR, бюджет циклов;docs/ARCHITECTURE.md§ One modal contract / One transient-surface contract;docs/TOUCH-SUPPORT.md§ Safety floor;- фактический код: все 8 call sites
confirm(вsrc/**, существующие специализированные диалоги (_roomDeleteDialog,_partitionDeleteDialog,confirm.erase_decor, backup/optimize),src/hp-dialog.ts(focus session, autofocus, Escape),src/houseplan-editor-runtime.ts::_deleteSpace(blocker-проверка перед confirm); - два спеки-precedента (
337-lazy-editor-chunk.md,348-german-localization.md) как калибровка того, что в этом репозитории считается «затронутые файлы» и «влияние на производительность» в ТЗ сопоставимого масштаба.
Находки
Medium (в скоупе задачи — чинится в этой же правке ТЗ)
M1. DoR-пункт «влияние на производительность и бюджеты названо» не закрыт, хотя задача добавляет новый eager-код.
- Файл:
docs/specs/032-unified-danger-confirmation.md - Строка: §5.2 (владение состоянием) и §10 (тестовый план)
- Суть: §5.2 явно решает архитектурный вопрос — «Controller находится в eager
root, поэтому onboarding не тянет editor chunk, а View unlock не загружает
его». Это осознанное добавление нового кода (
hp-confirm.ts+ controller + разметка для всех 6 сценариев) в eager root graph, который в этом проекте является бюджетируемой величиной:AGENTS.mdназываетnpm run run bundle:budget # initial View graph <= 256000 B gzip (#337)в одном ряду сbundle:syncкак обязательный после-сборочный гейт, и прецедентныйdocs/specs/337-lazy-editor-chunk.mdтрактует именно этот initial-view-бюджет как central product constraint с отдельным разделом и AC. Раздел 10 текущего ТЗ (обязательные команды перед S7) перечисляетbundle:sync, но неbundle:budget; ни один AC (§9) не привязан к размеру eager-бандла. - Воспроизведение:
npx tsc --noEmit/npm testэтого не поймают —bundle-budget.mjsработает только по manifest послеnpm run build, и если его не прогнать явно, регресс initial View graph (пусть и небольшой) останется незамеченным до пре-релизного гейта, где чинить дороже, чем сейчас дописать одну строку в тестовый план. - Почему это Medium, а не Low: DoR (PROCESS.md §2.5) прямо требует «влияние на
производительность и бюджеты названо (или явно «нет»)» как условие входа в
S5-ready; сейчас оно не названо ни явно, ни как «нет» — и «нет» здесь было бы неверным утверждением, раз §5.2 сознательно добавляет код в eager graph. Фикс дешёвый: добавить предложение с ожидаемым порядком величины прироста (или явную оценку «в пределах текущего headroom») и добавитьnpm run bundle:budgetв список команд §10 рядом сbundle:sync. - Находка в скоупе issue #32 (сам ТЗ), чинится в этой же правке ТЗ — не отдельный issue (owner's decision 2026-08-19, #202).
Что проверено и корректно
- Полнота охвата call sites. Таблица §4.1 называет ровно 8 сценариев;
rg 'confirm\('поsrc/**даёт ровно те же 8 строк вhouseplan-card.ts,houseplan-editor-runtime.ts,houseplan-onboarding-runtime.ts— расхождений нет. - Границы со специализированными диалогами не выдуманы. Проверено чтением
кода:
_roomDeleteDialog(houseplan-editor-runtime.ts:11599-11618) — ужеhp-dialogс двумя вариантами (keep/with walls);_partitionDeleteDialog(:11564-11587) — ужеhp-dialogсо списком проёмов;confirm.erase_decor(:5539) — уже кастомныйhp-dialog; backup/import/optimize — многошаговые диалоги с собственными подтверждениями (backup.confirm_detach,backup.replace_warning). Исключение этих четырёх групп из scope (§4.2) соответствует факту, а не догадке. - Claim о существующем focus/autofocus/Escape-контракте hp-dialog не
выдуман.
src/hp-dialog.tsдействительно реализует focus session, scoped к shadow root,[autofocus]-резолюцию и обработкуEscape(строки 237-396) — §6.1 ТЗ корректно ссылается на наследуемое поведение, а не придумывает новое. - Race-safety claim по пространству проверен по коду.
_deleteSpace(houseplan-editor-runtime.ts:8758-8784) действительно выполняет dependency/blocker-проверку доconfirm()— ровно то, что §6.3 таблицы утверждает («существующая blocker-проверка остаётся раньше confirm»). - Lock-инвариант SCOPE.md не нарушается и не переопределяется. §4.2 явно оставляет закрытие замка без подтверждения (безопасное действие) и не трогает единственную разрешённую поверхность актуации; AC-9 отдельно требует, чтобы unlock не вызывался после cancel/stale state.
- Обязательные разделы §7.1 присутствуют: сценарий и персона (§1), «до/после» одной фразой без терминов реализации (§2), проблема и цель (§3), scope/не-scope (§4), контракт поведения и API (§5, §7), UX (§6), данные и миграция (§8 — явно «миграция отсутствует»), AC1-12 с доказательством (§9), план автотестов (§10), риски (§11), откат (§12), release-артефакты (§13).
- Явных догадок, выданных за факт, не найдено. Единственное место, где ТЗ
сознательно оставляет свободу выбора — §6.1 «action использует warning/on
акцент» для unlock-кнопки — не выдаёт решение за факт, а явно формулирует
как одно из двух допустимых значений; в проекте нет отдельного
.btn.warningкласса, только warning-баннер, так что оба варианта («on»-акцент или новый warning-акцент) реалистичны и не противоречат существующим стилям. Отношу это к техническому допущению (§14 ТЗ его не называет явно, но по духу оно туда подходит) — не блокирую, ревьюер кода вправе потребовать явного выбора при коде. - Открытых продуктовых вопросов нет — комментарий владельца от 2026-08-30 подтверждает, что контракт достаточно определён; ревьюер не находит продуктового вопроса, который стоило бы вынести отдельно (единственный недостающий пункт, M1, технический и не требует решения владельца).
- Ссылки issue ↔ ТЗ на месте в обоих направлениях (тело issue → файл ТЗ;
docs/specs/README.md:39→ issue).
Чего не проверял
- Реализацию — её нет, стадия
S4-spec-review, код не писался. - Точный список i18n-ключей (en/ru/de/fr) — ТЗ описывает контент body/title по
сценариям (§6.3), но не называет конкретные строковые ключи. Признано
приемлемым для этой стадии: AC-11 требует машинной проверки паритета через
test/i18n.test.mjs, а конкретные имена ключей — техническая деталь (PROCESS.md §7.1: «именование» решают агенты сами), не продуктовый вопрос. Не поднимаю до Medium. - Golden/perf профили не запускал — на этой стадии нет кода для прогона;
npm run typecheck/npm test/npm run buildне прогонялись, так как ревью ТЗ не гейтится кодовыми командами (правки затрагивают толькоdocs/specs/032-*.md, класс C). - Не сверял ТЗ с
docs/CONFIG-COMPATIBILITY.mdпострочно — §8 ТЗ утверждает «persisted schema не меняется, миграция отсутствует», что для чисто presentation-контракта (без изменения config/layout) выглядит правдоподобно и не противоречит ничему найденному в CONFIG-COMPATIBILITY.md; не стал открывать весь документ ради этой проверки, так как diff ТЗ прямо утверждает «вне scope: формат config/layout».
Вердикт
Единственная находка (M1) — Medium, строго в скоупе этого же ТЗ, чинится
дополнением двух мест в тексте (не код, не отдельный issue). High-находок нет.
Итог: жёлтый, автор ТЗ правит §5.2/§10, повторный заход разбирается по
дельте (PROCESS.md §2.10) относительно этого документа и SHA 206bcd1a.