Files
houseplan-card/docs/reviews/SPEC-REVIEW-647-r2.md
T
2026-09-25 08:10:38 +00:00

21 KiB
Raw Blame History

SPEC-REVIEW-647-r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/647
  • Этап: S4-spec-review (ревью ТЗ, PROCESS.md §2.4)
  • Трек: small (лёгкий), по аналитике автора в комментарии «Аналитика»
  • Материал: тело issue #647, раздел ## ТЗ, редакция r2 (снимок на момент этого ревью, 2026-09-25); предыдущий комментарий-ответ автора «ТЗ r2 — ответ на SPEC-REVIEW-647-r1»
  • Заход: r2 · блокирующих циклов израсходовано 1 из 2 (лёгкий трек)
  • Роль: ревьюер ТЗ (не автор)

Скоуп ревью

Редакция r2 — прямой ответ на жёлтый вердикт SPEC-REVIEW-647-r1 (0 High, 2 Medium, оба в скоупе, закрываются правкой текста). Дельта локальна: автор переписал п.4 «Скоупа», добавил К5/К6 в «Контракт поведения» и AC5/AC6 в таблицу доказательств, расширил «Release-артефакты» (docs/UX-MODES.md) и уточнил «UX, i18n» по touch-контракту; заодно поправил абзац «Проблема (по коду)», испорченный в r1 форматированием (вложенные обратные кавычки). Остальные разделы ТЗ (сценарий, «что человек увидит», не-скоуп, план автотестов, риски, откат, «принято предположительно») не менялись по существу.

По правилу «объём разбора по дельте» (PROCESS.md §2.10) разбор ниже сосредоточен на: (а) действительно ли новый текст закрывает Medium-1 и Medium-2 из r1, (б) не создали ли сами правки новой неоднозначности или непроверяемого AC. Разделы, не задетые дельтой и уже проверенные в r1 (состав обязательных §7.1, точность описания кода «как есть», удаление ключа count.devices, не-скоуп, план автотестов, трейлеры), приняты без повторной проверки — см. «Унаследовано из r1» ниже.

