Files
houseplan-card/docs/reviews/SPEC-REVIEW-277-r2.md
T
2026-08-24 06:31:15 +03:00

14 KiB
Raw Blame History

SPEC-REVIEW-277-r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/277
  • Этап: ТЗ на ревью (PROCESS.md §2.4)
  • Заход: r2 · блокирующих циклов израсходовано 1 из 4
  • Документ ТЗ: docs/specs/277-safe-resize.md
  • HEAD ревью: 4ed94a52c9eaaf062ab033f6325e4bee8964bb41

Скоуп раунда

r2 — не полный повторный разбор, а разбор по дельте (PROCESS.md §2.10, issue #214).

  1. Вердикт r1: жёлтый · High 0 · Medium 3 (M1, M2, M3), опубликован в docs/reviews/SPEC-REVIEW-277-r1.md, комментарий https://github.com/Matysh/houseplan-card/issues/277#issuecomment-5389 (id IC_kwDOTOcLQM8AAAABQUJ7Dw).
  2. SHA r1 не назван в вердикте — это находка процесса, зафиксирована ниже как L1. Восстановлен по дереву: последний коммит спеки перед коммитом ревью-документа — 6436eafb3022bb53e58c6f89bdf7be53b16ce052 («docs: specify safe fixed-topology resize», 2026-08-24 04:50:51+03:00); ревью-документ docs/reviews/SPEC-REVIEW-277-r1.md добавлен отдельным коммитом 4a16ddeb в 01:59:09 UTC того же дня. Значит r1 разобран на 6436eafb.
  3. Дельта: git diff 6436eafb..4ed94a52 -- docs/specs/277-safe-resize.md — единственный коммит 4ed94a52 («docs: address safe resize spec review»), 31 добавленных строки, 0 удалённых, правки только в docs/specs/277-safe-resize.md. Диапазон затронутых участков: новый подраздел «Что человек увидит до и после» в §1, новый раздел «12.1. Риски и меры», новый AC17 и три новых пункта плана тестов в §16, новый пункт 6 в §18 «Принятые технические предположения».
  4. Не тронуто дельтой: §2 (решения владельца, Q1/Q2), §3–§11 (термины, eligibility, non-shared/shared transform, stops, preview/commit, удаляемое поведение, скоуп/не-скоуп), §12 (архитектура, без счёта рисков), §13–§15 (перформанс, touch, AC1–AC16 кроме новой AC17), §17 (release- артефакты/rollback). Класс изменения — C (docs/**), диапазон не задевает src/**, поэтому дешёвые гейты (typecheck/test/build) и check-docs не запускались — как и в r1, ровно по тому же основанию (диф не содержит кода).

Дельта локальна (не ребейз на ушедший вперёд dev, не смена контракта поведения, не новая подсистема, объём — 31 строка против 322 исходных) — полный повторный разбор не требуется по правилу §2.10 «разбор остаётся полным, если...». Разбирались только: (а) закрытие M1–M3 построчно, (б) все AC/разделы, которые дельта физически задевает — §1 сценарий, §12.1, AC17, §16, §18.

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

Находка r1 Чем закрыта Где это видно
M1 — нет раздела «риски», не назван риск параллельной работы над #264/#276/#278 Добавлен раздел «## 12.1. Риски и меры» — таблица из 10 строк риск/мера. Отдельно назван риск #264 («второй controller boundary») с мерой «#264 не начинается параллельно, после #277 обязан rebase и refactor-only parity» и риск #276/#278 («меняют соседние geometry helpers») с мерой «порядок merge #276 → #277 → #278». docs/specs/277-safe-resize.md:252-265
M2 — нет фразы «что человек увидит до/после» без терминов реализации; §1 целиком на терминах room polygon/vertex/segment Добавлен подраздел «### Что человек увидит до и после» с двумя пользовательскими предложениями («До: … стена может стать визуально толще или тоньше…»; «После: выбранная стена двигается, а всё остальное на плане остаётся как было; … стена видимо упирается…»). Формулировка почти буквально повторяет пример из вердикта r1. docs/specs/277-safe-resize.md:29-36
M3 — из «Обязательных тестов» issue выпал пункт про анонимизированную before/after fixture реального плана; ни один AC на него не ссылался Добавлен AC17 (fixture provenance test + production-bundle smoke + model invariants), три новых пункта плана тестов про test/fixtures/resize-safe-regression.json (минимизация/анонимизация, provenance-комментарий, smoke проигрывает исходную последовательность жестов, а не подставляет готовый after), новая строка риска в §12.1 («Thickness/open spans расходятся при переносе… реальная fixture AC17») и новый пункт 6 в §18, явно решающий, как реальная fixture попадает в репозиторий без утечки пользовательских данных. docs/specs/277-safe-resize.md:261, 284-320, 352-353 (AC17: строка 304)

Все три Medium закрыты по существу, а не декларативно: каждая правка — новый текст, читаемый построчно, а не ссылка на намерение автора.

Находки нового раунда

L1 (Low, снята с записью). Новое пользовательское предложение из M2 («…и рядом с её handle написана причина», docs/specs/277-safe-resize.md:36) использует непереведённое handle в ровно том месте, которое по требованию AGENTS.md/PROCESS §7.1 должно быть «одной фразой без терминов реализации». docs/USER-GUIDE.ru.md уже знает русский термин для точно такого UI-элемента — «ручка» (угловые/поворотные ручки подложки и линии, docs/USER-GUIDE.ru.md:1133,1138,1161,1203), а «маркер» в этом документе занят под значок устройства (docs/USER-GUIDE.ru.md:60 и далее) и был бы двусмысленным выбором. Слово handle в технических разделах (§2, §4) не проблема — это внутренний рабочий термин спеки, ровно как и в r1, где терминология была сверена с RESIZE.md и признана согласованной. Проблема только в новой пользовательской фразе.

Не блокирует: единственное слово, не меняет ни один AC и не создаёт неоднозначности пользовательского сценария — оба соседних предложения того же абзаца уже сформулированы по-русски и понятны без перевода термина. Снимаю Low с записью: при следующей правке файла заменить handle на ручка (или иной согласованный с USER-GUIDE.ru.md термин) в пользовательском абзаце; блокирующего цикла ради одного слова не открываю.

L2 (Low, процессная, снята с записью). Вердикт r1 не называл SHA, на котором получен (см. п.2 «Скоуп раунда» выше) — ровно тот случай, который PROCESS.md §2.10 прямо называет находкой. Восстановлен однозначно по времени коммитов, дельта от восстановленного SHA не оставляет разночтений, отдельного возврата не требует. Отмечаю для инфраструктурного шага публикации: вердикт код/спец-ревью должен называть SHA явно.

Ни одной находки, задевающей продуктовое поведение, AC или проверяемость, в дельте не найдено.

Что проверено и корректно (сверх закрытия r1)

  • AC17 однозначен и проверяем: падение теста возможно (не сохранены walls/ extras/openings либо global wall-null — конкретные, механически проверяемые инварианты), способ доказательства назван (fixture provenance test + production-bundle smoke + model invariants), нет догадки, выданной за решение — двойной исход «либо безопасно завершает жест, либо clamp/disabled» сознательно оставлен открытым, потому что сама природа воспроизводимого бага (старый Resize допускал небезопасный ход) не позволяет заранее утверждать, какой из двух исходов даст новый безопасный контракт именно на этой fixture — и это явно не продуктовый вопрос, а технический, решённый автором, не переброшенный владельцу.
  • §18 п.6 корректно ставит границу «assumed, change freely»: реальная fixture обязательна, но публикуется только после минимизации/анонимизации — это прямое согласие с телом issue («Реальный экспорт исследован локально и не публикуется из-за пользовательских данных») и не оставляет открытого продуктового вопроса.
  • Риск-таблица §12.1 не расходится с §18 п.5 и с телом issue: порядок «#276 → #277 → #278» упомянут дважды одинаково, никакой новой зависимости от #264 не введено (наоборот, зависимость явно исключена).
  • Новый текст не расширяет и не сужает скоуп/не-скоуп (§10/§11 не менялись), не переопределяет ни одного из AC1–AC16, не противоречит решениям владельца по Q1/Q2 (§2, не тронуто дельтой).

Унаследовано из r1

Разделы, которые дельта не затронула, и AC, чьё доказательство дельта не меняет, приняты без повторной проверки в этом раунде — на основании docs/reviews/SPEC-REVIEW-277-r1.md, разобранного на SHA 6436eafb:

  • Q1/Q2 (§2) закрыты точно по решению владельца, без угадывания.
  • AC1–AC16 однозначны, у каждого указан способ доказательства.
  • Технические ссылки на текущий код (applyRoomScale, clampRoomScale, shiftSharedSpans, _rszApplyPreview, src/plan-geometry-preflight.ts из #199) подтверждены в дереве.
  • Терминология §3–§12 согласована с RESIZE.md/WALL-THICKNESS.md/ CANVAS.md/UX-MODES.md.
  • Скоуп/не-скоуп (§10/§11) корректно разграничивают #277 от #253/#264/#276/ #278.
  • Откат и release-артефакты (§17) описаны полно.
  • Математическая полнота формул safe range (§3, §7) не разбиралась построчно ни в r1, ни в r2 — по-прежнему предмет код-ревью, когда появятся тесты на конкретных fixtures; дельта r2 эти разделы не трогала.

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

  • Гейты (typecheck/test/build/check-docs/model-invariants) — диф класса C, только docs/specs/277-safe-resize.md, кода нет; то же основание, что и в r1.
  • Реальный воспроизводящий экспорт — не публикуется по условиям issue, как и в r1.
  • Полный повторный разбор §3–§11, §13–§15 — не требуется правилом «разбор по дельте», дельта не задевает их доказательство (см. «Унаследовано из r1»).

Вердикт

Зелёный. 0 High, 0 Medium. Обе оставшиеся находки — Low, сняты с записью выше, без открытия нового блокирующего цикла.