mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,163 @@
|
||||
# SPEC-REVIEW-29-r2
|
||||
|
||||
- Issue: https://github.com/Matysh/houseplan-card/issues/29
|
||||
- Этап: spec (PROCESS.md §2.4)
|
||||
- Заход: r2 · блокирующих циклов израсходовано 1 из 4
|
||||
- ТЗ: `docs/specs/029-device-inbox-lifecycle.md`
|
||||
- SHA предыдущего вердикта (r1): `a6ce1ae7e534fa4b41fcc0ab93e5ed95a693c4c1`
|
||||
- SHA материала этого раунда: `375b402d940a0ea30f23becef95f9755212ecbd9`
|
||||
(ветка `issue/29-device-inbox-lifecycle`, коммит «docs: preserve hidden
|
||||
device ghost mode»)
|
||||
- Трек: обычный, лимит циклов ревью ТЗ — 4.
|
||||
|
||||
## Скоуп разбора (по дельте, PROCESS.md §2.10)
|
||||
|
||||
Предыдущий вердикт (r1, документ `docs/reviews/SPEC-REVIEW-29-r1.md`) —
|
||||
жёлтый, две находки Medium в скоупе (M1, M2), High нет. Автор ответил
|
||||
комментарием в issue со ссылкой на коммит `375b402b` (фактический SHA —
|
||||
`375b402d`, см. выше) и заявил закрытие обеих находок.
|
||||
|
||||
Дельта — `git diff a6ce1ae7e534fa4b41fcc0ab93e5ed95a693c4c1..HEAD` по файлу
|
||||
ТЗ: 36 добавленных / 11 удалённых строк, все — в §10.1, §10.2, §10.3, §10.4,
|
||||
§14, AC1, AC4, AC6, §18 (риски). Дельта локальна: один документ, правки
|
||||
адресуют ровно M1 и M2, новая подсистема не затронута, поведенческий
|
||||
контракт вне уже согласованных Q1/AC не меняется, объём дельты не
|
||||
сопоставим с объёмом исходного ТЗ (548 строк). Условия «разбор остаётся
|
||||
полным» (ребейз на ушедший вперёд `dev`, смена контракта, новая подсистема,
|
||||
сопоставимый объём) не выполнены — сокращаю объём разбора до дельты и её
|
||||
последствий для AC1, AC4, AC6, §14, §18.
|
||||
|
||||
Продуктового кода на этом этапе нет, гейты §8 к ревью ТЗ не относятся (как
|
||||
и в r1).
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
| Находка r1 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| **M1** (Medium, в скоупе) — §10.1 убирал существующий режим просмотра скрытых/HA-disabled маркеров призраками на плане, не давая эквивалента в каталоге (`Find` работал только для реально отрисованного marker) | Автор не выбрал ни один из трёх предложенных путей закрытия буквально, а снял противоречие в корне: существующий локальный ghost-режим **сохранён** целиком (позиция, выбор, настройка, drag), его переключатель просто переносится с панели внутрь каталога как новый switch «Показывать скрытые на плане», доступный во всех вкладках. `Find` для скрытых/HA-disabled строк теперь доступен при включённом ghost-режиме (было — недоступен вовсе) | `docs/specs/029-device-inbox-lifecycle.md` §10.1 (новый абзац «Существующий локальный режим… сохраняется»), §10.2 п.6 (новый switch), §10.3 (столбец «Дополнительные действия» для трёх категорий — «Найти призрак при включённом ghost-режиме»), §10.4 (переписанное условие доступности `Find`), AC1 («Локальный ghost-toggle доступен внутри каталога, а его активность видна на кнопке «Устройства»»), AC4 (переписан), AC6 (добавлен абзац с явным описанием эквивалентности старому поведению), §18 (новая строка риска с защитой) |
|
||||
| **M2** (Medium, в скоупе) — `marker.hide_tip` (ru/en) ссылался на удаляемую кнопку «Скрытые и деактивированные» / «Hidden and disabled», §14 не включал обновление существующих строк | §14 получил новый абзац: `marker.hide_tip` обновляется на обеих языках, чтобы вести в каталог «Устройства», плюс явное требование поиска прочих ссылок на старые названия кнопок перед реализацией | `docs/specs/029-device-inbox-lifecycle.md` §14, новый абзац сразу после списка тестируемых строк i18n |
|
||||
|
||||
Обе находки закрыты по существу, а не декларативно: текст, который был
|
||||
предметом претензии (удаление режима просмотра позиции; необновлённая
|
||||
подсказка), в текущей редакции отсутствует, проверено чтением файла
|
||||
целиком, а не поиском одной фразы.
|
||||
|
||||
## Проверка дельты
|
||||
|
||||
- **AC1** (golden + smoke): формулировка «активность видна на кнопке
|
||||
«Устройства»» — проверяемое поведение (класс/атрибут кнопки для smoke,
|
||||
визуальное состояние для golden), метод доказательства не изменился и
|
||||
остаётся адекватным.
|
||||
- **AC4** (unit): новая формулировка «Show недоступен, а Find доступен
|
||||
только для призрака при включённом ghost-режиме» согласована с §10.3/§10.4
|
||||
той же дельты — противоречий нет.
|
||||
- **AC6** (smoke): добавленный абзац описывает переключатель ghost-режима
|
||||
как воспроизводящий текущее поведение 1:1 (позиция/выбор/настройка/drag,
|
||||
без изменения `marker.hidden`, сброс при выходе из редактора) — это то же
|
||||
утверждение, что и в §10.1, не новое обязательство.
|
||||
- **§14** (i18n): новый пункт обязывает обновить `marker.hide_tip` в обоих
|
||||
языках и найти прочие ссылки на старые названия кнопок. Точечно
|
||||
перепроверено по коду (не только по тексту ТЗ): `src/i18n/ru.json:673` и
|
||||
`src/i18n/en.json:673` — единственная пара строк с буквальной ссылкой на
|
||||
удаляемую кнопку (тот же результат, что и в r1); `title.show_all` и
|
||||
`devbar.show_all` и так входят в объём замены по §10.1 и отдельного
|
||||
упоминания не требуют.
|
||||
- **§18** (риски): новая строка «Перенос ghost-toggle делает активный режим
|
||||
незаметным после закрытия каталога» ссылается на AC6 как на защиту, но
|
||||
видимое active-state кнопки описано в AC1, а не в AC6 — см. находку L1
|
||||
ниже.
|
||||
|
||||
Остальные AC (AC2, AC3, AC5, AC7–AC11) дельтой не задеты текстуально и не
|
||||
зависят по доказательству от изменённых разделов — наследую вывод r1 без
|
||||
повторной проверки (см. «Унаследовано»).
|
||||
|
||||
## Находки
|
||||
|
||||
### L1 (Low) — риск в §18 ссылается не на тот AC
|
||||
|
||||
**Файл:** `docs/specs/029-device-inbox-lifecycle.md`, §18, строка риска
|
||||
«Перенос ghost-toggle делает активный режим незаметным после закрытия
|
||||
каталога».
|
||||
|
||||
Защита названа как «Активное состояние кнопки «Устройства» и сброс при
|
||||
выходе из редактора; AC6». Однако видимое active-state кнопки «Устройства»
|
||||
описано в AC1 («его активность видна на кнопке «Устройства»»), а не в AC6
|
||||
(AC6 — про воспроизведение самого ghost-поведения: позиция/выбор/drag).
|
||||
Сброс режима при выходе из редактора действительно упомянут в AC6 —
|
||||
ссылка верна только для половины защиты.
|
||||
|
||||
Не создаёт двусмысленности AC и не блокирует реализацию: оба AC
|
||||
(AC1 и AC6) существуют, проверяемы и в сумме покрывают заявленную защиту —
|
||||
перепутана только адресация в таблице рисков.
|
||||
|
||||
**Решение ревьюера:** снимается без правки текста ТЗ. Основание —
|
||||
PROCESS.md §2.4 «Low либо правится, либо снимается решением ревьюера с
|
||||
записью»: неверная перекрёстная ссылка в информационной таблице рисков не
|
||||
меняет ни один AC, не вводит в заблуждение исполнителя относительно того,
|
||||
*что* защищает риск (только относительно того, *под каким номером* это
|
||||
искать), и правка не стоит очередного цикла ревью на light-независимой
|
||||
задаче с уже потраченным одним из четырёх циклов.
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Документ: `docs/reviews/SPEC-REVIEW-29-r1.md`, SHA `a6ce1ae7e534fa4b41fcc0ab93e5ed95a693c4c1`.
|
||||
Принято без повторной проверки в r2, поскольку дельта их не касается:
|
||||
|
||||
- Соответствие `docs/SCOPE.md` (job J4/J6, персона Home admin, отсутствие
|
||||
выхода за продуктовую рамку, `Не входит §6`).
|
||||
- Формальная полнота §7.1 (все обязательные разделы присутствуют).
|
||||
- AC1–AC11 однозначны, у каждого назван способ доказательства (кроме
|
||||
точечных правок AC1/AC4/AC6, разобранных выше в этом раунде).
|
||||
- Корректность отражения решения владельца по Q1 в §7.2 и AC3.
|
||||
- Проверка фактических утверждений о текущем поведении кодом и каноном:
|
||||
`_bindingCandidates`, `HaBindingStatus.kind`, `marker.hidden`/`marker.removed`,
|
||||
`.slice(0, 200)` кап, `duplicate_name_area` устарела, фильтрация
|
||||
`new_device_ids` от уже скрытых id, терминология «Добавить»/«Правила
|
||||
иконок».
|
||||
- §21 «Принятые технические предположения» — маркировка предположений
|
||||
корректна и отделена от продуктовых решений (кроме пробела M1, который
|
||||
в r2 закрыт не через §21, а прямым сохранением поведения — что делает
|
||||
сам вопрос неактуальным: решать стало нечего, поведение не меняется).
|
||||
- Существование тестовых артефактов: `test/devices.test.mjs`,
|
||||
`test/ha-binding-status.test.mjs`, `test/device-presentation*.test.mjs`,
|
||||
`demo/smoke_hidden_flag.mjs`, `demo/smoke_binding_picker.mjs`,
|
||||
`scripts/smoke-select.mjs`.
|
||||
- Откат (§19) реалистичен, обратно совместим.
|
||||
|
||||
## Что проверено и признано корректным (в этом раунде)
|
||||
|
||||
- M1 и M2 закрыты по существу — см. таблицу выше.
|
||||
- Новый текст §10.1–§10.4 и AC1/AC4/AC6 внутренне непротиворечив: описание
|
||||
условия доступности `Find` (§10.4) совпадает с формулировками в таблице
|
||||
действий (§10.3) и в AC4.
|
||||
- Новая формулировка `marker.hide_tip` (замена ссылки на кнопку) не создаёт
|
||||
нового расхождения с `src/i18n/*.json` — единственная затронутая пара
|
||||
строк подтверждена прямым чтением файлов.
|
||||
- Старый (ошибочный) текст §10.1 «Скрытые markers больше не рисуются…» и
|
||||
«устраняет состояние панели» полностью удалён из документа — проверено
|
||||
`grep` по всему файлу, совпадений нет.
|
||||
- Терминология не расходится с `docs/USER-GUIDE.ru.md`/`FILTERING.md`:
|
||||
старое «Скрытые и деактивированные» (панель) и новое «Показывать скрытые
|
||||
на плане» (switch внутри каталога) — разные элементы UI с разной
|
||||
областью действия, противоречия нет; обновление USER-GUIDE уже стоит в
|
||||
§20 Release-артефакты.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Не повторял полную сверку §7.1/AC1–AC11 с кодом — она выполнена в r1 и
|
||||
дельта её не аннулирует (см. «Унаследовано»).
|
||||
- Не запускал никакие гейты (`typecheck`/`test`/`build`/смоки/`check-docs`) —
|
||||
на этапе ТЗ продуктового кода нет, диф не затрагивает `src/**`, гейты §8
|
||||
относятся к код-ревью.
|
||||
- Не проверял `docs/ARCHITECTURE.md`/`docs/CANVAS.md` — дельта их не
|
||||
касается.
|
||||
- Не оценивал заново перформанс (§17 дельтой не затронут).
|
||||
|
||||
## Вердикт
|
||||
|
||||
High-находок нет. Обе Medium-находки r1 закрыты по существу и подтверждены
|
||||
чтением текущего файла, а не заявлением автора. Единственная новая находка
|
||||
этого раунда — Low, снята решением ревьюера с записью, без возврата на
|
||||
правку.
|
||||
|
||||
**Вердикт: зелёный.** ТЗ переходит в «Готово к разработке».
|
||||
Reference in New Issue
Block a user