mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,116 @@
|
||||
# SPEC-REVIEW-249-r2
|
||||
|
||||
- Issue: [#249](https://github.com/Matysh/houseplan-card/issues/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**
|
||||
Reference in New Issue
Block a user