Как проверялось

  1. Сопоставлен текст комментария автора «ТЗ r2 — ответ на SPEC-REVIEW-647-r1» построчно с находками r1 (Medium-1, Medium-2) — заявленные правки существуют в текущем теле issue дословно там, где автор их называет.
  2. Перечитан весь текущий раздел ## ТЗ целиком (не только изменённые абзацы), чтобы делта не читалась в отрыве от контекста — противоречий между новыми К5/К6/AC5/AC6 и остальным текстом не найдено.
  3. Проверено закрытие Medium-1 (риск: новый слот наследует @media (max-width: 1100px) { .head .count { display: none } } и прячет крестик на обычной ширине):
    • п.1 «Скоупа» теперь явно удаляет само правило .head .count вместе со счётчиком («оно станет мёртвым»), а не просто оставляет его висеть;
    • п.2 явно требует для слота «собственный класс... не .count и без наследования его правил»;
    • п.4 переписан: «слот виден и занимает своё место на любой ширине, где видна группа кнопок режимов (в том числе 721–1100 px, где счётчик скрывался)»;
    • добавлен К6 и AC6 с прямой проверкой видимости/клика × на 390/768/1000/ 1400 px через elementFromPoint, с мутантом «слоту правило скрытия как у .count» → смок красный на 1000 и 768 px. 1000 px лежит внутри диапазона 900–1100 px, который r1 просил проверить явно. Три независимых слоя защиты (переписанный скоуп, явный запрет наследования, тестируемый АС с мутантом) закрывают находку с запасом.
  4. Проверено закрытие Medium-2 (риск: контракт hit-target ≥24×24 px из docs/UX-MODES.md:41-44 не упомянут в ТЗ и не защищён AC, документ не входит в Release-артефакты):
    • новый К5: «Кликабельная зона × — не меньше 24 × 24 CSS px (getBoundingClientRect()...), глиф — 13 px; клик в точку, отстоящую от центра глифа на 10 px..., закрывает редактор (как в #195)» — дословно воспроизводит контракт из UX-MODES.md и метод регрессионной проверки из истории #195;
    • новая строка AC5 в таблице с named-мутантом «размер слота 13 px (переменная) → смок красный» — защитный AC теперь имеет непустой третий столбец;
    • «Release-артефакты» теперь называют docs/UX-MODES.md явно: «строка про panel-host (убрать «device count»...) и абзац про × (× — в отдельном слоте..., hit target ≥ 24 × 24 px сохранён)»;
    • «UX, i18n» теперь содержит явное обоснование вместо голого утверждения: «Touch: размер кликабельной зоны × не уменьшается (≥ 24 × 24, как сейчас)...» — это уже не непроверенное заявление из «Аналитики» r1, а требование ТЗ со своим AC.
  5. Прочитан docs/UX-MODES.md ещё раз (строки 1–50) и сверен построчно с планом Release-артефактов r2: строка 14 («...device count, zoom and actions remain») и абзац строк 33–44 (крестик как часть кнопки-режима, «hit target of at least 24 × 24 px without changing the tab's layout footprint») — оба фрагмента действительно устареют после правки и оба поимённо покрыты планом автора («строка про panel-host» и «абзац про ×»). Расхождений между тем, что попросил ревью r1, и тем, что реально устареет в документе, нет.
  6. Проверено состояние кода на материале ревью (SHA 1ba4c23a, git show --stat HEAD, git branch -a, git log --oneline --all | grep 647): для #647 в дереве нет ничего, кроме коммита docs: review document for #647 (добавляет только сам документ r1 и строку в docs/reviews/ INDEX.md); ветка issue/647-toolbar-stable-width в этом чекауте отсутствует — код ещё не написан. Это подтверждает, что на этапе spec гейты (tsc, npm test, npm run build, check-docs.mjs, смоки, golden) неприменимы: сверять их не с чем, src/** в материале не меняется. Ровно так же поступил ревьюер r1 (см. его «Чего не проверял»).
  7. Перепроверены факты кода, на которые опирается r2 (не только цитаты ТЗ, а сам код): src/styles/dialogs.styles.ts:27-29 (правило .head .count, max-width: 1100px), src/styles/chrome.styles.ts:154-172 (.modetab .closex, 24×24 хит-зона через отрицательные поля), src/houseplan-card.ts:10811,10820 (крестик внутри активной кнопки, <span class="count"> отдельным элементом) — совпадает с описанием «Проблема (по коду)» дословно, включая уже исправленный в r2 абзац (нет разрушенных обратных кавычек, текст читается корректно).
  8. Проверен docs/reviews/INDEX.md — строка #647 | SPEC-REVIEW-647-r1.md | spec · r1 | 🟡 жёлтый | 0 | 2 | ... присутствует и соответствует документу r1; смежные подсистемные записи (#195 code · r1/r2 — оба 🟢, #437 — источник сводной панели) подтверждают исходные ссылки ТЗ на историю контрактов.
  9. Перечитаны docs/SCOPE.md и docs/process/REVIEWER.md заново для этого захода (без изменений в применимости выводов r1: задача обслуживает J1/J6 как polish уже принятого механизма переключения режимов, вне скоупа не выходит).

Гейты не гонялись — этап spec, материал ревью текстовый (тело issue), в дереве материала (SHA 1ba4c23a) для #647 нет диффа src/**, test/** или demo/**: код появится только после перехода в S5-ready/S6-in-progress и будет предметом код-ревью. Это не сокращение объёма, а соответствие самому этапу — гейты §8 привязаны к диапазону коммитов, а не к тексту issue.

Находки

Не найдено. Оба Medium из r1 закрыты правкой текста ТЗ, новых неоднозначностей, непроверяемых AC или противоречий делта не внесла.

Закрытие раунда r1

Находка r1 Чем закрыта Где это видно
Medium-1: п.4 ТЗ дословно предлагал унаследовать .head .count's @media (max-width: 1100px){display:none}, крестик мог исчезнуть на обычной ширине 721–1100 px, ни один AC это не ловил П.1 «Скоупа» удаляет само правило .head .count, а не наследует его; п.2 явно запрещает слоту класс .count и наследование его правил; п.4 переписан («слот виден... в том числе 721–1100 px, где счётчик скрывался»); добавлен К6 + строка AC6 с мутантом «правило скрытия как у .count → красный на 1000 и 768 px» Тело issue #647, раздел «Скоуп» п.1–п.2, п.4 «Адаптивность»; раздел «Контракт поведения» К6; таблица «AC · чем доказан · чем краснеет», строка AC6
Medium-2: контракт hit-target ≥24×24 px (docs/UX-MODES.md:41-44, issue #195) не упомянут в ТЗ, нет защищающего AC, docs/UX-MODES.md не в Release-артефактах, «Аналитика» заявляла «hit area прежние» без обоснования Добавлен К5 (дословно воспроизводит контракт ≥24×24 px и метод проверки как в #195); добавлена строка AC5 с мутантом «размер слота 13 px (переменная) → смок красный»; «Release-артефакты» теперь называют docs/UX-MODES.md (обе строки: про panel-host и про ×); «UX, i18n» содержит явное обоснование вместо голого утверждения Тело issue #647, раздел «Контракт поведения» К5; таблица AC, строка AC5; раздел «Release-артефакты»; раздел «UX, i18n, модель данных»

Унаследовано из r1 (принято без повторной проверки)

Материал: docs/reviews/SPEC-REVIEW-647-r1.md, SHA дерева 973c05543e3f... (якорь того раунда). Делта r2 не касается перечисленного ниже, поэтому повторно не перепроверялось:

  • Обязательные разделы §7.1 присутствуют все (сценарий, «что человек увидит до/после», проблема, скоуп/не-скоуп, UX/i18n/модель данных, план автотестов, риски, откат) — r1, раздел «Что проверено и корректно».
  • Описание бага «по коду» и границы правки совпадают с src/houseplan-card.ts:10797-10820 — r1, п.6 «Как проверялось» (в r2 перепроверено повторно в п.7 этого документа, поскольку абзац редактировался; расхождений нет).
  • Безопасность удаления ключа count.devices (единственное место чтения, сводная панель #437 использует другой источник) — r1, п.7 «Как проверялось».
  • AC1–AC3 однозначны и привязаны к способу доказательства с непустой колонкой «чем краснеет» — r1, «Что проверено и корректно» (нумерация AC1–AC3 в r2 не изменилась по содержанию, только сдвинулась таблица вниз добавлением AC5/AC6).
  • Не-скоуп сформулирован явно, без пересечения с #437 — r1, «Что проверено и корректно».
  • План автотестов ссылается на реально существующие механизмы (test/core-file-budget.test.mjs, scripts/smoke-links.mjs, scripts/mutation-registry.mjs, scripts/smoke-select.mjs, фасад data-hp="mode-tab") — r1, п.10 «Как проверялось».
  • Трейлеры User-Visible: yes и требование обоих changelog в одном коммите — r1, «Что проверено и корректно».
  • Открытых продуктовых вопросов владельцу нет — r1, «Что проверено и корректно»; в r2 не появилось новых.

Что проверено и корректно

  • Оба Medium из r1 закрыты по существу (не декларативно): каждое — переписанным текстом скоупа/контракта и новым тестируемым AC с названной мутацией, а не только обещанием в комментарии автора.
  • Новые К5/К6 и AC5/AC6 однозначны, ссылаются на конкретный метод измерения (getBoundingClientRect, elementFromPoint, смещение 10 px от центра глифа) и называют мутацию, на которой тест обязан покраснеть — колонка «чем краснеет» не пустая ни в одной новой строке.
  • Правка Release-артефактов называет обе фактически устаревающие строки docs/UX-MODES.md (строка 14 про panel-host/device count, абзац 33–44 про крестик и его футпринт) — проверено построчным сравнением с текущим содержимым файла, а не на слово автора.
  • Исправление абзаца «Проблема (по коду)» (вложенные обратные кавычки r1) не изменило фактического содержания — код-цитаты и номера строк те же.
  • Дельта не создала противоречий с неизменёнными разделами: «принято предположительно» по-прежнему корректно описывает размер слота как одну переменную, совпадающую с прежней кликабельной зоной (24 px), что теперь явно требуется К5.
  • На материале ревью (SHA 1ba4c23a) для #647 отсутствует какой-либо код — подтверждено git show --stat и git log; риск «текст ТЗ разошёлся с уже написанным кодом» (типичная причина находки на код-ревью) здесь не применим.

Чего не проверял

  • Гейты (tsc, npm test, npm run build, check-docs.mjs, смоки, golden, инварианты, smoke-select.mjs) — не прогонял: код для #647 ещё не написан на материале ревью, диапазон ревью — текст ТЗ, а не диапазон коммитов. Предмет код-ревью после реализации.
  • Не проверял браузером в реальном рендере поведение на 1000/900 px — вывод о том, что мутант «правило скрытия как у .count» действительно покраснит смок, сделан чтением плана AC, а не исполнением ещё не написанного смока; это неизбежно на этапе spec и будет прямой обязанностью код-ревью (проверить, что demo/smoke_toolbar_stable_width.mjs умеет падать на названной мутации).
  • Не переоценивал заново трек small/критерии лёгкого трека — не задеты делтой r2 (добавление двух AC не меняет ни сложность ≤3, ни «одну поверхность», ни отсутствие миграции конфига), и в r1 они не были находкой.
  • Не проверял golden-кадры и скриншоты документации — правка кода ещё не существует; риск golden-регресса уже учтён в разделе «Риски» ТЗ (принято в r1 без замечаний).

Вердикт

Найдено 0 High, 0 Medium. Оба Medium из r1 закрыты по существу текстом редакции r2 — каждое явной правкой формулировки контракта/скоупа и новым тестируемым AC с названной мутацией. Новых неоднозначностей или непроверяемых AC делта не внесла. ТЗ готово к разработке.


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

  • SHA материала: 1ba4c23a5813d0cf51fb010d79e45416a15facf2 (рабочая копия ревью).
  • Тело issue #647, редакция r2 — снимок на момент этого ревью, 2026-09-25.

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

  • Ветка: dev, коммит 1ba4c23a5813 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: b5de29ae951c3df446606e8324139fdb919ff0e1
    git log --all --format='%H %T' | grep b5de29ae951c
    
  • Тело issue: 96f3d23ef7e626083567418cc5d5c098150d97627da79dc8ebe77b949f39a1c1
  • Вердикт конвейера: green · High 0