mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -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`
|
||||
Reference in New Issue
Block a user