From ddb2d5e07ba52ae5d28db768673825131de6b968 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 11:11:13 +0000 Subject: [PATCH] docs: review document for #476 Issue: #476 User-Visible: no --- docs/reviews/SPEC-REVIEW-476-r2.md | 123 +++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-476-r2.md diff --git a/docs/reviews/SPEC-REVIEW-476-r2.md b/docs/reviews/SPEC-REVIEW-476-r2.md new file mode 100644 index 00000000..c4f3c658 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-476-r2.md @@ -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, без изменений). + +--- + + + +## Материал раунда + +- Ветка: `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 + ```