Files
houseplan-card/docs/reviews/SPEC-REVIEW-381-r2.md
T
2026-08-30 07:48:16 +00:00

135 lines
11 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-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`