Files
houseplan-card/docs/reviews/SPEC-REVIEW-282-r2.md
2026-08-26 02:20:57 +03:00

16 KiB
Raw Permalink Blame History

SPEC-REVIEW-282-r2

Скоуп ревью r2 — по дельте (PROCESS.md §2.10)

Между 8856fbda и 2f30c481 изменён только docs/specs/282-stable-wall-segment-identity.md (git diff 8856fbda..HEAD --stat: 37 строк в одном файле; второй файл в diffstat — сам docs/reviews/SPEC-REVIEW-282-r1.md, зафиксированный шагом публикации, не автором ТЗ). Продуктовый код (src/**, custom_components/**) не тронут — его для #282 всё ещё нет. Изменение целиком является прямым ответом на M1/M2 из r1: не рёбейз, не смена контракта, не новая подсистема, объём дельты (37 строк из 663) несопоставим с объёмом задачи. Полный разбор ТЗ заново не требуется — разбирается дельта плюс AC, которых она касается (AC1), остальное наследуется из r1 без повторной проверки.

Как проверялось

  1. Найден вердикт r1 и SHA, на котором он получен (8856fbda, указан в шапке SPEC-REVIEW-282-r1.md — в отличие от типового риска этого пункта, здесь SHA был назван явно, задача «найти SHA» тривиальна).
  2. Объявлена дельта: git diff 8856fbda..HEAD — построчно прочитан весь diff docs/specs/282-stable-wall-segment-identity.md (7 хансов).
  3. По каждой находке r1 (M1, M2) проверено, чем именно она закрыта — конкретной строкой изменённого текста, а не комментарием автора «исправлено» (комментарий issue #282 от Matysh, 2f30c48, только заявляет закрытие; настоящая проверка — ниже).
  4. Прочитан целиком раздел «§7 Атомизация и deterministic migration v7 → v8» (включая нетронутый §7.2) и «§9 Writers и единый identity barrier» в текущей редакции — чтобы убедиться, что новое определение exact в §7.1 корректно распространяется на §7.2, который сам не редактировался.
  5. Перечитан AC1 целиком (единственный AC, чей текст изменён) на предмет однозначности и проверяемости после правки.
  6. Проверена терминология нового i18n/UX-текста против источника интерфейса (PROCESS.md требует брать термины из docs/USER-GUIDE.ru.md, не изобретать): grep по src/i18n/ru.json подтвердил gs.align_all/gs.align_title = «Оптимизировать планы» — тот же лейбл, что и в новом тексте тоста и в §2; docs/USER-GUIDE.ru.md:998 (backup.preserved_unresolved_hint) уже использует ровно ту же конструкцию «запустите «Оптимизировать планы»» — формулировка не придумана, а повторяет существующий паттерн продукта.
  7. Проверено, что дельта не расширяет скоуп и не меняет контракт вне того, что закрывают M1/M2 (§4/§5/§6/§8/§10/§13/§14 кроме AC1/§15–§19 кроме п.5 не тронуты).

Закрытие раунда r1

Находка r1 Чем закрыта Где это видно
M1 (Medium) — не специфицирован порядок атомизации Stage 1 относительно lattice-барьера #291, и какой из двух существующих допусков (1e-4 vs max(pitch·10⁻⁶,10⁻⁹)) применяется §7.1 получил абзац: канонизация #291 запускается до breakpoint-вычисления и до любых v8 ID/ref; порог принадлежит только #291 (LATTICE_NOISE_STEPS = 1e-4); слово exact везде в §7 означает побитовое равенство уже канонизированных координат; третий допуск не вводится. §9 добавил тот же порядок в описание barrier-пайплайна («сначала… canonicalizeConfigGeometry #291, затем… commitWallSegmentModel», «одна атомарная commit-транзакция»). §19 п.5 повторяет то же для момента миграции. AC1 расширен явным требованием: fixtures с шумом по обе стороны порога дают byte-equivalent v8 candidate, шум внутри порога канонизируется и не создаёт micro-segments, координата вне порога не схлопывается молча. docs/specs/282-stable-wall-segment-identity.md:199-205 (§7.1), :333-338 (§9), :655-657 (§19 п.5), :439-445 (AC1)
M2 (Medium) — §2/§11 обещают тексту тоста конкретный совет («Optimize либо исправление»), но toast.wall_model_migration_blocked в §12 не содержал никакого действия §2 переформулирован под фактический текст: «предлагает сначала запустить «Оптимизировать планы», а при повторном отказе — исправить конфликтующую геометрию стен». §12 переписан в обе стороны (RU/EN): toast.wall_model_migration_blocked теперь буквально содержит «Запустите «Оптимизировать планы»; если ошибка повторится, исправьте конфликтующую геометрию стен.» / «Run "Optimize plans"; if the error repeats, fix the conflicting wall geometry.» — текст §2 и текст ключа теперь описывают одно и то же действие в одном порядке. docs/specs/282-stable-wall-segment-identity.md:32-34 (§2), :412 (§12, таблица i18n)

Обе находки закрыты текстом, а не заявлением: конкретные строки процитированы выше и прочитаны целиком в контексте (см. «Как проверялось», пп. 3–4).

Дополнительная проверка терминологии (не отдельная находка, часть проверки закрытия M2)

Новая формулировка «Оптимизировать планы» — не изобретённый ревьюером или автором термин: это точное название существующей кнопки (gs.align_all/gs.align_title, src/i18n/ru.json:807-808) и уже употреблённый в docs/USER-GUIDE.ru.md:998 паттерн «запустите «Оптимизировать планы»» для родственного случая (нерешённые ссылки после импорта). Правка M2 не только закрывает находку, но и делает это в терминах, которые уже существуют в продукте — соответствует требованию PROCESS.md брать терминологию интерфейса из USER-GUIDE.ru.md, а не изобретать.

Что переразобрано в этом раунде (AC, которых касается дельта)

  • AC1 — единственный AC с изменённым текстом. Новая формулировка добавляет случай lattice-noise по обе стороны порога #291 к уже существующему списку fixture-классов (outer/shared/partial-overlap/T/X/diagonal/open span/key-only/exact walls). Критерий остаётся однозначным и проверяемым тем же способом доказательства (TS migration unit matrix + golden/static path comparison + backend fixture parity): для шума ниже 1e-4 ожидается, что после канонизации #291 атомизация не порождает лишних микросегментов; для расхождения выше порога — coordinate не схлопывается. Оба утверждения формулируются как конкретные fixture-проверки (сравнение catalog до/после на данных внутри/вне порога), а не как качественное пожелание — критерий выполнимости не потерян правкой.
  • Остальные AC2–AC17 текстуально не изменились дельтой; их доказательство не зависит от порядка canonicalization/atomization (эта деталь относится только к самому механизму миграции, не к результату, который проверяют AC2 и далее) — повторный разбор не требуется, см. «Унаследовано» ниже.

Унаследовано из r1 (без повторной проверки)

Всё нижеперечисленное принято из docs/reviews/SPEC-REVIEW-282-r1.md на SHA 8856fbda, так как дельта r1→r2 их текста и логики не касается:

  • Соответствие docs/SCOPE.md/J6, отсутствие расширения UX/новой функциональности — §4/§5 не изменены дельтой.
  • Продуктовые разделы §1 «Сценарий» и §2 «Что человек увидит» присутствуют и различимы (PROCESS.md §7.1); §2 в этом раунде получил только точечную правку текста тоста-совета (см. M2 выше), структура и персона не менялись.
  • Построчная сверка фактических утверждений ТЗ о текущей модели (v7, MAX_ROOMS/MAX_POLY_POINTS=200000, host?: {kind:'partition',...}, wallKey/rekeyWallsAfterMove/exactCoveringWall/edgeKinds/sharedSegsOf/atomicPolyForRoom, существование src/coordinate-canonicalization.ts/canonicalizeConfigGeometry/LATTICE_NOISE_STEPS, существование скриптов config-field-registry.mjs/model-invariants.mjs/mutation-gate.mjs/smoke-select.mjs, i18n-префиксы toast.*/gs.*) — код в этих частях не менялся между r1 и r2, повторная сверка не требуется.
  • AC2–AC17 однозначны и проверяемы, каждый называет способ доказательства — текст этих AC не изменён дельтой.
  • Не-скоуп (§5) корректно ограничивает риск, держит границу Stage 1 против Stage 2–4 — не изменён.
  • Откат и release-артефакты (§17–18) реалистичны — не изменены.
  • Ссылки на существующий тулинг и гейты (§10.4, §17) верны — не изменены.
  • «Чего не проверял» из r1 (ARCHITECTURE.md/CANVAS.md/UX-MODES.md/TOUCH-SUPPORT.md целиком; история регрессионных issues из AC12 построчно; typecheck/test/build — кода нет; вероятность hash-коллизии §7.3 математически) — основания этих пропусков не изменились дельтой, пропуски наследуются на тех же условиях.

