Files
houseplan-card/docs/reviews/SPEC-REVIEW-500-r3.md
T
2026-09-10 11:41:16 +00:00

183 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPEC-REVIEW-500-r3
- **Issue:** #500 — одна граница владения config/adoption
- **Этап:** ТЗ на ревью (PROCESS.md §2.4)
- **Заход:** r3 · блокирующих циклов израсходовано 2 из 4 (лимит лёгкого трека
не действует — трек полный, лимит 4; заход r3 сам по себе бюджет не тратит,
если вердикт зелёный, §4/#227)
- **Материал раунда:** ветка `issue/500-config-adoption-boundary`, коммит
`622470ffb57285c6a2ffc9fa3d913004212fe00a` (докс-only, `docs(spec): #500 r3
— post-write profile keeps caller tails untouched`), поверх коммита
документа ревью r2 `3f6b991c2839e7c2aa2586b38b4292571e742cf6`. ТЗ:
`docs/specs/500-config-adoption-boundary.md`, блоб на этом коммите
`596ca78a…` (см. `git show 622470ff:docs/specs/500-config-adoption-boundary.md`).
Материал доступен локально (fetch выполнен), код продукта не менялся ни в
одном из трёх заходов — ТЗ описывает существующий код `origin/dev`, а не
вносит изменений в `src/**`.
## Скоуп разбора (по §2.10)
Это третий заход. Предыдущий вердикт (r2, документ
`docs/reviews/SPEC-REVIEW-500-r2.md`) — жёлтый, одна блокирующая находка
High-3, материал которой зафиксирован как коммит `c35ecf13206b`, дерево
`9a354a9fa366fcca195773d22a15f7947caf5d14`, блоб ТЗ
`5cfc36e2614361d1e90d4d9a8a9a7358d4bec3b9`. SHA живой, дельта построена как
`git diff c35ecf13..622470ff -- docs/specs/500-config-adoption-boundary.md`.
Дельта r3 нелокальной не является: правка ограничена одним понятием
(«профиль `post-write`») внутри одного раздела ТЗ (§6.3), одной строкой в
списке особенностей `import/apply`, одной строкой AC3, одной строкой риска
§12 и одним пунктом §15. Она не меняет выбранную границу, не переоткрывает
закрытые High-1/High-2, не добавляет новую подсистему и не сопоставима по
объёму с исходной задачей — значит, объём разбора по дельте оправдан, полный
повторный проход не требуется. Разбор ниже проверяет ровно то, до чего
дотягивается дельта: правильность нового описания профиля `post-write`,
согласованность AC3/AC4/§12/§15 между собой и с кодом, и то, что High-1/High-2
не пострадали от этой правки (они дельту не задевают — оба живут в §3 п.1–3 и
AC1/AC2, которые в дельте r3 не тронуты).
## Как проверялось
Материал сверен построчным чтением `src/**` на `origin/dev` (тот же код, что
и в r1/r2 — эта задача ещё не реализована, ТЗ описывает текущее поведение):
- `houseplan-editor-runtime.ts:9757` — подтверждена цитата ТЗ: `if
(this.host._hasFixedFloor) this.host._adoptInitialSpace(this.host._model,
true); else this.host._commitSpace(nextSpace);` внутри `_applyBackupImport`.
Именно это утверждение High-3 назвал неверно описанным в r2 («сегодня их
там нет»); r3 признаёт факт и меняет модель профиля, а не сам факт.
- Тайл `import/apply` после этой ветки: `_backupImportDialog = null`,
`_cacheSnapshot()`, `requestUpdate()`, `_showToast(...)` — совпадает с
текстом «выбор пространства (…), `_cacheSnapshot`» в списке особенностей
вызывающих (§6.3, последний абзац).
- `houseplan-onboarding-runtime.ts:476-483` и байт-в-байт дубликат
`houseplan-editor-runtime.ts:8677-8699` (`space/delete`, оба входа) —
`_commitSpace(...)` вызывается условно (`if (this.host._space === spaceId)`),
что соответствует формулировке «`_commitSpace` при удалении текущего
пространства» из того же списка; в обоих `_cfgRev`/`_layoutRev`
действительно перезаписываются из ответа `space/delete` **после**
`_adoptStructuralResponses` — подтверждает и I2, и таблицу AC4.
- `houseplan-editor-runtime.ts:9569-9591` (`_undoPlanOptimization`, `plan/
optimize_undo`) — тайл: сброс `_canOptimizeUndo`/`_undoKind`, очистки
историй, `_cfgEpoch++`, `_cacheSnapshot()`, toast — совпадает с текстом ТЗ.
- Проверена внутренняя согласованность документа: `grep` по терминам
«пост-шаг», «профил», `_adoptInitialSpace`, `_commitSpace`, `_restoreZoom`,
`_resumePendingNavMode` по всему файлу (`/tmp/spec_r3.md`) — нового
противоречия между §3 п.2 (описание «до»), §6.3 (описание «после»), AC3,
§12 и §15 п.7 не найдено; все места, где раньше стояло «post-write получает
общие пост-шаги `_cacheSnapshot`/`_regSignature`/`_maybeRebuildDevices`»,
переписаны на «пост-шагов нет, хвост остаётся у вызывающего» одновременно.
- Гейты (`typecheck`/`test`/`build`) не запускались: класс изменения —
докс-only (`docs/specs/**`), продуктовый код не тронут ни в этом заходе, ни
в предыдущих двух. Это тот же объём, что r1 и r2 сочли достаточным для
этапа ТЗ; код появится только после `S5-ready`, и именно код-ревью будет
отвечать на вопрос «оно работает» автотестами.
## Закрытие раунда r2
| Находка r2 | Чем закрыта | Где это видно |
|---|---|---|
| High-3: §6.3 утверждал «`_adoptInitialSpace`/… в профиль post-write не входят: сегодня их там нет», что неверно для `import/apply` при `_hasFixedFloor` (`houseplan-editor-runtime.ts:9757`, тогда `:9756`) | ТЗ признаёт факт и меняет модель: профиль `post-write` объявлен без пост-шагов вовсе — «последовательность заканчивается шагом 4», а `_adoptInitialSpace`/`_commitSpace` остаются частью нетронутого хвоста каждого вызывающего, а не шагом профиля. Формулировка больше не утверждает отсутствия вызова — она выносит его за пределы модуля | `docs/specs/500-config-adoption-boundary.md` §6.3 (строки «Профиль `post-write` **пост-шагов не имеет**: …включая `_adoptInitialSpace(_model, true)` в ветке `_hasFixedFloor` у `import/apply` (`houseplan-editor-runtime.ts:9757`)»), синхронно поправлены список особенностей `import/apply`, AC3, риск-строка §12, §15 п.7. Цитата с номером строки перепроверена чтением кода в этом заходе (см. «Как проверялось») |
High-1 и High-2 (заход r1) дельта r3 не задевает — они разрешены в r2 и
подтверждены зелёной частью вердикта r2 («обе High-находки r1 закрыты
содержательно»); ниже они наследуются без повторной проверки.
## Унаследовано из r2
Принято без повторной проверки в этом заходе, со ссылкой на материал, где
вывод был получен:
- **Семь вызывающих `_adoptStructuralResponses`** (три `reload` + четыре
`post-write`, включая оба входа `space/delete`) и **18 присваиваний
`_serverCfg =` в 8 модулях** (включая оба vacuum-writer'а) — перепроверены
чтением `src/**` в раунде r2 и подтверждены дословным совпадением чисел с
текстом ТЗ. Источник: `docs/reviews/SPEC-REVIEW-500-r2.md`, материал
`c35ecf13206b` / дерево `9a354a9fa366fcca195773d22a15f7947caf5d14`.
- Пересчитанные числа `_layoutRev =` (7/4), fingerprint config (10/5),
fingerprint layout (5) — там же, не изменились дельтой r3 (эти строки вне
диффа `c35ecf13..622470ff`).
- `_resumePendingNavMode`/`_restoreZoom` действительно не встречаются на
post-write путях — проверено в r2 и остаётся верным независимо от того, что
сам профиль в r3 переопределён как «без пост-шагов»: отсутствие вызова этих
двух функций на post-write путях не оспаривалось, менялась только модель
«откуда» это отсутствие проистекает (не выбор профиля, а отсутствие шага 5
вообще).
- Обязательные разделы §7.1, обоснование отказа от `small`, блок §15
«принято предположительно» по назначению — подтверждены в r1, дельты не
касались.
## Находки
Нет. Ни High, ни Medium, ни Low в этом заходе не обнаружено.
## Что проверено и корректно
- Единственная блокирующая находка r2 (High-3) закрыта по существу, а не
переформулировкой в обход: автор не стал спорить с фактом (цитата кода
подтверждена), а изменил модель профиля так, что факт больше не противоречит
тексту. Это тот редкий случай, когда правильный фикс — не «добавить
исключение», а «снять избыточное обобщение» (было false claim «этого шага
нет», стало honest «этот шаг не наш, мы его не трогаем»).
- Новая формулировка внутренне согласована по всем пяти местам документа,
которые о ней говорят (§6.3, список особенностей `import/apply`, AC3, риск
§12, допущение §15 п.7) — правки синхронны, нигде не осталось старой
формулировки «post-write получает общие пост-шаги `_cacheSnapshot`/
`_regSignature`/`_maybeRebuildDevices`».
- Все процитированные в дельте номера строк (`houseplan-editor-runtime.ts:9757`)
и утверждения о телах функций (`_commitSpace`, `_adoptInitialSpace`,
тайл `optimize_undo`) подтверждены чтением текущего `origin/dev`, а не
приняты на слово автора.
- Изменение не вводит нового продуктового вопроса и не расширяет скоуп:
правка — уточнение технической модели существующего рефакторинга,
подпадает под §15 «принято предположительно, менять свободно» и не требует
решения владельца (продуктовых вопросов по-прежнему нет — пользователь
ничего не наблюдает).
- AC4 (единственное намеренное изменение поведения — гейт `prepareImage` и
источник ревизии на post-write путях) дельтой r3 не задет и остаётся
доказанным описанным в r1/r2 способом.
## Чего не проверял
- Достижимость самого рефакторинга — кода ещё нет, ревью ТЗ оценивает план,
не реализацию.
- Автотесты/typecheck/build не запускались — класс изменения r3 докс-only,
как и r1/r2; гейты кода — предмет код-ревью (§2.7), когда появится код.
- Полный повторный построчный аудит `plan-optimize-write.ts`/
`space-copy-runtime.ts`/`serialized-write-queue.ts` на предмет иных,
ранее не поднятых расхождений — не проводился; фокус остался на том, что
дельта r3 реально меняет (модель профиля `post-write`) плюс проверка, что
High-1/High-2 не пострадали. Полный аудит этих трёх файлов был предметом
r1 и не повторяется третий раз без сигнала, что дельта их задевает — не
задевает (вне диффа `c35ecf13..622470ff`).
- Не проверялась (и не должна проверяться на этом этапе) корректность будущей
реализации хвостов вызывающих «без изменений» — AC3 сам называет способ
доказательства: «сверка диффом на ревью», то есть это станет предметом
код-ревью, когда появится реальный диф `houseplan-editor-runtime.ts`/
`houseplan-onboarding-runtime.ts`.
## Вердикт
Дельта r3 закрывает единственную блокирующую находку r2 содержательно и без
побочных повреждений уже принятого материала. Новых High/Medium/Low не
обнаружено.
**Вердикт: зелёный · заход r3 · блокирующих циклов 2/4 · High: 0 · Medium: 0 → в задаче**
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/500-config-adoption-boundary`, коммит `622470ffb572` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `22a334b5fe6188377bba675b5115d0b48735029e`
```
git log --all --format='%H %T' | grep 22a334b5fe61
```
- ТЗ `docs/specs/500-config-adoption-boundary.md`, блоб `596ca78ac25df5d829d803a733cc165635cc689c`
```
git log --all --find-object=596ca78ac25df5d829d803a733cc165635cc689c -- docs/specs/500-config-adoption-boundary.md
```
- Вердикт конвейера: `green` · High 0