Files
houseplan-card/docs/reviews/SPEC-REVIEW-449-r2.md
T
2026-09-04 18:18:14 +03:00

270 lines
22 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 — issue #449 · заход r3 (см. «Расхождение нумерации» ниже)
- Issue: https://github.com/Matysh/houseplan-card/issues/449
- Этап: ревью ТЗ (PROCESS.md §2.4)
- ТЗ: `docs/specs/449-double-fit-all.md`
- Материал: ветка `issue/449-double-fit-all`, SHA `9238ce666bee7ea9b7eddcd9e5b3f083b96ad114`
- Трек: полный (issue не помечен `small`); лимит циклов ревью ТЗ — 4 (§2.4)
- Заход r3 (истинный порядковый номер — см. ниже), блокирующих циклов
израсходовано до этого вердикта: **2**/4 (r1 — жёлтый, r2 — жёлтый)
## Расхождение нумерации: env дал «заход r2 · циклов 1/4», это неверно
Заголовок задачи для этого прогона (`needs.guard.outputs.cycle`/`spent`,
рендерится в `.github/workflows/process.yml:437-440,625`) сообщил «Заход: r2 ·
блокирующих циклов израсходовано 1 из 4». Это не совпадает с историей issue:
- r1 — жёлтый вердикт, коммент
[#issuecomment-5542152824](https://github.com/Matysh/houseplan-card/issues/449#issuecomment-5542152824),
документ опубликован коммитом `9206ef64` под именем
`docs/reviews/SPEC-REVIEW-449-r1.md`;
- правка `e027b2a0` закрыла M1;
- r2 — жёлтый вердикт, коммент
[#issuecomment-5542290451](https://github.com/Matysh/houseplan-card/issues/449#issuecomment-5542290451),
сам документ внутри себя корректно называет себя «заход r2» и явно ссылается
на материал r1 (`9206ef64`, SHA `5847bf2b1bb6`);
- правка `9238ce66` (материал этого раунда) закрывает M2.
То есть до этого прогона фактически было **два** жёлтых вердикта, а не один, и
этот прогон — **третий**, а не второй.
**Корневая причина найдена.** `guard`-джоб считает `attempt`/`spent` не по
номеру, а по числу комментариев issue, которые одновременно проходят два
regex-теста: `Вердикт:` и буквальную подстроку маркера (`SPEC-REVIEW` для
этапа spec) — `.github/workflows/process.yml:87-93`. Комментарий r1 закончился
фразой «Документ: см. артефакт ревью (публикуется шагом конвейера)» —
**без имени файла**, поэтому подстроки `SPEC-REVIEW` в его теле нет, и jq-фильтр
`of_stage` его не засчитывает. Комментарий r2, наоборот, заканчивается
«Документ: `docs/reviews/SPEC-REVIEW-449-r2.md`» — с маркером — и он единственный
учтён. Итог на момент этого прогона: `of_stage` = 1 (только r2), `attempt` = 1+1
= 2, `spent` = 1. Оба числа занижены ровно на единицу — комментарий r1
исключён из подсчёта навсегда, если его текст не поправить.
**Уже нанесённый ущерб.** Тем же образом на предыдущем прогоне `guard` посчитал
`cycle=1` для того, что публикующийся ревьюер верно назвал «заход r2» в тексте.
Шаг публикации (`.github/workflows/process.yml:661`,
`doc="docs/reviews/${marker}-${NUM}-r${CYCLE}.md"`) берёт номер не из текста
ревью, а из `$CYCLE` — и положил документ r2 в файл `…-r1.md`, **затерев**
оригинальный документ r1. Оригинал не потерян безвозвратно — он читается из
истории git:
```
git show 9206ef64:docs/reviews/SPEC-REVIEW-449-r1.md
```
— но рабочее дерево на `origin/dev` сейчас содержит под именем `…-r1.md`
содержимое второго раунда, а файла `…-r2.md` не существует вовсе.
**Что это значит для этого прогона.** Публикующий шаг снова возьмёт номер из
`$CYCLE` (=2, по тому же занижению) и положит **этот** документ в
`docs/reviews/SPEC-REVIEW-449-r2.md`. Это не перезапишет существующий файл
(такого файла ещё нет), поэтому данные в этот раз не теряются — но нумерация
файла (`r2`) разойдётся с истинным порядковым номером раунда (третий), и то же
занижение на единицу останется навсегда, пока кто-то не поправит текст
комментария r1 (добавив в него подстроку `SPEC-REVIEW-449-r1`) либо саму логику
подсчёта в `guard`. Ни то, ни другое не лечится в ветке `issue/449-double-fit-all`
и не входит в скоуп ТЗ #449, поэтому заведён отдельный issue —
[#454](https://github.com/Matysh/houseplan-card/issues/454) — со ссылкой на этот
документ и точной репродукцией.
Числа `spent`/`limit`, которые увидит владелец в шапке будущих прогонов, тоже
занижены на единицу: лимит `review-4` фактически сработает на пятом жёлтом
вердикте вместо четвёртого. На этом issue лимит не выбирается ни при
буквальном, ни при истинном счёте (2 или 3 из 4), поэтому решение по вердикту
этого раунда не меняется — расхождение зафиксировано для владельца и починки
инфраструктуры, а не потому, что оно блокирует #449.
Дальше в этом документе использую **истинный** счёт (r3, циклов 2 уже
потрачено до этого раунда), а не буквальные числа из шапки задачи — иначе
номер в тексте противоречил бы фактической истории раунда, которую сам же
документ и восстанавливает. Это решение не влияет на будущий автоматический
подсчёт: `guard` считает по наличию подстрок `Вердикт:`/`SPEC-REVIEW` в теле
комментария, а не по значению, которое написано после «заход r».
## Скоуп проверки — по дельте (PROCESS.md §2.10)
Предыдущий раунд (r2 по факту истории, физически опубликован как документ
`docs/reviews/SPEC-REVIEW-449-r1.md` из-за описанного выше искажения нумерации)
получен на материале SHA `e027b2a06d62b79530840a36369651d5eea38839`. Правка —
один коммит `9238ce66` поверх него, ребейза не было
(`git merge-base origin/dev 9238ce66` = `89647c10`, та же база, что и у r1/r2).
```
git diff e027b2a0..9238ce66 -- docs/specs/449-double-fit-all.md
```
```diff
- **Touch editor: not exposed** — жест живёт только во View и kiosk; редакторы
- Плана, Устройств, Декора и Подложки его не получают, их touch-поведение и
- редакторский double-click не меняются (§6 «Режимы», AC7). Правило
+ **Touch editor: not exposed** — жест живёт только во View и kiosk; редакторы
+ Плана, Устройств и Подложки (в ней редактируется декор) его не получают, их
+ touch-поведение и редакторский double-click не меняются (§6 «Режимы», AC7).
`docs/TOUCH-SUPPORT.md` → «Documentation rule».
```
3 строки, ровно та формулировка, которую предыдущий раунд предложил как
исправление M2. `docs/specs/README.md` не менялся. `git diff origin/dev...HEAD`
содержит только `docs/reviews/SPEC-REVIEW-449-r1.md` (артефакт прошлого раунда),
`docs/specs/449-double-fit-all.md`, `docs/specs/README.md` — класс C целиком,
продуктовый код по-прежнему не тронут.
Дельта локальна: не ребейз, не смена контракта, не новая подсистема, объём —
3 строки против находки в одну неточность. Разбор ограничен дельтой плюс всем,
до чего она дотягивается: сама строка и разделы, на которые она ссылается
(§6, AC7, канонический словарь редакторов). Остальные разделы ТЗ дельта не
задевает — см. «Унаследовано».
## Как проверялось
1. Получены оба вердикта (`gh issue view 449 --json comments`) и раскрыт их
реальный порядок и содержание — расхождение с шапкой задачи описано выше.
2. `git diff e027b2a0..9238ce66 -- docs/specs/449-double-fit-all.md` — ровно
правка из предложения r2, больше в файле ничего не менялось.
3. Независимо пересчитан состав редакторов по тем же трём источникам, что
называло r2, плюс дополнительно код:
- `docs/USER-GUIDE.ru.md:201-206` — таблица режимов называет три редактора:
План / Устройства / Подложка;
- `docs/UX-MODES.md:186` — `## Background — the decor underlay`, декор —
содержимое Подложки;
- `scripts/check-docs.mjs:115` — `[/\bDecor editor\b/gi, 'Background editor']`
нормализует устаревшее имя того же редактора;
- `grep -n -i "декор\|редактор" docs/specs/449-double-fit-all.md` — во всём
файле (шапка, «Не-скоуп» :73, AC7 :279-286) теперь ровно три редактора,
без расхождений.
4. Ссылки новой строки на §6 (`:180-188`) и AC7 (`:279-286`) открыты и
сверены построчно — оба раздела называют те же три редактора, что и
исправленная шапка.
5. `node scripts/check-docs.mjs` — прогнан лично, `Documentation checks passed
(7 files, 12 external links)`, exit 0.
6. `git diff --check e027b2a0..9238ce66 -- docs/specs/449-double-fit-all.md` —
чисто, exit 0.
7. Обязательные разделы §7.1 пересчитаны по текущему файлу
(`grep -n "^## " docs/specs/449-double-fit-all.md`) — все 15 присутствуют,
структура не пострадала от правки одной строки.
8. `docs/specs/README.md:178` — запись issue↔ТЗ на месте, дельтой не тронута.
9. Трейлеры `9238ce66` (`git show -s --format=full`) — `Issue: #449`,
`User-Visible: no`, верно для документационной правки без изменения
поведения.
## Закрытие раунда r2 (по факту истории; физически — документ `…-r1.md`)
| Находка r2 | Чем закрыта | Где это видно |
|---|---|---|
| **M2** (Medium, в скоупе): строка `Touch editor: not exposed` называла несуществующий четвёртый редактор («Декора» отдельно от «Подложки») | Формулировка заменена на «Плана, Устройств и Подложки (в ней редактируется декор)» — те же три редактора, что в §6/AC7/гайде | `docs/specs/449-double-fit-all.md:9-12` (коммит `9238ce66`) |
Проверено не на слово автора: цитаты трёх источников (`USER-GUIDE.ru.md`,
`UX-MODES.md`, `check-docs.mjs`) сверены заново лично (см. «Как проверялось»
п.3), а не приняты по формулировке коммента. Новая строка теперь дословно
согласована с §6 и AC7, на которые сама же ссылается — расхождения, которое
породило M2, больше нет нигде в файле.
## Находки
Нет находок уровня High/Medium/Low в дельте r3 по содержанию ТЗ #449.
Отдельно (не находка против ТЗ, а находка против инфраструктуры ревью) —
см. раздел «Расхождение нумерации» выше и заведённый
[#454](https://github.com/Matysh/houseplan-card/issues/454). Не учитывается в
счётчике High/Medium этого вердикта: предмет ревью — ТЗ #449, а не пайплайн.
## Что проверено и корректно
- **M2 закрыта по существу**, а не только по форме: три независимые сверки
(USER-GUIDE.ru.md, UX-MODES.md, check-docs.mjs) плюс перечитанные §6/AC7
подтверждают, что шапка теперь называет ровно тех же трёх редакторов, что и
остальной документ.
- **Никакого нового текста, кроме согласованной формулировки, правка не
вносит** — дифф ограничен тремя строками ровно там, где была неточность.
- **`node scripts/check-docs.mjs` зелёный** (прогнан лично на этом SHA).
- **`git diff --check` чист** — не внесено пробельных дефектов.
- **Обязательные разделы §7.1 на месте**, `docs/specs/README.md` не требовал
правки и не тронут.
- **Трейлеры `9238ce66` корректны**: `Issue: #449`, `User-Visible: no`.
- **Дельта действительно локальна** — не ребейз (`merge-base` не изменился с
r1/r2), не новая подсистема, не смена контракта: полный повторный разбор не
требовался.
## Унаследовано из r1 и r2
Всё, что предыдущие раунды проверили и признали корректным, а дельта r3 (3
строки правки M2) не задевает, принято без повторной проверки:
- продуктовая рамка — job J1, персоны Household/Guest (View) и Home admin
(kiosk), задача в скоупе `docs/SCOPE.md`; проверено в r1
(`docs/reviews/SPEC-REVIEW-449-r1.md`@`9206ef64`, доступен по этому SHA в
истории git — рабочая копия того же пути сейчас содержит текст r2, см.
«Расхождение нумерации»);
- решения владельца Q1/Q2 корректно перенесены в контракт поведения (§5) и
таблицу §6; сама таблица §6 не менялась ни в r2, ни в r3 — построчно
перечитана в этом раунде заново только по факту ссылки новой строки на неё
(см. «Как проверялось» п.4), не как повторная приёмка всего раздела;
- построчная сверка «текущего поведения по коду» (`_lastTap`/`_swipeStart`
внутри kiosk-ветки, отсутствие `dblclick` на stage, сигнатура `_fitAll`,
`ROOM_FIT_INTERACTIVE_OWNER`, `CameraTransitionReason`, no-op на
`sameCameraState`) — код не менялся ни разу за все три раунда, повторная
сверка не требуется;
- существование всех файлов, названных в «Плане автотестов» и AC1–AC11
(smoke/test/mutation-gate) — файлы не переименовывались и не удалялись;
- обязательные разделы §7.1 присутствуют все, AC пронумерованы и каждый несёт
способ доказательства — подтверждено в r1, пересчитано механически заново в
этом раунде (п.7 «Как проверялось»), без повторного смыслового чтения
каждого AC;
- блок «Принятые предположения» отделяет техническое от продуктового
корректно — не менялся с r1;
- вне-скоуп находка «Показать всё» / «Вписать всё» в `docs/USER-GUIDE.ru.md`
верно заведена r1 как [#452](https://github.com/Matysh/houseplan-card/issues/452)
и не относится к предмету этого раунда.
## Чего не проверял и почему
- **Реализацию** — её по-прежнему нет: `git diff origin/dev...HEAD` не
содержит класса A/B, только `docs/**`.
- **`npx tsc --noEmit` / `npm test` / `npm run build`** — не гонял: раунд не
меняет ни одной строки кода, а Validate на предыдущем продуктовом SHA к
этому ТЗ не относится (ТЗ ещё не имеет реализации).
- **Инварианты модели / golden / браузерные smoke** — не применимо: дифф не
трогает `src/**`, геометрию, рендер.
- **Полный текст ТЗ вне зоны дельты** (сценарий, скоуп/не-скоуп кроме списка
редакторов, модель данных, риски, план автотестов, откат,
release-артефакты) — не перечитывал заново; ничто из этого не зависит от
трёх изменённых строк, см. «Унаследовано».
- **Q1/Q2 продуктовую историю** — не переоткрывал: решения владельца
зафиксированы до r1, дельта их не касается.
- **Историческую правку комментария r1** (добавление в него маркера
`SPEC-REVIEW-449-r1`, чтобы восстановить корректный счёт `guard`) — не
делал: это чужой опубликованный комментарий, редактировать его не входит
в роль ревьюера; чинить нужно логику подсчёта, а не задним числом
переписывать историю issue. Отражено в заведённом
[#454](https://github.com/Matysh/houseplan-card/issues/454).
## Вердикт
High: 0 · Medium в скоупе ТЗ #449: 0 · Medium вне скоупа: 0 (обе прежние
вне-скоуп находки уже закрыты решением r1: #452 заведена, эта находка выше —
о пайплайне, а не о соседнем продуктовом поведении, заведена отдельно как
#454 в силу серьёзности, но не считается в этом тэлли, так как её предмет —
не ТЗ).
Зелёный вердикт (PROCESS.md §2.4, §12): M2 закрыта по существу, новых находок
против содержания ТЗ #449 нет. Зелёный вердикт бюджет циклов не тратит —
истинный счёт остаётся 2/4 (r1, r2), а не увеличивается этим раундом.
ТЗ #449 готово к `S5-ready`.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/449-double-fit-all`, коммит `9238ce666bee` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `ee0b2f4528fb30de7b90d79323c7aa16c96af7e7`
```
git log --all --format='%H %T' | grep ee0b2f4528fb
```
- ТЗ `docs/specs/449-double-fit-all.md`, блоб `d6ddccbb3920bdffbb8414f4b6c225a4cdf4f420`
```
git log --all --find-object=d6ddccbb3920bdffbb8414f4b6c225a4cdf4f420 -- docs/specs/449-double-fit-all.md
```