mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 04:09:17 +00:00
committed by
Sergey Matyunin
parent
85a064430b
commit
b39f99b3a4
@@ -0,0 +1,269 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user