diff --git a/docs/reviews/SPEC-REVIEW-178-r1.md b/docs/reviews/SPEC-REVIEW-178-r1.md new file mode 100644 index 00000000..f0b37caa --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-178-r1.md @@ -0,0 +1,227 @@ +# SPEC-REVIEW-178-r1 + +- **Issue:** https://github.com/Matysh/houseplan-card/issues/178 +- **ТЗ:** [`docs/specs/178-toggle-entity.md`](../specs/178-toggle-entity.md) + (commit `e46ef6f55c44ec1f05268cdff4ceeb4dcc5af116`, ветка `issue/178-toggle-entity`) +- **Ревьюер:** Claude (ревью ТЗ ≠ автор), этап `S4-spec-review` +- **Цикл:** r1/4 (обычный трек — issue не `small`/`trivial`, подтверждено + комментарием аналитики и меткой `feature` без `small`) + +## Скоуп ревью + +Ревью ТЗ #178: новое optional поле `marker.toggle_entity`, дающее пользователю +выбор конкретной собственной `light.*`/`switch.*`-сущности для действия +«Переключить состояние» у составных устройств (сейчас цель выбирает эвристика +`resolveOwnEntity()`/`ownRoleCandidates()`), плюс диалоговый селектор, +stale-fallback, влияние на explicit controls-group, backend-валидацию и +export/import. + +Не в скоупе ревью: код ещё не написан (issue в `S4-spec-review`, +`git diff origin/dev...HEAD` для `src/**` и `custom_components/**/*.py` пуст — +проверено), поэтому проверка реализации, тестов и гейтов — предмет будущего +code-review (PROCESS.md §2.7). + +## Как проверялось + +Прочитано в заданном порядке: + +1. `docs/SCOPE.md` — цель задачи привязана к J3 («Let me act on the obvious + right from the plan»); лок-инвариант (§«The lock invariant») не затронут — + `toggle_entity` ограничен `light.*`/`switch.*`, что явно исключает + `lock.*`/`alarm_control_panel.*`. +2. `AGENTS.md`, `PROCESS.md` целиком (включая §2.4, §2.5 DoR, §7.1, §5, §8). +3. Issue #178 body и все 3 комментария: аналитика владельца (оценка, связанные + задачи, подтверждённые технические контракты), «взял в работу», «ТЗ готово». +4. `docs/USER-GUIDE.ru.md` — строки 541, 571–590, 645–650, 780–781: термины + «Переключить состояние», «Ведущая сущность» (для `light_entity`, отдельное + поле) сверены с §2 и §9.2 ТЗ. +5. `docs/CONFIG-COMPATIBILITY.md` (раздел про `marker.light_entity`, + строки 176–191) и `docs/TOUCH-SUPPORT.md` целиком — канонические документы, + которые ТЗ обязано соблюсти для поля-precedent и для editor-фичи. +6. Само ТЗ `docs/specs/178-toggle-entity.md` целиком. +7. Текущий код на той же ветке/коммите (продуктовый код не менялся) — построчно + сверены все фактические утверждения ТЗ о текущем поведении: + - `src/device-toggle.ts` — `ownRoleCandidates()` (370–392), `resolveOwnEntity()` + (401–423), `resolveControls()` (573–646), `toggleOriginOf()` (459–463); + - `src/devices.ts` — `ownControllableEntities()` (317–325), + `forcedLightEntityOf()` (329–336), `persistedExternalControls()` (288–300); + - `src/houseplan-card.ts` — диалоговый паттерн `light_entity` + (11924–11968, 12356–12358, 18398–18428: native `` в диалоге устройства), и такой строки в +документе нет вовсе. + +**Воспроизведение:** `grep -n -i "риск\|откат\|rollback\|touch\|производительн" docs/specs/178-toggle-entity.md` +возвращает пустой список (кроме заголовка-метаданных с оценкой сложности). +Автор код-ревью, дойдя до вопроса «какой откат у этой фичи, если баг +проявится после релиза» или «это editor-фича, какой у неё touch-статус», +не найдёт ответа в каноническом документе — придётся выяснять по памяти или +логике задним числом, что PROCESS.md §7.1 и прямо называет недопустимым +(«ТЗ, которое не может ответить на эти два вопроса, описывает работу, а не +изменение продукта» — тот же принцип применим к остальным обязательным +разделам). + +Содержательно риск, скорее всего, невелик — поле optional, миграции нет +(§7.2), диалог основан на native `