Files
houseplan-card/docs/reviews/SPEC-REVIEW-476-r2.md
T
2026-09-06 12:56:13 +00:00

124 lines
14 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-476-r2
- **Issue:** https://github.com/Matysh/houseplan-card/issues/476
- **Этап:** ТЗ на ревью (PROCESS.md §2.4), заход r2, блокирующих циклов израсходовано 1/4
- **Артефакт ТЗ:** `docs/specs/476-color-picker-ok.md` (ветка `issue/476-color-picker-ok`, HEAD `a29c854f`)
- **Предыдущий раунд:** SPEC-REVIEW-476-r1.md, вердикт жёлтый, ревью получено на `acd28558` (SHA восстановлен из
`Материал раунда` того же документа — в тексте вердикта issue-комментария SHA не назван, это отдельная находка
процесса, см. ниже)
- **Трек:** полный (не пересматривался — установлен в r1, дельта его не касается)
- **Ревьюер:** Claude (роль «ревьюер ТЗ», отдельная от автора — Codex)
## Дельта r1 → r2
```
git diff acd28558..a29c854f -- docs/specs/476-color-picker-ok.md
```
Один коммит автора: `a29c854f docs: clarify color picker invalid confirmation` (13 строк, только
`docs/specs/476-color-picker-ok.md`, +11/-2). Никакой другой файл дельтой не тронут — продуктовый код,
i18n, тесты, changelog не менялись (и не должны были: ТЗ ещё не перешло в код).
Правка — только §7.3 «Невалидный HEX» и §18 «Принятые предположения». Изменение локальное и не является ни
ребейзом на ушедший вперёд `dev`, ни сменой контракта поведения, ни новой подсистемой: это точечное уточнение
механизма против ровно одной r1-находки. Объём разбора этого раунда сведён к дельте и её последствиям (AC4,
§7.3, §18, §13 п.2), остальное наследуется из r1.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium: §18 предполагал, что confirm вызывает существующий `_commitHex()` и использует его результат — буквальная реализация ломает AC4, потому что повторный `_commitHex()` над уже нормализованным (сброшенным к последнему валидному) `_hexDraft` пройдёт валидацию и снимет `_hexInvalid`, закрыв picker без нового пользовательского ввода | §18 переформулирован: confirm может переиспользовать commit helper, но решение о закрытии выводится не только из нормализованного `_hexDraft`, а из отдельного признака «был ли новый `input` с валидным HEX после неуспешного commit»; признак не сбрасывается нормализацией draft, повторным confirm, blur или переводом фокуса — только новым валидным `input` | `docs/specs/476-color-picker-ok.md` §18, абзац 2 (diff `a29c854f`, +5 строк); идентичная формулировка продублирована в §7.3, последний абзац (+4 строки того же коммита) — обе секции синхронны, не разошлись |
| Low: §7.2 шаг 3 («возвращает фокус на trigger») читается как безусловный вне контекста §7.3 | Не правилась — r1 сам снял находку с записью («§7.3 имеет приоритет по построению документа, смысловой неоднозначности, влияющей на AC, нет»), автор не обязан был её чинить | `docs/reviews/SPEC-REVIEW-476-r1.md`, раздел «Low» |
Обе строки таблицы содержат конкретную строку текста, а не заявление автора «исправлено» — я прочитал диф и
сверил формулировку со сценарием, который сломал бы AC4.
## Проверка дельты по существу
Проверил, что новая формулировка §18/§7.3 действительно устраняет математическое противоречие с AC4, а не
маскирует его другой недосказанностью:
1. **Логика непротиворечива.** Новый признак — отдельная переменная состояния, не производная от
`_hexDraft`/`_hexInvalid`. Она устанавливается неуспешным commit'ом и снимается только `input`-событием с
валидным HEX. Blur, повторный confirm и внутренняя нормализация draft внутри commit helper явно перечислены
как НЕ снимающие признак — то есть сценарий из r1 («второй confirm над уже-нормализованным draft закрывает
picker») больше не проходит: второй confirm видит признак всё ещё установленным и обязан отказать в закрытии.
2. **Технически осуществимо, не только текст.** Сверил с реальным кодом `src/hp-color-opacity.ts`: `_hexInput`
(строка 649, обработчик `@input`) и `_commitHex` (строка 663, вызывается по `@blur`/`Enter`/по новому confirm)
— уже два разных обработчика, один привязан именно к `input`-событию поля. Новый признак естественно вешается
в `_hexInput`, не требуя изобретать несуществующий hook. §18 прямо помечен как «предположения, свободно
изменяемые ревьюером» — я не требую от автора большей технической детализации, чем нужно, чтобы AC4 не
ломался буквальным прочтением; этого условия текст теперь достигает.
3. **AC4 и план теста (§13 п.2, защитный мутант в §13 п.5 «закрыть surface при invalid HEX») не менялись
дельтой и не нуждаются в правке** — они уже требовали ровно то поведение, которое §18 теперь корректно
описывает. До правки была нестыковка между «что доказывает тест» и «что предполагает механизм»; после
правки оба говорят одно и то же.
4. Не нашёл новой находки, которую внесла бы сама правка (флип в другую сторону, новая недосказанность,
рассинхрон между §7.3 и §18) — тексты двух секций идентичны по формулировке, не только по смыслу.
Отдельная процессная находка (не по задаче, а по r1-вердикту): SHA, на котором был получен вердикт r1, не
назван в тексте issue-комментария с вердиктом («Вердикт: жёлтый · заход r1 …»); я восстановил его из раздела
«Материал раунда» документа `SPEC-REVIEW-476-r1.md` (`HEAD acd28558`) и перепроверил по времени коммитов
(`acd28558` 13:59:20+03:00 — до `972ef72b` 14:05:47+03:00 публикации r1-документа — до `a29c854f` 14:06:31+03:00
фикса). Это не блокирует данный раунд — документ r1 SHA всё-таки содержал, только не сам комментарий-вердикт.
## Унаследовано из r1 (без повторной проверки)
Все пункты ниже не пересматривались: дельта их не касается (правка ограничена §7.3/§18/AC4-механизмом), а
источник вывода — `docs/reviews/SPEC-REVIEW-476-r1.md`, получен на `acd28558`:
- Сверка фактических утверждений ТЗ о текущем коде/API с исходником (`_emit`, `_closePicker`, `_toggle`,
`_outsidePointerDown`, `_keyDown`, disconnect-путь, `ColorPickerLabels` без поля `confirm`, 5 потребителей
`showOpacity=false`, плоский формат i18n-ключей в 4 языках, существование и состав пяти golden-сцен,
`docs/specs/README.md`) — ни одна не оказалась догадкой, выданной за факт.
- Продуктовые вопросы Q1–Q4 закрыты решением владельца без новых открытых пунктов.
- Полный трек обоснован (новый наблюдаемый UX-контракт завершения).
- §5/§6 скоуп и не-скоуп разделены чётко, граница «расширение контракта → возврат в S3-spec» присутствует.
- AC1–AC3, AC5–AC8 сформулированы однозначно, у каждого назван способ доказательства (unit/smoke/golden/docs
gate) — дельта их текст не меняла и доказательная база (существующий код/тесты) не менялась тоже.
- §9 i18n, §10 модель данных/совместимость/downgrade, §8 touch/a11y, §14 release-артефакты, §16 риски, §17
откат — приняты без повторной проверки, содержимое этих секций дельтой не тронуто.
- Роли соблюдены: автор ТЗ (Codex) не рецензирует своё же ТЗ.
## Что проверено и корректно (специфично для r2)
- §7.3 и §18 после правки говорят об одном и том же механизме одними словами — не разошлись при редактировании
двух мест сразу.
- Новый признак технически привязываем к существующему разделению `_hexInput`/`_commitHex` в коде — предположение
не голословно.
- AC4 и защитный мутант §13 п.5 остаются достижимыми буквальным прочтением исправленного §18 (в r1 буквальное
прочтение делало их недостижимыми — сейчас нет).
## Чего не проверял
- Не гонял `typecheck`/`test`/`build`/`golden:verify` и `check-docs.mjs` — диф r2 (13 строк одного .md) класса C,
продуктовый код не менялся; `check-docs.mjs` для этого коммита уже гонялся автором и указан «passed» в
хендофф-комментарии, повторный прогон не добавляет информации к тексту-ревью.
- Не пересматривал ничего вне §7.3/§18/AC4 — см. раздел «Унаследовано из r1» с обоснованием, что дельта туда
не дотягивается.
- Не связывался с владельцем — новых продуктовых вопросов дельта не создала, различие «поле не менялось» vs
«новое валидное значение» техническое, не продуктовое.
## Вывод
Единственная Medium-находка r1 закрыта точной, синхронной правкой двух секций, логически устраняющей
противоречие с AC4, и технически реализуемой на существующей структуре кода. Новых находок дельта не внесла.
Вердикт зелёный; бюджет блокирующих циклов не расходуется (израсходовано 1/4, без изменений).
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/476-color-picker-ok`, коммит `a29c854f9904` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `fa031b74f2bfc5cd4b1eb39cf8e77b6a76386284`
```
git log --all --format='%H %T' | grep fa031b74f2bf
```
- ТЗ `docs/specs/476-color-picker-ok.md`, блоб `d21066d56e69c35fe7d0b40d9f965968dac9f803`
```
git log --all --find-object=d21066d56e69c35fe7d0b40d9f965968dac9f803 -- docs/specs/476-color-picker-ok.md
```