# 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 → в задаче** --- ## Материал раунда - Ветка: `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