Files
houseplan-card/docs/reviews/SPEC-REVIEW-249-r2.md
T
2026-08-23 03:47:19 +00:00

12 KiB
Raw Blame History

SPEC-REVIEW-249-r2

  • Issue: #249 — «Стык трёх стен разной толщины рисуется шипом наружу вместо соединённого узла»
  • ТЗ: docs/specs/249-multiwall-junction-bevel.md, ветка issue/249-multiwall-junction-bevel, коммит 675294b9a0c62fb412220bdc04194f6eabedc0c4
  • Этап: spec (PROCESS.md §2.4), заход r2, блокирующих циклов израсходовано 1 из 4
  • Трек: обычный (не small) — файл в docs/specs/ существует
  • Вердикт: зелёный

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

Предыдущий вердикт найден в комментарии issue от claude (2026-08-23T02:18:27Z): жёлтый, заход r1, High 0 / Medium 2 (M1 — отсутствует раздел «Риски», M2 — внутреннее противоречие mitre/bevel в §7.2). SHA, на котором получен вердикт r1, в самом вердикте не назван — это находка процесса r1, а не r2; я восстановил его по цепочке коммитов: документ ревью 748d484 («review document for #249») зафиксировал docs/reviews/SPEC-REVIEW-249-r1.md с явной строкой «ТЗ: … коммит 8d2e00bbbfbb9151ca2079eaf6e51f916cb59eff», и по времени (8d2e00b — 05:07:48, вердикт — 02:18:27 UTC = 05:18:27 MSK, 748d484 — 05:18:37 MSK) это единственный кандидат. Далее — SHA r1.

Дельта раунда: git diff 8d2e00b..675294b -- docs/specs/249-multiwall-junction-bevel.md. Дельта локальна: изменена статусная строка шапки, переписан §7.2 (пункты 1–2, добавлены пункты 3–4), добавлен новый раздел 11 «Риски и меры снижения» (R1–R5), старые §11 «Откат» и §12 «Предположения» сдвинуты на §12/§13. Ни сценарий, ни AC, ни scope/не-scope, ни термины §6, ни §7.1/7.3/7.4/7.5, ни раздел 10 не тронуты. Смены контракта поведения, ребейза или новой подсистемы нет — правило mitre/bevel то же самое (d <= R → митра, d > R → фаска), неоднозначная полоса убрана, а не расширена. Поэтому разбор — по дельте, не заново.

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

Находка r1 Чем закрыта Где это видно
M1 — обязательный раздел «Риски» отсутствовал полностью Добавлен раздел 11 «Риски и меры снижения» с пятью пунктами (R1 blast radius T-стыков, R2 щель/ложная кладка, R3 порядок/winding/scale, R4 boolean-ошибка, R5 перформанс), каждый с явной митигацией docs/specs/249-multiwall-junction-bevel.md:297-350 (см. git diff 8d2e00b..675294b, добавленные +### R1. … +### R5.); R1 прямо называет тот самый риск, что был предметом M1: «Сегодня визуально приемлемая митра в диапазоне (1.25×H, 4×H] станет фаской… изменение может затронуть golden-сценарии, не связанные с #249», митигация — обязательный полный golden:verify перед бетой с просмотром всех изменённых кадров, а не только нового crop
M2 — правила §7.2.1/7.2.2 противоречили друг другу в полосе (R, R+epsilon] Оба правила переписаны на единственную границу R: п.1 «остаётся митрой, если его конечное расстояние от node d <= R», п.2 «если пересечения нет, оно не конечное либо d > R — фаска». Добавлен явный п.3: «epsilon не расширяет область выбора митры: branch decision всегда разделён единственной границей R. Допуск epsilon используется только при проверке и сравнении уже вычисленных floating-point координат» docs/specs/249-multiwall-junction-bevel.md:138-151; выбран ровно вариант закрытия, предложенный r1 («либо оба правила используют R, а epsilon остаётся только допуском сравнения»)

Оба закрытия проверены по тексту диффа, не по заявлению автора комментария.

Побочная проверка: делает ли фикс M2 что-то ещё непоследовательным

§7.5 «Ошибки и fallback» (не тронут дельтой) уже содержал формулировку «если точная митра не укладывается в R, результатом служит фаска» — то есть до фикса M2 этот раздел молчаливо предполагал границу R, а §7.2 колебался между R и R+epsilon. Новая редакция §7.2 приводит оба места к одному порогу без дополнительной правки §7.5 — расхождение снято, а не создано новое. AC1 (§9, не тронут) по-прежнему использует 1.25×H + epsilon как допуск проверки результата (п.4 нового §7.2), а не как границу branch decision — противоречия между AC1 и переписанным §7.2 нет.

Внутренние перекрёстные ссылки (§7.5, §8 — единственные, что встречаются в тексте документа) не задеты сдвигом нумерации §11→12, §12→13; проверено grep -n "§[0-9]" по всему файлу.

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

Без повторной проверки в этом раунде приняты выводы docs/reviews/SPEC-REVIEW-249-r1.md (коммит ТЗ 8d2e00b, документ опубликован коммитом 748d484):

  • сценарий и соответствие J1 (docs/SCOPE.md);
  • подтверждение корневой причины по коду на HEAD (MITRE_LIMIT = 4 в src/wall-thickness.ts:46, независимые митры двух комнат в insetContour()/outsetContour(), строки 1030/2238/701/1853; wall-merge.ts junctionAt()/spaceMergeGeometry() действительно не формируют этот узел);
  • согласованность чисел H = 4.8611, спайк 8.7312 ≈ 1.80×H;
  • перенос решений владельца Q1/Q2 в §4 без искажений;
  • Scope/не-scope §5;
  • термины §6 (ray, node, join vertex), обоснованные кодом (Math.max при слиянии дублей, строка 626);
  • полнота и проверяемость AC1–AC7 (таблица AC из r1) — дельта их текст не меняла;
  • соответствие терминологии docs/USER-GUIDE.ru.md («стык», «митра/фаска»);
  • Low-находка о нестандартной структуре заголовков — принята как снятая ревьюером r1 без требования правки, автор её и не трогал.

Эти пункты не переверялись повторно, так как дельта r2 их не касается.

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

  • DoR-чеклист §2.5 PROCESS.md: «риски перечислены» и «открытых продуктовых вопросов нет» — оба условия теперь выполнены (риски — новый §11; открытых вопросов в тексте r2 не появилось, оба Q1/Q2 остались решёнными в §4).
  • Новый раздел рисков внутренне согласован с остальным ТЗ: R1↔AC3 (двухлучевые expected values не меняются), R2↔AC1/AC2 (ненулевая связность, отсутствие hole), R3↔AC2 (матрица permutation/winding/coordScale=1000), R4↔§7.5 и regression #197, R5↔§8 (O(E)/O(E log E)) и обязательный предрелизный performance smoke. Ни один риск не изобретён — все пять уже фигурировали как отдельные абзацы аналитики/issue до этого ТЗ (см. первый комментарий владельца в issue: «Риск: 6/10… ошибка способна дать щель, лишнюю кладку либо изменить обычные двухлучевые углы»), r2 их структурировал под требуемый раздел, а не придумал заново.
  • Тонкая граница d <= R вместо d <= R + epsilon не расширяет, а сужает зону неоднозначности до нуля — это не новый риск детерминизма, а устранение единственного такого риска, названного в M2.

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

  • Не запускал typecheck/test/build — класс A (src/**) в дельте r1→r2 не менялся, дифф ограничен docs/specs/249-multiwall-junction-bevel.md.
  • Не переисполнял AC1–AC7 (соответствующих файлов тестов/smoke/fixture ещё не существует — ожидаемо для этапа ТЗ, будет предметом код-ревью).
  • Не проводил повторный полный разбор сценария, root cause, scope и терминов — см. раздел «Унаследовано из r1»: делта их не касается, значит не задевает и их доказательства.

Итог

Обе Medium-находки r1 закрыты точечно и именно так, как предлагало ревью: раздел «Риски» добавлен по существу (не формальная заглушка — пять пунктов с митигациями, согласованных с остальным ТЗ), а противоречие mitre/bevel снято единой границей R с epsilon только как допуском проверки. Дельта раунда локальна, не затрагивает AC/scope/термины и не создаёт нового расхождения. Открытых High/Medium находок нет.

Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0