From 20cd3241c0365df61318f5a2c6939e59120a5332 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 30 Aug 2026 07:27:04 +0000 Subject: [PATCH] docs: review document for #381 Issue: #381 User-Visible: no --- docs/reviews/SPEC-REVIEW-381-r2.md | 134 +++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-381-r2.md diff --git a/docs/reviews/SPEC-REVIEW-381-r2.md b/docs/reviews/SPEC-REVIEW-381-r2.md new file mode 100644 index 00000000..8e7aeba4 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-381-r2.md @@ -0,0 +1,134 @@ +# SPEC-REVIEW-381-r2 + +- Issue: https://github.com/Matysh/houseplan-card/issues/381 — «Действие по + нажатию: добавить "Ничего не делать"» +- Этап: ТЗ на ревью (PROCESS.md §2.4), полный трек (подтверждён в r1, дельтой + не затронут) +- ТЗ: `docs/specs/381-no-op-tap-action.md` +- Материал ревью: ветка `issue/381-no-op-tap-action`, ревизия автора `a64833a8` + (комментарий автора называет этот SHA явно) +- Заход: r2 · блокирующих циклов израсходовано 1 из 4 + +## Предыдущий раунд + +- Вердикт r1: жёлтый · High: 0 · Medium: 1 → в задаче. +- SHA, на котором получен вердикт r1: `7a260e8f` (ревизия ТЗ 1, найден по + git log — в самом вердикте SHA не назывался, только «ревизия 1»; это не + находка данного раунда, а восстановленный факт, нужный для дельты). +- Документ r1: `docs/reviews/SPEC-REVIEW-381-r1.md` (коммит `abbaebbc`). +- Единственная находка r1 — **M1 (Medium, в скоупе)**: в ТЗ отсутствовали + обязательные разделы `## Риски` и `## Откат` (PROCESS.md §7.1, DoR §2.5). +- Снятый Low (L1): ярлык AC4 «visual assertion» вне канонического словаря — + не требовал отдельного цикла, но было предложено переименовать заодно. + +## Дельта r1 → r2 + +`git diff 7a260e8f..a64833a8 -- docs/specs/381-no-op-tap-action.md` и +`git diff --stat 7a260e8f..a64833a8` (полный репозиторий) показывают: + +- изменён ровно один файл ТЗ (плюс появление `docs/reviews/SPEC-REVIEW-381-r1.md` + — это артефакт самого ревью, не предмет проверки автора); +- шапка: «первая редакция» → «вторая редакция, замечание r1 устранено», + ревизия 1 → 2; +- добавлен раздел `## Риски` (5 пунктов); +- добавлен раздел `## Откат` (двухэтапный, с явным разбором downgrade); +- AC4: ярлык «unit + visual assertion» → «unit, DOM assertion». + +Никакие другие разделы (Сценарий, Скоуп/Не-скоуп, Контракт поведения, UX/i18n, +Модель данных, Затронутые файлы, AC1–AC9 кроме ярлыка AC4, План автотестов, +Производительность, Release-артефакты, Принятые предположения) не менялись. +Дельта локальна к требованию M1 — не рёбейз, не смена контракта поведения, +не новая подсистема, объём на порядок меньше исходной задачи. Разбор в этом +раунде сокращён по дельте (PROCESS.md §2.9); полный список того, что +наследуется без повторной проверки, — в разделе ниже. + +## Закрытие раунда r1 + +| Находка | Чем закрыта | Где это видно | +|---|---|---| +| **M1** — отсутствуют `## Риски` и `## Откат` (§7.1, DoR §2.5) | Оба раздела добавлены с предметным наполнением, привязанным к механизмам контракта, а не общими словами | `docs/specs/381-no-op-tap-action.md:222-266` (см. текст ниже) | +| **L1** (Low, был снят без цикла) — ярлык AC4 вне словаря | Автор всё же переименовал попутно, как и предлагалось «если правит документ по M1» | `docs/specs/381-no-op-tap-action.md:180` — «unit, DOM assertion» | + +Проверка содержания `## Риски` (строки 222–245): 5 пунктов, каждый называет +конкретный механизм отказа и снимающий механизм со ссылкой на AC: +1. смешение `none` с absence/falsy → снимается явной веткой и таблицей в + AC2/AC5; +2. неполный охват потребителей `tap_action` (fingerprint, virtual-light, + cover presentation) → снимается предреализационным поиском consumers и + AC4/AC6; +3. ранний return не в той точке относительно `stopPropagation`/fallback → + снимается dispatcher-тестом и списком мутантов; +4. mixed-version/downgrade → снимается совместной поставкой frontend+backend + и порядком отката, описанным ниже; +5. пассивное нажатие приняли за поломку → снимается тем, что long + press/right click остаются документированными, и smoke-проверкой. + +Это ровно тот уровень конкретности, который требовал r1 («предметные риски +конкретно этого контракта», а не общие слова) — риски 2–4 почти дословно +покрывают то, что r1 предлагал как пример содержания. + +Проверка содержания `## Откат` (строки 247–266): двухэтапная схема — +(1) revert selector/runtime/i18n/docs, backend allowlist временно оставляет +`none` (старый frontend уже безопасно проецирует его в `info` — ссылается на +уже проверенный в r1 факт про `projectedTapAction`); (2) отдельный data-fix +переписывает сохранённые `none` в `info` перед тем, как убрать literal из +backend. Отдельно явно запрещён «слепой» полный `git revert` одним шагом с +объяснением, почему он ломает запись уже существующих конфигов старым +backend. Раздел отвечает буквально на вопрос DoR §2.5 «как откатить именно +этот выпуск» и не оставляет читателю выводить это самому — та же претензия, +которая была у r1 к рассеянному по тексту содержанию, снята: раздел +самодостаточен, хотя и корректно ссылается на уже существующий раздел +Import/export вместо дублирования его целиком. + +Оба раздела не противоречат остальному контракту: сценарий downgrade в +«Откате» согласован с фактами, уже подтверждёнными в r1 чтением исходников +(`projectedTapAction` fail-closed в `info`, `MARKER_SCHEMA` — allowlist). +Новых утверждений о поведении кода, не проверенных в r1 и требующих сверки с +`dev`, раздел не вносит — это узнаваемое пересказывание уже проверенных +фактов под правильным заголовком, что и просил r1. + +M1 закрыт по существу. Новых находок в дельте нет. + +## Унаследовано из r1 + +Без повторной проверки в этом раунде принято (документ `docs/reviews/SPEC-REVIEW-381-r1.md`, +SHA ревизии на момент проверки `7a260e8f`, дельта их не затрагивает): + +- продуктовая рамка и job **J3** `docs/SCOPE.md`, персона и поверхность; +- выбор трека (полный, не `small`/`trivial`) по критериям §5; +- все фактические утверждения ТЗ о текущем коде (`TAP_ACTIONS`, + `projectedTapAction`, `_clickDevice`, `_keyDevice`, `_ctxDevice`/long press, + editor selector visibility, lossless untouched-write, `tap_target` очистка, + backend `MARKER_SCHEMA`, import_export virtualization, `device-presentation.ts` + cover independence, i18n-словари и паттерн ключей, cross-language backend + test) — сверены с `dev` в r1, дельта их не меняет; +- терминология («Действие по нажатию» из `docs/USER-GUIDE.ru.md:812`, touch + как гарантированная поверхность по `docs/TOUCH-SUPPORT.md`); +- однозначность и доказуемость AC1–AC9 (кроме переименованного ярлыка AC4, + проверенного заново выше) и полнота плана автотестов/раздела «Мутанты»; +- полнота «Затронутые файлы и модули»; +- release-артефакты (оба changelog в скоупе одного `User-Visible: yes` + коммита, отсутствие нового golden/docs-скриншота). + +## Гейты + +Продуктовый код не менялся ни в r1, ни в дельте r2 (`git diff --stat` выше — +только `docs/specs/*` и `docs/reviews/*`). Этап — ревью ТЗ: `tsc`/`test`/ +`build`/`invariants`/smoke/`golden:verify`/`check-docs` неприменимы и не +прогонялись, как и в r1. Они станут обязательны на этапе код-ревью (§2.7). + +## Чего не проверял + +- Не проверялась реализация — её по-прежнему нет. +- Не проверялась орфография/стиль переводов DE/FR по существу — не менялись + в дельте, а структурная проверка ключей унаследована из r1. +- Не выполнялся повторный построчный разбор разделов, не тронутых дельтой + (см. «Унаследовано из r1» выше) — это осознанное сокращение объёма по + PROCESS.md §2.9, а не пропуск. + +## Вердикт + +M1 закрыт предметно, новых находок дельта не создала, остальной контракт +наследуется из r1 без изменений. High: 0, Medium: 0 → зелёный. + +`Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0 · Документ: docs/reviews/SPEC-REVIEW-381-r2.md`