From a44fbd373d071ef407b37544fed51894f71b5564 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 07:26:33 +0000 Subject: [PATCH] docs: review document for #500 Issue: #500 User-Visible: no --- docs/reviews/SPEC-REVIEW-500-r3.md | 182 +++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-500-r3.md diff --git a/docs/reviews/SPEC-REVIEW-500-r3.md b/docs/reviews/SPEC-REVIEW-500-r3.md new file mode 100644 index 00000000..3ec7189c --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-500-r3.md @@ -0,0 +1,182 @@ +# 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