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

17 KiB
Raw Permalink Blame History

SPEC-REVIEW-597-r2 — «Редактор боковой панели переезжает на общий набор контролов (шаг 2 эпика #591)»

Issue: #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



Материал раунда

  • Ветка: dev, коммит 589958aa9361 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 263e541f0909d65b6dc28f65a11b5270dc717529
    git log --all --format='%H %T' | grep 263e541f0909
    
  • Тело issue: 8a56815128285d56f2c2f9f63eb6d8ae211525202f38e8bdd75159aa7c55412c
  • Вердикт конвейера: green · High 0