mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,193 @@
|
||||
# SPEC-REVIEW-598-r2
|
||||
|
||||
**Issue:** https://github.com/Matysh/houseplan-card/issues/598
|
||||
**Заголовок:** Три оставшихся диалога настроек на общий набор контролов: Пространство, Общие,
|
||||
Устройство (шаг 3 эпика #591)
|
||||
**Этап:** ревью ТЗ (PROCESS.md §2.4)
|
||||
**Заход:** r2 · блокирующих циклов израсходовано 1 из 4
|
||||
**Материал:** тело issue #598, раздел `## ТЗ`, снято `gh issue view 598 --json body` на момент
|
||||
чтения 2026-09-19 (редакция текста — r3 по собственной нумерации автора; раунд ревью — r2, так
|
||||
как редакции r2→r3 прошли под `blocked` без нового ревью). Комментариев к issue — 4: вердикт
|
||||
конвейера r1, ответ автора на M1 (с открытым вопросом), ответ владельца, финальный ответ автора
|
||||
со снятием `blocked` и заявкой `S4-spec-review`.
|
||||
|
||||
## Скоуп ревью r2
|
||||
|
||||
По PROCESS.md §2.10 предмет повторного раунда — дельта, а не задача целиком. Прежний вердикт
|
||||
(SPEC-REVIEW-598-r1.md, `docs/reviews/`) — единственная находка M1, Medium, в скоупе. Материал
|
||||
того раунда объявлен в его блоке «Материал раунда»: ветка `dev`@`958ab36652eb`, дерево
|
||||
`232dd22abb22fc04ea01c124ac4332a6060a4fc8`, блоб тела issue
|
||||
`aee54691f0fa3651f53c32dcb2934b5d0ebb983714e8c297783696b476976331`. Код по issue не писался
|
||||
(веток `issue/598-*` нет, `git branch -a | grep 598` — пусто, HEAD на `ac1d25a0` — это как раз
|
||||
коммит публикации `SPEC-REVIEW-598-r1.md`, `git status` чист), поэтому дельта — только текст
|
||||
тела issue между r1 и текущей редакцией.
|
||||
|
||||
Готового постраничного диффа тела issue GitHub не отдаёт (правки — не отдельные ревизии API, а
|
||||
редактирование одного и того же issue body), поэтому дельта восстановлена по авторской записи:
|
||||
комментарий «Ответ на жёлтый вердикт r1» построчно называет, что изменилось (М1, вторая находка
|
||||
про словарь `gs.hint`, пересчёт счётчиков), а текущее тело issue сверено с этим перечнем построчно
|
||||
— см. «Как проверялось» ниже. Это тот же метод доказательства, что использует сам конвейер для
|
||||
git-дельты: не гадание, а сверка заявленного изменения с итоговым текстом.
|
||||
|
||||
Разбор остаётся по дельте: рёбейз/смена контракта/новая подсистема неприменимы к текстовому ТЗ,
|
||||
объём дельты (одна находка + одно сопутствующее наблюдение автора) несравним с объёмом всего ТЗ.
|
||||
Проверке заново подлежат ровно те разделы, которых касается дельта: К4, К5, УX-таблицы «Общие» и
|
||||
«Устройство», раздел i18n со счётчиками, риск №4, AC4, AC5. Остальные разделы (§7.1 полностью,
|
||||
К1–К3/К6–К8, AC1–AC3/AC6–AC11, скоуп/не-скоуп, классы риска §2.6, план автотестов, откат,
|
||||
release-артефакты) дельта не трогает — они наследуются из r1 (раздел ниже).
|
||||
|
||||
## Как проверялось
|
||||
|
||||
1. Прочитано текущее тело issue #598 целиком (`gh issue view 598 --json body`, 312 строк) и все 4
|
||||
комментария (`gh issue view 598 --json comments`).
|
||||
2. Открыт архивный `docs/reviews/SPEC-REVIEW-598-r1.md` — проверено, что находка M1 сформулирована
|
||||
именно так, как её описывает текущий раздел «Закрытие раунда r1» ниже (сверка дословная).
|
||||
3. Построчно сверены места, где дельта обязана была появиться, с текущим текстом ТЗ:
|
||||
- К5 (новый контракт) присутствует и называет оба сообщения о состоянии поимённо со ссылкой на
|
||||
решение владельца;
|
||||
- УX-таблица «Общие настройки», строка «Солнце», явно оставляет `gs.sun_missing` callout'ом; УX
|
||||
«Устройство на плане» явно называет карточку («Действие по нажатию»), где остаётся callout'ом
|
||||
`marker.run_target_gone`, — то есть седьмое пояснение из r1-находки больше не висит без места;
|
||||
- раздел i18n предметно: «Итого 24 ключа, 96 строк» вместо прежних 26/104; таблица разбивки
|
||||
12+12 ключей × 4 языка = 48+48 строк сходится арифметически (проверено умножением, не
|
||||
переписано на слово);
|
||||
- список «переиспользуются и не удаляются» в i18n явно включает и `gs.sun_missing`, и
|
||||
`marker.run_target_gone` — они не попадают ни в один список переносимых ключей;
|
||||
- AC5 добавлен, доказательство — блок в смоках «Общих» и «Устройства» с фикстурой без
|
||||
`sun.sun` и черновиком с несуществующей целью, страж — новый мутант
|
||||
`state-callout-hidden-under-help`;
|
||||
- риск №4 переписан под этот же риск явно («соблазн спрятать предупреждение заодно... запрещено
|
||||
К5 и сторожится мутантом»);
|
||||
- нумерация AC — пересчитана таблица ТЗ: AC1…AC11, встроен новый AC5, дальше сдвинуто на один
|
||||
без пропусков и дублей (сверено построчно, не на слово автора).
|
||||
4. Отдельно проверено новое наблюдение автора, не бывшее находкой r1: перенос `gs.hint` из
|
||||
`src/i18n/support/*.json` в основной каталог как `gs.card_fills.help`.
|
||||
`grep -rn "gs.hint\|gs\\.hint" src/` и чтение `src/editors/general-settings-dialog.ts` /
|
||||
`src/i18n/support/*.json` подтверждают заявленное — ключ реально живёт в `support/*.json` и
|
||||
читается через `supportT(...)`, а `_help()` действительно резолвит `${string}.help` через
|
||||
основной `_t`. Значит перенос текста между словарями, который называет ТЗ, — не выдумка, а
|
||||
реальное расхождение путей чтения; `test/i18n-dead-keys.test.mjs` реально существует и
|
||||
действительно сливает оба словаря (файл присутствует в дереве), так что заявление «оставленная
|
||||
копия покраснит его» проверяемо, а не голословно.
|
||||
5. Терминология «карточки-группы» — уже используется `docs/USER-GUIDE.ru.md:572` для диалога
|
||||
комнаты (#594); r1 это подтвердил, дельта термин не меняет — унаследовано.
|
||||
6. `git branch -a`, `git log --oneline -3`, `git status` — подтверждают отсутствие кода и то, что
|
||||
HEAD стоит ровно на коммите публикации r1-документа; материал для код-ревью по этому issue не
|
||||
существует, гейты (typecheck/test/build) неприменимы на этапе ревью ТЗ, как и в r1.
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
| Находка r1 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| M1 (Medium) — судьба `marker.run_target_gone` не решена; счётчик i18n «7 пояснений» расходится с 6 явно поимёнными парами «карточка → текст» | Автор задал продуктовый вопрос владельцу (обязателен, т.к. решение 18.09 «под «?» уезжает всё» — продуктовое, распространять ли его на предупреждения — тоже продуктовый вопрос, а не только технический выбор варианта а/б, которые оба предложил r1); владелец ответил в комментарии: оба сообщения остаются видимыми callout'ами. ТЗ переписано: добавлен К5, AC5, УX-таблицы обеих форм явно называют карточку/место, где остаётся callout, риск №4 и мутант `state-callout-hidden-under-help` добавлены, счётчик i18n пересчитан на 24 ключа/96 строк | К5 (строка «Сообщения о состоянии остаются на виду»); AC5 в таблице критериев; УX-таблица «Общие настройки» строка «Солнце» и «Устройство на плане» строка «Действие по нажатию»; раздел i18n «Итого 24 ключа, 96 строк»; раздел «Риски» пункт 4 |
|
||||
| Сопутствующее наблюдение автора (не было находкой r1, вскрыто при разборе M1) — `gs.hint` читается из `support/*.json`, а не из основного словаря; перенос под «?» — это перенос ключа между словарями, а не только разметки | Явно описано отдельным разделом «`gs.hint` лежит в другом словаре»; в i18n-разделе прямо сказано: переезжает как `gs.card_fills.help`, копия в support удаляется во всех четырёх локалях, `test/i18n-dead-keys.test.mjs` покраснит при забытой копии | Раздел «`gs.hint` лежит в другом словаре» в «Аналитике»; раздел i18n, абзац «Отдельно: `gs.hint` переезжает...» |
|
||||
|
||||
Оба пункта закрыты текстом ТЗ, а не заявлением «сделано»: место, счётчик и страж названы конкретно
|
||||
и проверяемы по самому тексту, без необходимости угадывать поведение реализации (ровно то, чего не
|
||||
хватало для AC4 в r1).
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Без повторной проверки приняты выводы `docs/reviews/SPEC-REVIEW-598-r1.md` (материал: `dev`@
|
||||
`958ab36652eb`, дерево `232dd22abb22fc04ea01c124ac4332a6060a4fc8`), поскольку дельта r1→r2 их не
|
||||
затрагивает:
|
||||
|
||||
- полнота обязательных разделов §7.1 (сценарий, что человек увидит, проблема, скоуп/не-скоуп,
|
||||
контракт поведения, УX, модель данных и миграция, i18n, AC, план автотестов, риски, откат,
|
||||
release-артефакты) — дельта не удаляла и не переименовывала ни один раздел, только правила К4,
|
||||
добавила К5 и AC5, пересчитала i18n;
|
||||
- К1–К3, К6–К8 — запись в те же ключи, поведение сохранения/отмены, `hp-color-opacity`, классы-опоры
|
||||
`.srcrow`/`.dispsection`/пр., клавиатура/44px, граф загрузки — не упомянуты дельтой, текст не
|
||||
менялся;
|
||||
- AC1–AC3, AC6–AC11 (нумерация до AC5 не сдвигается, после — сдвигается на один без потери
|
||||
содержания, проверено построчно в п.3 «Как проверялось») — доказательства и способы покраснения
|
||||
идентичны r1;
|
||||
- скоуп/не-скоуп — идентичен, сверен построчно на этапе r1 с архивным `SPEC.md` эпика #591 и с
|
||||
#594 — дельта эту границу не трогает;
|
||||
- 11 golden-сцен AC8 (было AC7 в r1) — тот же список имён, дельта не добавляла и не убирала сцены;
|
||||
- классы риска §2.6 — не переписывались;
|
||||
- терминология «карточки-группы» (USER-GUIDE.ru.md:572) и минимум 44 px (TOUCH-SUPPORT.md) — не
|
||||
переписывались;
|
||||
- существование примитивов набора (`form-kit.ts`: `formCard`, `formRow`, `segmented`, `colorRow`) и
|
||||
факт, что `hpf-switch` в коде не существует и правильно помечен «принято предположительно», —
|
||||
дельта эти утверждения не касается.
|
||||
|
||||
## Находки
|
||||
|
||||
Не найдено. Дельта закрывает M1 полностью и по существу (не декларативно): продуктовая часть
|
||||
вопроса ушла владельцу и получила прямой ответ, техническая часть (счётчики, место словаря)
|
||||
решена автором самостоятельно и корректно, с проверяемыми доказательствами. Новых догадок,
|
||||
выданных за факт, дельта не вносит — оба новых утверждения (перенос словаря, арифметика счётчиков)
|
||||
проверены по коду и по самому тексту таблиц, а не приняты на слово.
|
||||
|
||||
## Что проверено и признано корректным
|
||||
|
||||
- М1 закрыт: `marker.run_target_gone` явно назван callout'ом карточки «Действие по нажатию»,
|
||||
`gs.sun_missing` — callout'ом карточки «Солнце»; ни один не участвует в переносе под «?»; AC4
|
||||
(«абзацев-пояснений... не осталось») теперь непротиворечив относительно AC5 («сообщения о
|
||||
состоянии остались видимыми»), поскольку ТЗ явно развело термины «пояснение» и «сообщение о
|
||||
состоянии» и использует слово «callout» только для второго — код-ревьюеру не придётся гадать,
|
||||
что считается нарушением AC4.
|
||||
- Продуктовый вопрос действительно был продуктовым (что человек видит — предупреждение или скрытая
|
||||
подсказка) и действительно ушёл владельцу, а не решён автором за него; технический побочный
|
||||
вопрос (словарь) автор решил сам, как и предписывает §7.1 — граница между двумя видами вопросов
|
||||
соблюдена корректно.
|
||||
- Счётчики i18n пересчитаны верно и согласуются с комментарием автора «было 26/104, стало 24/96» —
|
||||
проверено умножением по таблице, а не переписано на слово.
|
||||
- `gs.hint`/`supportT`/`_help()`/`test/i18n-dead-keys.test.mjs` — реальные пути в коде, наблюдение
|
||||
автора не является отвлечённым утверждением.
|
||||
- Материал раунда r1 (SHA `958ab36652eb`, дерево, блоб тела issue) не осиротел: `dev` не двигался
|
||||
вперёд относительно r1 непредвиденным образом, HEAD рабочей копии — коммит публикации того же
|
||||
документа; отдельная реставрация по дереву/блобу не потребовалась.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Не проверял `fr`-локаль на реальные значения строк (унаследовано из r1 — там же не проверялось
|
||||
предметно, только совпадение счётчика «4 языка» с существующими словарями `en/ru/de/fr`).
|
||||
- Не сверял архивный `SPEC.md` эпика #591 построчно — он не входит в это репо (не найден ни по
|
||||
`find . -iname "SPEC.md"`, ни в файловой системе с иным путём), это внешний присланный документ;
|
||||
ТЗ и r1, и текущая редакция сознательно берут из него только раскладку, отклонённые части (смена
|
||||
поведения, компас, инлайн-цвет и т.д.) не входят в скоуп и не требуют сверки.
|
||||
- Не запускал `npm test`/`npm run typecheck`/`npm run build` — кода по issue нет (ветки `issue/
|
||||
598-*` не существует), гейты неприменимы на этапе ревью ТЗ; они станут предметом код-ревью.
|
||||
- Не оценивал будущую формулировку `docs/USER-GUIDE.ru.md` для новой раскладки трёх диалогов — этот
|
||||
документ обновляется на этапе кода (Release-артефакты ТЗ это явно называют), сейчас сверялась
|
||||
только терминологическая преемственность («карточки-группы»), не текст будущей правки.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Единственная находка предыдущего раунда закрыта по существу: продуктовый вопрос решён владельцем,
|
||||
техническое наблюдение — автором, оба с явными, проверяемыми следами в тексте ТЗ (К5, AC5,
|
||||
УX-таблицы, счётчики i18n, риск №4, новый мутант). Дельта не вносит новых High или Medium находок и
|
||||
не разрушает ни один вывод r1: наследуемые разделы не затронуты, а точки соприкосновения с дельтой
|
||||
(AC4/AC5, i18n-таблица) проверены заново и непротиворечивы. ТЗ готово к разработке.
|
||||
|
||||
`Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0`
|
||||
|
||||
---
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, тот же коммит, что и в r1 — `958ab36652eb` (кода по issue #598 не появлялось между
|
||||
раундами); рабочая копия ревью — `ac1d25a08cb6da1e4154e857df761504a7f79d1d` (коммит публикации
|
||||
`SPEC-REVIEW-598-r1.md`).
|
||||
- Тело issue снято `gh issue view 598 --repo Matysh/houseplan-card --json body` 2026-09-19,
|
||||
312 строк — предмет этого раунда; официальный sha256 нормализованного тела для якоря пишет
|
||||
конвейер публикации, как и в r1 (issue #414), самостоятельный расчёт здесь не приводится во
|
||||
избежание расхождения метода нормализации с конвейером.
|
||||
- Комментарии issue на момент ревью: 4 (`gh issue view 598 --json comments` → `length: 4`) —
|
||||
вердикт r1, ответ автора (M1 + открытый вопрос), ответ владельца, финальный ответ автора.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `ac1d25a08cb6` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `d80ad22ec697829c20bd27b1a0cd5bda4d600e55`
|
||||
```
|
||||
git log --all --format='%H %T' | grep d80ad22ec697
|
||||
```
|
||||
- Тело issue: `a81e7c46b347ae3eb2a0de35e30606c335c901733d52a04e1019a937a6d737fb`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user