Files
houseplan-card/docs/reviews/SPEC-REVIEW-360-r2.md
T
2026-08-29 08:14:17 +00:00

124 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPEC-REVIEW-360-r2
Issue: #360 · этап: spec (S4-spec-review) · трек: `small` (лёгкий) · заход: r2 ·
блокирующих циклов израсходовано: 1 из 2 (лимит лёгкого трека, §4 — r1 был
жёлтым и потратил цикл, зелёный r1 бюджет бы не тратил, но r1 был жёлтым)
Ревьюер: Claude (роль «ревьюер ТЗ»), отдельная сессия от r1 и от автора.
ТЗ по-прежнему живёт в теле issue #360 (revision 2), файл `docs/specs/` не
создаётся — верно для `small`. Кода нет: issue в `S4-spec-review`, Rule #1 не
разрешает трогать `src/**` раньше `S5-ready`, и на `dev` (HEAD `6ce42b33`)
изменений класса A по #360 нет.
## Разбор по дельте (PROCESS.md §2.10)
Второй заход — разбор ограничен дельтой revision 1 → revision 2, а не ТЗ
целиком. Дельта локальна: ни ребейза, ни смены контракта поведения, ни новой
подсистемы, объём дельты (два добавленных предложения) несопоставимо меньше
исходной задачи. Полный повторный разбор не требуется.
**Как найдена дельта.** Тело issue не версionируется в git, поэтому вместо
`git diff <SHA>..HEAD` использован эквивалент для spec-этапа: GitHub
`userContentEdits` (GraphQL) с историей правок тела issue. Ревизия 1 (та, что
читал r1) — снимок тела issue непосредственно перед правкой в 08:00:23Z, без
слов «Touch editor» и без `_decorSaveShape`; это дословно совпадает с тем, что
процитировано в `docs/reviews/SPEC-REVIEW-360-r1.md`. Текущее тело (revision 2,
правка в 08:08:24Z) сверено с этим снимком построчным diff.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **M1** — не названа обязательная формула туча из `docs/TOUCH-SUPPORT.md` («New editor feature specifications... must state one of: `Touch editor: supported` / `best effort / intentionally degraded` / `not exposed`») | Пункт 8 контракта поведения дополнен буквальной формулой | Тело issue, п.8: «**Touch editor: best effort / intentionally degraded.** Background editor сохраняет действующий desktop-first контракт; на touch View/kiosk нет изменений и регрессий.» — точное совпадение одного из трёх канонических вариантов `docs/TOUCH-SUPPORT.md:165-167` |
| **M2** — не описано, что сохранение properties-диалога существующего line/rect/ellipse/furniture перезаписывает тот же `_decorStyle`, который задача делает постоянно видимым | Новый п.9 контракта плюс расширение AC5 и шага 4 плана тестов | Тело issue, п.9: «Сохранение properties-диалога уже существующего line/rect/ellipse/furniture сохраняет текущую семантику `_decorSaveShape`: его `color`/`opacity` становятся новым `_decorStyle`... Это не ретроактивная перекраска других объектов и не новая побочная связь.»; AC5 добавлена фраза «сохранение нового цвета/opacity в properties-диалоге существующего line/rect/ellipse/furniture обновляет main picker по текущему контракту `_decorSaveShape`, и следующий объект получает последнее значение»; план тестов, шаг 4, добавлено «Затем сохранить новый цвет/opacity через properties-dialog уже существующих line, rect, ellipse и furniture и проверить main picker и стиль следующего объекта» |
Обе находки закрыты добавлением текста без изменения архитектуры контракта или
номеров AC — ровно так, как r1 и предписывал. Других правок в теле issue между
ревизиями 1 и 2 нет: построчный diff (см. ниже) вне пп. 8, 9, AC5 и шага 4
плана тестов состоит только из переноса строк markdown (тот же текст, другая
раскладка по ширине), без содержательных изменений.
## Проверка дельты по коду (не только по формулировке)
Обе добавленные фразы — не пересказ, а утверждения о поведении текущего кода,
которые обязаны быть сверены (это ровно тот класс, где ТЗ может выдать догадку
за решение):
- **М1-текст.** Формула `Touch editor: best effort / intentionally degraded`
сверена дословно с `docs/TOUCH-SUPPORT.md:163-167` («Documentation rule») —
совпадает буква в букву, это один из трёх легальных вариантов, а не
собственная формулировка автора.
- **М2-текст.** Утверждение «сохранение properties-диалога существующего
line/rect/ellipse/furniture пишет color/opacity в общий `_decorStyle`»
сверено чтением `src/houseplan-editor-runtime.ts:4422-4485` (`_decorSaveShape`):
строки 4476–4480 действительно присваивают
`this.host._decorStyle = { ...style, fill/fillColor/fillOpacity сохраняются
из предыдущего _decorStyle кроме rect/ellipse }` — подтверждено. Функция
правит только элемент с `shape.id === d.id` (строка 4434), других
размещённых объектов не касается — подтверждает фразу «не ретроактивная
перекраска других объектов».
- Также проверено чтением, что `_decorSaveText` (`houseplan-editor-runtime.ts:4381-4419`,
диалог текста) **не** пишет в `_decorStyle` — то есть ограничение п.9 списком
«line/rect/ellipse/furniture» без text точное, а не случайно узкое.
Обе фразы дельты — не догадка, а корректно сформулированный факт кода.
## Унаследовано из r1
Без повторной проверки в этом раунде приняты все выводы
`docs/reviews/SPEC-REVIEW-360-r1.md` (заход r1, снимок тела issue на 08:00:23Z,
т.е. revision 1) — дельта их не затрагивает:
- обязательные разделы §7.1 присутствуют (сценарий, «что человек увидит»,
проблема, скоуп/не-скоуп, контракт, данные/i18n/совместимость, файлы,
AC1–AC8, план тестов, риски/откат, release-артефакты, принятые предположения);
- сверка утверждений ТЗ с деревом на SHA `0decce8d`: единый `_decorStyle` как
source для line/rect/ellipse/text/furniture, структура
`.decorbar`/`.editbar-tools`/`.editbar-end`, `flex-wrap` вместо скролла,
хрупкие тесты `demo/smoke_decor.mjs:132-134` и
`test/color-picker.test.mjs:57-62`, независимость `fillColor`/`fillOpacity`,
отсутствие новых i18n-ключей — все подтверждены и делтой не задеты;
`_decorStyle` со времени SHA `0decce8d` в этом файле не менялся (единственные
изменения на пути к `6ce42b33` — сам документ ревью и предыдущий golden/фикс
furniture-обводки, не относящиеся к decor-style contract), поэтому вывод
остаётся в силе и на текущем HEAD;
- product-question gate соблюдён, блокирующих продуктовых вопросов у автора нет;
- трек `small` подтверждён верно (одна поверхность, риск/сложность ≤3, нет
миграции, нет нового UX-контракта, лимит ревью ТЗ — 2 цикла);
- откат описан и достаточен;
- Low-находок сверх M1/M2 не было и не появилось.
## Что проверено заново в этом раунде
- Текст п.8 и п.9 (весь текст, добавленный дельтой);
- AC5 в новой редакции — единственный AC, чьё доказательство дельта расширяет;
- шаг 4 плана тестов в новой редакции;
- код `_decorSaveShape` и `_decorSaveText` (чтением, не исполнением — на этапе
spec кода задачи нет, поэтому запуск невозможен и не требуется).
## Гейты
Этап — spec, не code. `src/**` по issue #360 не изменялся (Rule #1: код
разрешён только из `S5-ready`), поэтому `typecheck`/`test`/`build`/
`check-docs`/`model-invariants`/смоки к этому раунду неприменимы — гейты кода
запускаются на этапе код-ревью. Единственная проверка этого раунда — чтение
кода `_decorSaveShape`/`_decorSaveText` в текущем дереве `dev` (см. выше),
выполненное вручную.
## Находки
Новых High/Medium/Low находок в дельте revision 1 → revision 2 нет. Обе
Medium-находки r1 закрыты полностью и точно.
## Чего не проверял
- Реальную браузерную/визуальную проверку (кода нет, применимо к
код-ревью после реализации) — без изменений относительно r1;
- `demo/golden` и фактический рендер light/dark — неприменимо к ТЗ;
- соответствие итогового кода контракту — предмет отдельного код-ревью.
## Вердикт
Зелёный. High: 0. Medium: 0 (обе находки r1 закрыты, новых нет). Issue готов
к переходу в `S5-ready`.