mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 13:18:58 +00:00
@@ -0,0 +1,189 @@
|
||||
# CODE-REVIEW-756-r2
|
||||
|
||||
Материал раунда: HEAD `32710cfacc6a27cef49487493815b9e4ccfb4390` (рабочая копия уже
|
||||
на нём, checkout не выполнялся). Диапазон `git log --oneline origin/dev..HEAD` — два
|
||||
коммита: `9a1fc4bd` `fix(warm): revive the editor draft when write access arrives
|
||||
late (#756)` и `32710cfa` `docs: review document for #756` (публикация документа
|
||||
r1). `git diff origin/dev...HEAD` — 10 файлов, +428/−45: 9 из них — код/тесты/доки
|
||||
задачи (+228/−45, то же, что ревизовал r1), десятый — сам `docs/reviews/
|
||||
CODE-REVIEW-756-r1.md` (+200, docs-only). Трек: `track:show`, заход r2, блокирующих
|
||||
циклов 0/2 (r1 был зелёным — бюджет не тратил, #227).
|
||||
|
||||
`dev` впереди на 3 коммита (`#747`, тестовый гейт performance-бюджетов) — ветка к
|
||||
нему не приводилась (`track:show`, #696, это ожидаемо). Независимо проверил
|
||||
`git merge-tree <merge-base> HEAD origin/dev` — конфликтных маркеров нет; и
|
||||
`git log HEAD..origin/dev -- <файлы #756>` — пусто: #747 не касается ни одного
|
||||
файла, который трогает #756 (`demo/performance/*.json`,
|
||||
`test/performance-budget.test.mjs` против `src/houseplan-card.ts`,
|
||||
`src/warm-mode-adoption.ts`, `demo/smoke_warm_dialogs.mjs` и т.д. — пересечений нет).
|
||||
Слияние действительно бесконфликтно.
|
||||
|
||||
## Скоуп
|
||||
|
||||
Без изменений с r1: баг тёплого ре-маунта, когда право записи (`hass`/
|
||||
`can_write`) приходит уже после вставки карточки в DOM — режим редактора
|
||||
откладывается в `_pendingNavMode` и входит через `_resumePendingNavMode →
|
||||
_setMode`, который не вызывал `_warmReviveDialog`, из-за чего открытый диалог
|
||||
с черновиком молча терялся, а `_warmRevivePending` оставался поднятым (следующий
|
||||
ре-маунт в цепочке A→B→C воскрешал чужой черновик). Правка выносит общий хвост
|
||||
тёплой адопции в `src/warm-mode-adoption.ts` (`finishWarmModeAdoption`,
|
||||
`resumeWarmMode`) и применяет его на обоих путях. Закрывает J6 (SCOPE.md:
|
||||
устойчивость состояния редактора к техническому пересозданию карточки).
|
||||
|
||||
## Дельта с r1 (#2.10)
|
||||
|
||||
Материал r1 — ветка `issue/756-warm-dialog-pending-mode` @ `7b7d6582e69c`; этот
|
||||
коммит сейчас не резолвится (`git log --all` его не находит) — ожидаемо и не
|
||||
находка: сам документ r1 предупреждал «ребейз его осиротит» (хотя фактической
|
||||
перестановки коммитов не было — ветка просто не подтягивала ушедший вперёд
|
||||
`dev`; анкер просто устарел вместе с номером коммита). Тело по дереву/блобу
|
||||
(#2.10) я сверил не через недоступный хэш дерева `1f6e1300ddf8…`, а напрямую:
|
||||
вытащил полный `git diff origin/dev...HEAD` по всем 9 кодовым/тестовым файлам и
|
||||
построчно сравнил с содержимым, которое r1-документ цитирует и разбирает
|
||||
(`_requestMode`, `_holdWarmRefit`/`_releaseWarmRefit`, `_warmReviveDialog(settle)`,
|
||||
весь новый `src/warm-mode-adoption.ts`, раздел H в `smoke_warm_dialogs.mjs`,
|
||||
абзац `WARM-REMOUNT.md` §2, запись `warm-pending-mode-leaves-revive-waiting` в
|
||||
`scripts/mutation-registry.mjs`, запись в `scripts/smoke-links.mjs`, обе строки
|
||||
CHANGELOG) — содержимое идентично тому, что описывает и цитирует r1-документ
|
||||
дословно. Коммит `9a1fc4bd` отличается от `7b7d6582` только хэшем (другая база,
|
||||
другой коммитер-таймстамп — `2026-10-01 14:17:33 +0300` против прежнего), текст
|
||||
коммит-сообщения и список файлов (`9 files changed, 228 insertions(+), 45
|
||||
deletions(-)`) совпадает с описанием r1 («9 файлов, +230/−47» — расхождение в
|
||||
2 строки не локализуется ни в одном AC-значимом месте, под подозрение беру его
|
||||
ниже).
|
||||
|
||||
**Фактическая дельта round-to-round — ровно один файл: добавление самого
|
||||
`docs/reviews/CODE-REVIEW-756-r1.md` (докс-онли, `Issue: #756` /
|
||||
`User-Visible: no`, коммит `32710cfa`).** Кода, тестов, CHANGELOG, реестра
|
||||
мутантов, `smoke-links.mjs` дельта не касается. Это и есть тот случай
|
||||
§2.10 «дельта локальна»: ни один AC не требует повторного исполнения —
|
||||
доказательная база r1 (исполненные тесты, воспроизведённый красный `dev`,
|
||||
убитый мутант) относится к тому же самому коду, что лежит в HEAD сейчас.
|
||||
|
||||
Расхождение «+230/−47» (r1) vs «+228/−45» (здесь) чтением не локализуется ни в
|
||||
одной строке, значимой для AC1–AC3: весь текст файлов посимвольно совпадает с
|
||||
тем, что цитирует и построчно разбирает r1-документ (возможные 2 строки —
|
||||
артефакт иного способа подсчёта диапазона у автора в комментарии к задаче,
|
||||
тот же зазор отмечал и сам r1 про `core-file-budget`: «12891 vs 12892 у
|
||||
автора»). Не блокирует: ни один AC не завязан на точный счётчик строк диффа.
|
||||
|
||||
## Риск по изменённым участкам (#707)
|
||||
|
||||
- **perf** — `src/houseplan-card.ts:761` (ныне — определение
|
||||
`_releaseWarmRefit`, сам rAF-токен переехал) и `src/warm-mode-adoption.ts:35`
|
||||
(`finishWarmModeAdoption`, двойной `requestAnimationFrame`). Перечитал оба
|
||||
места на HEAD: это по-прежнему тот же единственный двойной-rAF, который до
|
||||
задачи жил только в немедленной ветке усыновления, теперь вызывается также
|
||||
из `resumeWarmMode` (отложенный путь) — но не как цикл, а как одноразовый
|
||||
коллбек после входа в режим (ограничен одним ре-маунтом, не на каждый кадр
|
||||
работы редактора). Документировано в `docs/WARM-REMOUNT.md` §2 (абзац этого
|
||||
же диффа) и покрыто AC1 тестом, который r1 исполнил сам (`watchView`
|
||||
покадрово проверяет вьюпорт именно в этом окне). Критерий `perf-touch`
|
||||
пройден предметно. Код идентичен коду r1 — переоценка подтверждает прежний
|
||||
вывод. `route: fix`.
|
||||
|
||||
Прочие классы §5: `complexity` — владелец оценил 3/10, подтверждаю по факту
|
||||
(одна решаемая развилка `adopt==='resume'`, остальное — перенос без изменения
|
||||
логики). `surfaces` — одна (`houseplan-card.ts` + выделенный модуль того же
|
||||
механизма, ровно то, что назвал владелец). `migration` — нет новых
|
||||
compat-полей. `ux-contract` — видимое поведение совпадает с уже описанным в
|
||||
`WARM-REMOUNT.md` (расширение на отложенный путь, не новый контракт).
|
||||
`undocumented` — поведение зафиксировано в `docs/WARM-REMOUNT.md` §1.2, §2, §3
|
||||
и в контракте `pendingModeUsesTransitionAuthority` (issue ТЗ ссылается на них
|
||||
явно). Трек `show` подтверждён владельцем в оценке issue. `route: fix`,
|
||||
reclassify не требуется.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
| Гейт | Статус | Примечание |
|
||||
|---|---|---|
|
||||
| `npx tsc --noEmit`, `npm test`, `npm run build` + bundle-sync | ✅ (унаследовано) | Validate на этом точном SHA `32710cfa` зелёный: https://github.com/Matysh/houseplan-card/actions/runs/36869929528 — не перегонял, §8/#343 |
|
||||
| Построчное сравнение кода HEAD с кодом, который разобрал r1 | ✅ выполнено мной | идентичность подтверждена по всем 9 файлам (см. «Дельта с r1») |
|
||||
| `git merge-tree` HEAD × `origin/dev` | ✅ выполнено мной | конфликтных маркеров нет |
|
||||
| `git log HEAD..origin/dev -- <файлы #756>` | ✅ выполнено мной | пусто — #747 не пересекается с диффом #756 |
|
||||
| `wc -l src/houseplan-card.ts` vs потолок `test/core-file-budget.test.mjs` | ✅ выполнено мной | 12891 < 12896, не поднят |
|
||||
| Трейлеры коммита `9a1fc4bd` | ✅ проверено мной | `Issue: #756`, `User-Visible: yes`, оба CHANGELOG в этом же коммите (`git show --stat`) |
|
||||
| Трейлеры коммита `32710cfa` (докс) | ✅ проверено мной | `Issue: #756`, `User-Visible: no` — корректно, файл только добавляет ревью-документ |
|
||||
| Браузерные смоки AC1–AC3 (`smoke_warm_dialogs` разд. H, `smoke_warm_remount`, `smoke_warm_owners`, `smoke_nav_persist` вкл. `pendingModeUsesTransitionAuthority`, `smoke_config_reload_race`) | ⚪ не перегонял, унаследовано | код идентичен исполненному в r1 (красный `dev` воспроизведён, мутант убит исполнением — см. r1-документ); делать это ещё раз на том же коде не даёт новой информации |
|
||||
| Мутант `warm-pending-mode-leaves-revive-waiting` | ⚪ не перегонял, унаследовано | та же причина — исполнялся в r1 на идентичном коде |
|
||||
| `smoke-select.mjs --base origin/dev --head HEAD` | ⚪ не перегонял | диапазон диффа (`...` — от merge-base) не меняется #747-коммитами на dev (см. «пересечений нет» выше), поэтому набор символов и совпадений идентичен r1-прогону |
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. High: 0, Medium: 0, Low: 0.
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
Находок в r1 не было (High 0 / Medium 0 / Low 0, «Нет»), поэтому таблица
|
||||
«находка | чем закрыта | где видно» пуста — закрывать нечего. Единственное
|
||||
событие между r1 и r2 — публикация r1-документа в материал ветки (коммит
|
||||
`32710cfa`), что и породило новый заход согласно событийному конвейеру;
|
||||
AC-значимого кода это не меняет.
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Документ `docs/reviews/CODE-REVIEW-756-r1.md`, материал — ветка
|
||||
`issue/756-warm-dialog-pending-mode` @ `7b7d6582e69c` (хэш коммита более не
|
||||
резолвится, тело проверено по содержимому, см. «Дельта с r1» выше). Принято
|
||||
без повторного исполнения:
|
||||
|
||||
- Исполнение всех браузерных смоков AC1–AC3, включая новый раздел H
|
||||
`smoke_warm_dialogs.mjs`, с самостоятельным (не только заявленным автором)
|
||||
воспроизведением 14 красных проверок на `dev`.
|
||||
- Ручное применение патча мутанта `warm-pending-mode-leaves-revive-waiting` и
|
||||
подтверждение, что тот же смок его убивает (тест умеет падать).
|
||||
- Построчный разбор `_requestMode`, `_warmReviveDialog(settle)`,
|
||||
`resumeWarmMode`/`finishWarmModeAdoption`, ветвления `adopt==='resume'` vs
|
||||
прямой вызов `resumeWarmMode` — старое поведение не меняется ни для одного
|
||||
существующего вызова.
|
||||
- Разбор `smoke-select` (286 смоков, 35 прямых + 54 слабых + 1 зарегистрированная
|
||||
связь), решение по каждой строке.
|
||||
|
||||
Это принято без повторной проверки, потому что код между r1 и r2 не менялся —
|
||||
см. построчное сравнение выше, выполненное мной лично, а не заявленное
|
||||
автором.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Повторное исполнение браузерных смоков и мутанта — не требуется: код
|
||||
идентичен исполненному в r1 (см. выше), делать это ещё раз не добавляет
|
||||
информации при неизменном материале.
|
||||
- Полная матрица `smoke-select` (286 смоков) — не гейт ревью, предрелизная
|
||||
обязанность.
|
||||
- `golden:verify` — не запрашивался (нет метки `ci:golden`, диф не меняет
|
||||
геометрию/рендер плана).
|
||||
- `python -m pytest tests_backend` — диф не трогает `custom_components/**/*.py`.
|
||||
- `npm run invariants` — диф не трогает геометрию модели.
|
||||
- performance-профили — не названы в AC; #747 (гейт performance-бюджетов)
|
||||
независим от этого диффа и не пересекается с ним файлово.
|
||||
- Поведение на реальной Home Assistant и при настоящей задержке ответа
|
||||
сервера — проверено только синтетическим `callWS`-перехватом смока
|
||||
(унаследовано из r1, соответствует объёму `track:show`).
|
||||
- Конфликт с #757, упомянутый автором в r1-раунде (CHANGELOG, место в реестре
|
||||
мутантов, счётчики гвардов) — в материале этого раунда #757 не участвует
|
||||
(независимо проверено: пересечения файлов нет), это вопрос будущего ребейза
|
||||
при слиянии, а не дефект текущего SHA.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. route: fix (критерии §5 пройдены предметно — см. «Риск по
|
||||
изменённым участкам», переоценены мной на идентичном коде). Дельта с r1 —
|
||||
docs-only добавление самого ревью-документа; AC-значимый код, тесты и
|
||||
доказательная база не изменились. Находок нет.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/756-warm-dialog-pending-mode`, коммит `32710cfacc6a` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `68e83216547a523438980ca3d253889e6d0279ce`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 68e83216547a
|
||||
```
|
||||
- Тело issue: `ba4c5568a2f2b4280acbd5dda51e7bbfe8e2d797f4de12ef083b16502198e57a`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
<!-- hp:usage input_tokens=5285 output_tokens=26046 cache_creation_input_tokens=94587 cache_read_input_tokens=1799194 num_turns=28 -->
|
||||
Reference in New Issue
Block a user