mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 12:49:56 +00:00
270 lines
22 KiB
Markdown
270 lines
22 KiB
Markdown
# 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
|
||
```
|