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

16 KiB
Raw Permalink Blame History

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