mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
@@ -1,12 +1,13 @@
|
||||
# Индекс ревью
|
||||
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 271, issue: 138. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 272, issue: 139. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
|
||||
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|
||||
|---|---|---|---|---:|---:|---|---|
|
||||
| бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — |
|
||||
| #775 | [CODE-REVIEW-775-r1.md](CODE-REVIEW-775-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #772 | [CODE-REVIEW-772-r1.md](CODE-REVIEW-772-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #762 | [SPEC-REVIEW-762-r1.md](SPEC-REVIEW-762-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #761 | [CODE-REVIEW-761-r1.md](CODE-REVIEW-761-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | заявленная «красная» мутация не воспроизводится в этой среде | `scripts/process-metrics.mjs` |
|
||||
| #757 | [CODE-REVIEW-757-r1.md](CODE-REVIEW-757-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #756 | [CODE-REVIEW-756-r1.md](CODE-REVIEW-756-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
# SPEC-REVIEW-762-r1
|
||||
|
||||
Issue: #762 — «Warm remount и отложенный режим: хвосты после #756»
|
||||
Этап: spec (PROCESS.md §2.4) · Трек: ask (§5) · Заход: r1 · блокирующих циклов 0/4
|
||||
Материал: тело issue #762, раздел `## ТЗ`, сверено с рабочей копией на
|
||||
`0606a3664a6c819a501316f478840d6c3a5b456c` (HEAD; совпадает с актуализацией,
|
||||
заявленной в самом ТЗ — «Актуализация по `dev` `0606a366...`»; Validate на
|
||||
этом SHA зелёный). Код продукта в задаче ещё не писался — ревью судит только
|
||||
текст ТЗ и его соответствие дереву, на которое он ссылается.
|
||||
Route: fix.
|
||||
|
||||
## Скоуп
|
||||
|
||||
Пять связанных регрессий «тёплого» пересоздания карточки с отложенным правом
|
||||
записи (хвосты после #756/#95): (1) выход из отложенного редактора теряет
|
||||
исходный zoom/центр Просмотра; (2) камера дёргается на промежуточных кадрах
|
||||
отложенного восстановления без открытого диалога; (3) в warm-памятку
|
||||
попадает смешанная пара `hdrH`/`stageH` от разных layout; (4) позднее
|
||||
`_resumePendingNavMode` перебивает уже отданную пользователем новую команду
|
||||
режима; (5) смена пространства не отменяет ожидающее восстановление
|
||||
редактора старого пространства. Служит J1/J6 `docs/SCOPE.md` — «план остаётся
|
||||
верным» и «продолжить ту же работу после технического пересоздания»; новых
|
||||
UI-элементов, настроек и touch-жестов редакторов нет, View/выбор пространства
|
||||
на touch — обязательная поверхность и явно покрыты AC5.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Ревью ТЗ не включает выполнение гейтов — кода нет, этап его не требует.
|
||||
Проверялись: наличие обязательных разделов §7.1; однозначность и способ
|
||||
доказательства каждого AC; соответствие канону (`docs/WARM-REMOUNT.md`,
|
||||
`docs/CANVAS.md`, `docs/SCOPE.md`, `docs/USER-GUIDE.ru.md`); и, так как и
|
||||
ТЗ, и аналитический комментарий автора опираются на построчные ссылки на
|
||||
код, — сверка каждой процитированной причины с реальным деревом на
|
||||
материальном SHA, а не с заявлением автора.
|
||||
|
||||
Построчно сверено чтением (не исполнением) с текущим деревом:
|
||||
|
||||
| Утверждение ТЗ/комментария | Файл:строка | Проверено |
|
||||
|---|---|---|
|
||||
| `resumeWarmMode` удерживает камеру только при `_warmRevivePending`, случай без черновика выходит раньше защиты | `src/warm-mode-adoption.ts:55` (фактически строка `if (!host._warmRevivePending) return;`, код в файле сейчас на строке 58) | совпадает: ранний `return` действительно пропускает весь блок удержания `_view`/refit (строки 59–63), когда диалога нет |
|
||||
| `_setMode` при входе из Просмотра в редактор перезаписывает `_viewModeSnap` текущей камерой, а не сохранённым warm-снимком | `src/houseplan-editor-runtime.ts:986` (блок `this.host._viewModeSnap = { ... zoom: this.host._zoom ... }`) | совпадает: присваивание читает `this.host._zoom`/`this.host._view` на момент вызова `_setMode`, т.е. временную камеру отложенного Просмотра, если вход идёт через `resumeWarmMode → commit()` |
|
||||
| Обработчик шапки пишет новую `hdrH` вместе с `stage.clientHeight`, снятым до следующего рендера | `src/houseplan-card.ts:4068` (сейчас строка 4080: `this._warmPatch({ hdrH: t, stageH: stage.clientHeight })`) | совпадает: `stage.clientHeight` читается синхронно в том же колбэке, что и новое `t`, до того как layout успевает осесть под новой высотой шапки |
|
||||
| Новая команда редактора не отменяет `_pendingNavMode` синхронно | `src/houseplan-card.ts:737` (`_requestMode`) | совпадает: по всему файлу `_pendingNavMode` читается/пишется только в четырёх местах (:3311 установка, :4164–4166 потребление в `_resumePendingNavMode`, :7368/:7439 disconnect-путь) — `_requestMode` его не трогает вовсе |
|
||||
| Смена пространства не очищает pending | `src/houseplan-card.ts:1414` (`_commitSpace`) | совпадает: `_commitSpace` не ссылается на `_pendingNavMode` |
|
||||
| `docs/NAV-PERSIST*` на dev отсутствует | — | совпадает: файла нет, упомянутое в исходном (внешнем) репорте название действительно устарело |
|
||||
| `demo/smoke_nav_persist.mjs` существует и упомянут как часть материала | `demo/smoke_nav_persist.mjs`, `docs/WARM-REMOUNT.md:6` | совпадает |
|
||||
| «View restores the saved same-space centre and zoom on exit» — контракт п. 2 ТЗ не противоречит канону | `docs/CANVAS.md:104–113` | совпадает дословно по смыслу |
|
||||
| «Явная команда пользователя всегда сильнее ещё не применённой памятки» — контракт п. 5 — уже задокументированный принцип, ТЗ лишь уточняет его для окна загрузки модуля | `docs/WARM-REMOUNT.md:148–166` | совпадает |
|
||||
|
||||
Ни одно утверждение о текущем поведении кода не разошлось с деревом; все
|
||||
пять причинно-следственных связей, на которых строится ТЗ, подтверждены
|
||||
чтением, а не только ссылкой автора.
|
||||
|
||||
Дополнительно проверено: `_canManageConfiguration` (houseplan-card.ts:983)
|
||||
фолбэчится на `hass.user.is_admin` до ответа сервера — значит окно AC4
|
||||
«задержанный модуль» действительно достижимо пользователем (вкладки
|
||||
редактора рендерятся раньше, чем приходит авторитетный `can_write`), а не
|
||||
теоретическая гонка, которую невозможно воспроизвести через UI.
|
||||
|
||||
## Находки
|
||||
|
||||
High и Medium нет.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- Обязательные разделы §7.1 присутствуют все: сценарий (персона «владелец
|
||||
умного дома», десктоп/touch), что человек увидит до/после (одной фразой,
|
||||
без терминов реализации — «план может дёрнуться... после исправления
|
||||
сохраняет прежний вид»), проблема с построчными ссылками, скоуп и
|
||||
не-скоуп (явно перечислено, что НЕ переписывается: lifecycle целиком,
|
||||
загрузчик редакторов, TTL, owner-слоты, геометрия), контракт поведения
|
||||
и UX (пп. 1–8), модель данных/миграция/i18n («нет» явным текстом,
|
||||
обоснованно), критерии приёмки AC1–AC6 с доказательством, план
|
||||
автотестов, риски, откат, release-артефакты.
|
||||
- Каждый AC однозначен и снабжён конкретным, фальсифицируемым механизмом
|
||||
проверки: AC1 — числовые значения (1.6→3.4) и точка наблюдения (возврат
|
||||
после закрытия редактора); AC2 — rAF-запись каждого кадра перехода, а не
|
||||
только финала, явно запрещены «обязательные три кадра» как false floor;
|
||||
AC3 — наблюдение самой записи в памятку, а не только итоговых размеров;
|
||||
AC4/AC5 — конкурирующие исходы в обоих порядках (сервер раньше/позже
|
||||
модуля); AC6 — именованные существующие смоки, которые обязаны остаться
|
||||
зелёными, плюс проверка конечного состояния вместо поиска строк в
|
||||
исходнике.
|
||||
- Защитные AC (камера не дёргается, memo не смешивает пару, устаревший
|
||||
resume не побеждает) доказываются по правилам §2.7 уже на стадии ТЗ: для
|
||||
каждого из пяти симптомов назван отдельный красный свидетель на исходном
|
||||
коде, а не общий «потом разберёмся». План автотестов прямо требует писать
|
||||
их независимо друг от друга, чтобы один провал не прятал остальные — это
|
||||
снижает риск, что пройдёт зелёным ТЗ, которое на самом деле чинит только
|
||||
часть симптомов.
|
||||
- Термины согласованы с каноном: `_view`/`viewBox`/«Просмотр»/«пространство»
|
||||
использованы в точности как в `docs/CANVAS.md` и `docs/USER-GUIDE.ru.md`;
|
||||
описание warm-памятки, TTL, одноразового воскрешения диалога и приоритета
|
||||
явной команды не противоречит `docs/WARM-REMOUNT.md`, а п. 3 контракта
|
||||
(«наличие черновика не влияет на защиту камеры») точно закрывает
|
||||
несостыковку, которую сам канон констатирует словом «камера... возвращается
|
||||
бит-в-бит», а код — нет (см. таблицу сверки выше).
|
||||
- Технических утверждений, не подкреплённых ни кодом, ни каноном и не
|
||||
помеченных как предположение, не найдено — все пять причин проверены
|
||||
чтением и совпали; раздел «принято предположительно» (4 пункта) содержит
|
||||
только действительно нейтральные для пользователя технические решения
|
||||
(структура идентичности pending-запроса, разбиение тестов, отложенное
|
||||
измерение геометрии, тестовые значения zoom) и ни один не маскирует
|
||||
продуктовый вопрос.
|
||||
- Продуктовых вопросов владельцу в тексте нет, и это обоснованно: все восемь
|
||||
пунктов контракта либо повторяют уже принятое канон-решение (приоритет
|
||||
явной команды, «воскрешаем черновик, не воскрешаем решение», one-shot
|
||||
revive), либо являются прямым следствием того, что пользователь уже увидел
|
||||
как баг (откат к старой камере, потеря выбора). Отдельно проверена
|
||||
потенциально спорная граница — что происходит, если пользователь успевает
|
||||
запросить другой редактор, пока ещё не разрешился `_editorRuntime` внутри
|
||||
уже идущего resume (а не общий `can_write`): это реальное, достижимое через
|
||||
UI окно (см. «Как проверялось», фолбэк `_canManageConfiguration` на
|
||||
`is_admin`), и AC4 его покрывает явно, с обоими порядками разрешения гонки.
|
||||
- Touch покрыт в объёме, обязательном по `docs/TOUCH-SUPPORT.md`: View и
|
||||
выбор пространства полностью поддержаны, AC5 отдельно требует проверки tap
|
||||
в touch-viewport; новые touch-жесты редакторов осознанно не добавляются и
|
||||
не требуются (редакторы — desktop-first).
|
||||
- Release-артефакты: issue/ветка названы, `User-Visible: yes` обоснован
|
||||
(пользователь видел баг — пропадающий зум/самовольное переключение режима,
|
||||
значит и исправление видимо), оба changelog явно требуются в том же
|
||||
коммите, bundle/VERSION/теги не трогаются, перед S7 требуются ссылки на
|
||||
исходные красные и итоговые зелёные прогоны по каждому AC.
|
||||
- Трек `ask` обоснован критерием §5: несколько связанных async-путей,
|
||||
контракт камеры и риск 7/10, что выше рамок `show`; соответствует уже
|
||||
установленной метке `track:ask` и `ci:golden` (камера — визуальный риск
|
||||
даже без изменения статичного вида, значит `ci:golden` уместен).
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Исполнение гейтов (`tsc`, `npm test`, `npm run build`, golden, браузерные
|
||||
smoke) — кода ещё нет, этап spec их не требует; «дешёвый» зелёный Validate
|
||||
на материальном SHA относится к существующему `dev`, а не к ещё не
|
||||
написанной реализации этой задачи.
|
||||
- Фактическое поведение браузера на заявленных численных порогах (1.6→3.4,
|
||||
«не более 1 CSS px», «минимум 5 кадров») — это спецификация будущего
|
||||
теста, а не код, который можно прочитать и исполнить сегодня; проверено
|
||||
только, что похожий порог (1 CSS px, 48 CSS px и т. п.) — устоявшийся в
|
||||
проекте паттерн измерения (docs/CANVAS.md, docs/WALL-THICKNESS.md,
|
||||
docs/TOUCH-SUPPORT.md), а не произвольное число без основания.
|
||||
- Состояние соседних задач #756 и #95 как таковых — они не являются
|
||||
материалом этого ревью; ТЗ ссылается на их контракты корректно (черновик
|
||||
едет по цепочке, приоритет явной команды), и это подтверждено чтением
|
||||
`docs/WARM-REMOUNT.md`, а не повторным ревью тех issue.
|
||||
- Реализуемость предложенных точек изменения (`src/warm-mode-adoption.ts`,
|
||||
`src/houseplan-card.ts`, при необходимости `src/houseplan-editor-runtime.ts`)
|
||||
— список файлов правдоподобен (именно там найдены все пять причин), но
|
||||
фактический диф появится только на код-ревью.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. Документ ТЗ полон по §7.1, все пять причинно-следственных связей
|
||||
проверены чтением и совпадают с деревом на материальном SHA, каждый AC
|
||||
однозначен и снабжён названным способом доказательства и отдельным красным
|
||||
свидетелем, открытых продуктовых вопросов нет, технических утверждений без
|
||||
основания не найдено. High: 0, Medium: 0.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `0606a3664a6c` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `2b4c828038177a9231a8b041da0dad7c60c54f9f`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 2b4c82803817
|
||||
```
|
||||
- Тело issue: `43855b946e06e4cbd56d6890ba92b55ab76f4f3334fd8c10ac7b271d90344cee`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
<!-- hp:usage input_tokens=4063 output_tokens=35348 cache_creation_input_tokens=110554 cache_read_input_tokens=3296374 num_turns=42 -->
|
||||
Reference in New Issue
Block a user