From 8b227962b1b31b99f426b8571d1ed4d24bb6e931 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 02:06:48 +0000 Subject: [PATCH] docs: review document for #277 Issue: #277 User-Visible: no --- docs/reviews/SPEC-REVIEW-277-r2.md | 148 +++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-277-r2.md diff --git a/docs/reviews/SPEC-REVIEW-277-r2.md b/docs/reviews/SPEC-REVIEW-277-r2.md new file mode 100644 index 00000000..a4b416fe --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-277-r2.md @@ -0,0 +1,148 @@ +# 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, сняты с записью +выше, без открытия нового блокирующего цикла.