docs: review document for #381

Issue: #381
User-Visible: no
This commit is contained in:
claude[bot]
2026-08-30 07:48:16 +00:00
parent 212606c3e4
commit 20cd3241c0
+134
View File
@@ -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`