Files
houseplan-card/docs/reviews/SPEC-REVIEW-597-r2.md
T
2026-09-19 13:43:11 +00:00

170 lines
17 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-597-r2 — «Редактор боковой панели переезжает на общий набор контролов (шаг 2 эпика #591)»
Issue: [#597](https://github.com/Matysh/houseplan-card/issues/597)
Этап: ревью ТЗ (PROCESS.md §2.4), лёгкий трек (метка `small`, лимит циклов — 2, §4)
Заход: r2 · блокирующих циклов израсходовано 1 из 2 (зелёный вердикт бюджет не тратит)
## Вердикт
**Зелёный.** High: 0. Medium в скоупе: 0. Medium вне скоупа: 0. Low: 0.
## Предыдущий раунд
r1 — жёлтый, High 0, Medium 2 (обе в скоупе, возвращены автору).
Документ: `docs/reviews/SPEC-REVIEW-597-r1.md`.
Материал r1: ветка `dev`, коммит `83a07925465b5aa6724b2b27d454029b56ddd631`, дерево
`bb4d62ab340508554c03325cb0b12628cc8204cd`, тело issue (SHA-256)
`2e961eb72bcea811973fc142ce1964083b483d4d60c8ea3c39f056ff0d6f7c53`.
## Скоуп разбора r2
Текущий `HEAD` рабочей копии — `589958aa9361a20baa408400ffbee5090adab5b1` (один коммит
поверх материала r1, и это коммит публикации самого документа r1 — продуктовый код
не менялся; `git diff 83a07925..589958aa -- src test scripts` пуст). Автор прямо
подтверждает в комментарии: «Код по-прежнему лежит локально … в ветку уйдёт после
зелёного ревью ТЗ». Следовательно единственный материал этого раунда — редактированное
тело issue #597: текущий SHA-256 тела `86d477896071a533fa490b54ec541603223443b53a134fde02c18864a4ca35c9`
отличается от анкера r1, редактирование подтверждено.
Разбор по дельте (§2.9): полный повторный обход ТЗ не делаю. Дельта локальна — оба
изменения текста адресуют ровно две находки r1 и не задевают ни одного другого раздела
или AC; смены контракта, ребейза на ушедший `dev` или новой подсистемы нет. Основание для
сравнения старого текста — точные цитаты найденных мест из документа r1 (сохранены дословно
в разделе «Находки» r1), сверенные построчно с текущим телом issue.
## Закрытие раунда r1
| находка r1 | чем закрыта | где это видно |
|---|---|---|
| **M1.** AC2 называл проверку «пять вызовов + отсутствие `min-height: 54px`», которая ловит только фрагмент «ряд-переключатель»: литерал любого из четырёх остальных фрагментов прошёл бы её незамеченным. | Столбец «чем доказывается» AC2 заменён на «тот же тест: пять вызовов плюс цикл по всем пяти текстам из `PANEL_FRAGMENTS`» — именно правка, предложенную самим r1 (переиспользовать существующий словарь для проверки отсутствия, а не одну характерную подстроку). | Тело issue, раздел «Критерии приёмки», строка AC2. Автор дополнительно приложил пробу: литерал карточки-группы в комментарии рядом с листом красит новую проверку («карточка-группа: правило осталось литералом… копия не устранена»), тогда как прежняя формулировка была бы зелёной на этой же пробе. |
| **M2.** К3/AC3 заявляли байт-в-байт неизменность `formKitCss(CARD_DIALOG_FORM_KIT)`, но названный свидетель («существующие тесты набора») сравнивает подстроки/селекторы/счётчики `@media`, а не полный текст. | К3 дополнен явным «в обеих формах, с рядом-переключателем и без него»; AC3 теперь ссылается на две новые фикстуры (`form-kit-card-dialog.css`, `…-with-switch.css`) со сравнением полного текста, снятые с `origin/dev` до правки. Автор идёт дальше минимально требуемого: замораживает форму `withSwitch: true`, которую сегодня не использует ни один потребитель — иначе её расхождение не поймал бы никто. | Тело issue: раздел «Контракт поведения» К3, раздел «Критерии приёмки» строка AC3, раздел «Принято предположительно» (пути двух новых фикстур названы явно). |
Обе правки — ровно то, что просил r1 (переиспользовать `PANEL_FRAGMENTS` для M1;
добавить фикстуру с полным текстовым сравнением для M2), без побочных изменений
остального ТЗ.
## Как проверялось (дельта)
1. Сверил текущий текст AC2/К3/AC3 с цитатами старого текста в документе r1 —
изменения ограничены ровно этими тремя местами плюс преамбулой «Редакция r2»,
ничего другого в разделах «Аналитика», «Скоуп/не-скоуп», «Риски», «Откат»,
«Release-артефакты», «Принято предположительно» не тронуто.
2. Прочитал `test/form-kit.test.mjs:25-58` в текущем дереве: словарь `PANEL_FRAGMENTS`
существует, содержит ровно пять точных текстов (карточка-группа, обводка фокуса,
выключенное состояние, ряд-переключатель, подпись ряда), и подтвердил находку r1
независимо — строка `min-height: 54px` (form-kit.test.mjs:47) действительно лежит
только внутри фрагмента «ряд-переключатель». Значит план M1-фикса («цикл по всем
пяти текстам из этого же словаря») технически реализуем сегодняшними средствами
файла — ровно то, что заявляет исправленный AC2.
3. Прочитал `test/styles-split.test.mjs:13-79`: подтвердил характеристику r1 — проверка
для `CARD_DIALOG_FORM_KIT` строит `Set` селекторов и считает `@media`/`@supports` по
заголовкам блоков, полного текстового сравнения действительно нет. Значит пробел,
который называла M2, реален, и предложенное автором добавление байт-в-байт фикстуры
его закрывает по существу, а не по формулировке.
4. Собрал тестовый бандл (`tsc -p tsconfig.test.json` + `fix-test-build.mjs`) и
независимо вычислил `formKitCss(CARD_DIALOG_FORM_KIT, …)`:
```
без переключателя: 1885
с переключателем: 2399
```
Числа совпали с теми, что автор привёл в комментарии-ответе («1885 | 2399», «оба
совпали побайтово») — заявление проверено вычислением, а не принято на слово.
5. `ls test/fixtures/` — ни одной из трёх фикстур (`summary-panel-editor.css`,
`form-kit-card-dialog.css`, `form-kit-card-dialog-with-switch.css`) в дереве ещё нет,
что соответствует стадии «спецификация»: реализация не начата, гейты кода к этому
раунду неприменимы.
## Дешёвые гейты, прогнанные в этом раунде
Зелёного Validate на `589958aa` не было. Прогнал сам:
- `npm test` (`tsc -p tsconfig.test.json && fix-test-build.mjs && node --test test/*.test.mjs`)
— **зелёный**: 2765 тестовых файлов/групп, 2787 тестов, pass 2786, fail 0, skipped 1
(skip не по теме задачи). Продуктовый код по #597 ещё не написан, поэтому это гейт
базового здоровья дерева на момент ревью, а не проверка AC — использован только как
инфраструктура для независимого вычисления AC3-чисел (шаг 4 выше).
Не прогонял и почему: `npx tsc --noEmit` отдельно (входит в `npm run build`, а `npm test`
уже прогнал компиляцию тестового набора через `tsconfig.test.json` — для спецификации без
диффа `src/**` этого достаточно), `npm run build` и сверку трёх копий бандла, `node
scripts/check-docs.mjs`, `npm run golden:verify`, смоки, `npm run invariants`,
`python -m pytest tests_backend` — все они гейты кода: диффа `src/**`/`docs/**`/геометрии
нет (`git diff 83a07925..589958aa` пуст вне `docs/reviews/`), а сама задача ещё не
реализована. Их место — код-ревью после того, как ветка появится.
## Унаследовано из r1
Без повторной проверки в этом раунде (документ `docs/reviews/SPEC-REVIEW-597-r1.md`,
материал: коммит `83a07925465b5aa6724b2b27d454029b56ddd631`, дерево
`bb4d62ab340508554c03325cb0b12628cc8204cd`) — дельта r2 этих участков не касается:
- Комплектность обязательных разделов §7.1 (все на месте).
- Построчное соответствие таблицы `summary-panel-editor-style.ts` пяти общим правилам.
- Числа «Проверено до написания ТЗ» (длина `String.raw`-шаблона 14585, отсутствие
обратного слэша, побайтовое совпадение генератора с параметрами панели).
- AC1, AC4–AC8 — метод доказательства и «чем краснеет» признаны точными.
- Скоуп/не-скоуп, К1, К2 (кроме способа доказательства, закрытого выше), К4, К5.
- Раздел «Классы риска §2.6» — разобран по существу для всех шести классов.
- Риски (фикстура, которая живёт вечно; `String.raw` → шаблон; соблазн «заодно»).
- Откат, Release-артефакты, `docs/ARCHITECTURE.md` не устаревает.
- Раздел «Принято предположительно» корректно отделяет технические решения от
продуктовых (имена фрагментов, `formKitCss` как композиция — теперь и пути двух
дополнительных фикстур, добавленных в этом раунде, той же природы).
- Продуктовая рамка: сценарий и «что человек увидит» отвечают на нужные вопросы без
терминов реализации, задача устраняет техдолг уже принятой поверхности (не требует
отдельной строки Core user jobs).
## Что проверено и корректно (дельта r2)
- Формулировки AC2/К3/AC3 после правки соответствуют тому, что просил r1, дословно, а
не по духу — переиспользован тот же словарь `PANEL_FRAGMENTS`, что и предлагал r1;
добавлена фикстура с полным текстовым сравнением, а не понижение формулировки К3.
- Числа, которые автор привёл как свидетельство («1885 | 2399», «оба совпали
побайтово»), подтверждены независимым вычислением на текущем коде.
- Автор расширил защиту сверх минимально требуемого (заморозил и неиспользуемую сегодня
форму `withSwitch: true`) — не создаёт новых рисков, не расширяет скоуп файлов.
- Никакая другая часть ТЗ дельтой не задета — сверка с цитатами r1 подтверждает
отсутствие побочных изменений.
## Чего не проверял
- Реализацию — код по #597 всё ещё не в диффе (`git diff 83a07925..589958aa` пуст вне
`docs/reviews/`), гейты кода (`build`, `check-docs`, `golden:verify`, смоки,
`invariants`) неприменимы на этой стадии.
- Полный повторный разбор всего тела ТЗ — дельта локальна (две строки таблицы плюс
преамбула), остальное унаследовано из r1 (раздел выше) согласно §2.9.
- Github-историю правок тела issue напрямую (публичный API ревизий тела недоступен) —
сверка сделана по точным цитатам старого текста, сохранённым в документе r1, плюс
подтверждение, что тело действительно изменилось (несовпадение SHA-256).
- Связь с владельцем — открытых продуктовых вопросов нет, обе находки были техническими
и закрыты автором по существу до этого раунда.
## Вывод
Обе Medium-находки r1 закрыты точно предложенным способом, а не переформулированы:
AC2 теперь проверяет отсутствие всех пяти фрагментов через уже существующий словарь
`PANEL_FRAGMENTS` (независимо подтверждено, что словарь содержит ровно пять точных
текстов и что старая проверка `min-height: 54px` действительно ловила только один из
них), AC3 теперь опирается на байт-в-байт фикстуры для обеих форм диалогового листа
(числа автора — 1885/2399 — подтверждены независимым запуском генератора). Дельта не
затрагивает ни одного другого AC или раздела ТЗ. Правка не создаёт новых открытых
вопросов и не расширяет скоуп сверх ранее согласованного. ТЗ готово к реализации.
**Вердикт: зелёный · заход r2 · блокирующих циклов 1/2 · High: 0 · Medium: 0**
---
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `dev`, коммит `589958aa9361` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `263e541f0909d65b6dc28f65a11b5270dc717529`
```
git log --all --format='%H %T' | grep 263e541f0909
```
- Тело issue: `8a56815128285d56f2c2f9f63eb6d8ae211525202f38e8bdd75159aa7c55412c`
- Вердикт конвейера: `green` · High 0