Чего не проверял в r2

  • Не перечитывал целиком ADR docs/adr/282-wall-geometry-representation.md заново — дельта его не касается, а r1 уже подтвердил соответствие ТЗ этому ADR.
  • Не гонял npx tsc --noEmit/npm test/npm run build — дельта не касается ни одного файла класса A/B (только docs/specs/*.md, класс C), продуктового кода для #282 по-прежнему нет; гонять эти гейты в этом раунде нечего.
  • Не проверял математически вероятность hash-коллизии §7.3 — не тронуто дельтой, унаследовано из r1.
  • Не проверял согласованность нового текста тоста (M2) с фактическими лимитами длины UI-тоста/типографикой — это находится за пределами ТЗ-ревью (вопрос реализации/визуального QA на этапе код-ревью), а не критерий выполнимости ТЗ.

Вердикт

Обе Medium-находки r1 закрыты точечными, проверяемыми правками текста: M1 — явным порядком «канонизация #291 → атомизация» и запретом третьего допуска, с расширением AC1 под fixture с шумом по обе стороны порога; M2 — синхронизацией текста §2/§11 с фактическим i18n-ключом, использующей существующую терминологию интерфейса, а не изобретённую. Новых High- или Medium-находок дельта не создала. Дельта локальна (только текст ТЗ, 37 строк), полного повторного разбора не требует.

Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0 · Документ: docs/reviews/SPEC-REVIEW-282-r2.md