docs: review document for #476

Issue: #476
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-06 12:37:50 +00:00
parent b306dedb92
commit 557bc1fd85
+123
View File
@@ -0,0 +1,123 @@
# 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
```