mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
committed by
Sergey Matyunin
parent
154af2692f
commit
ffbbb217b5
@@ -0,0 +1,126 @@
|
||||
# SPEC-REVIEW-271-r1
|
||||
|
||||
Issue: #271 — «Degree-3 узел достраивает короткий луч до 8×H и рисует несуществующую стену и тень»
|
||||
Этап: spec (PROCESS.md §2.4)
|
||||
Заход: r1 · блокирующих циклов израсходовано 0 из 4
|
||||
ТЗ: `docs/specs/271-finite-multiwall-rays.md`, SHA `482b2be512b38cadb40855b79b710f6602d5eb54`
|
||||
|
||||
## Скоуп разбора
|
||||
|
||||
Первый заход — разбор полный. Проверено: `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md`
|
||||
(включая §2.4, §7.1, §4), тело issue #271 и оба комментария (аналитика +
|
||||
«ТЗ готово к ревью»), канонический `docs/WALL-THICKNESS.md`, сам ТЗ, исходный код
|
||||
`src/wall-thickness.ts` (интерфейс `MultiWallNodeRay`, `buildMultiWallNodeMap`,
|
||||
`bevelMultiWallBody`, константы `MITRE_LIMIT`, `MULTI_WALL_JOIN_LIMIT`), связанные
|
||||
issue #249/#261/#270/#272/#273 (заголовки и статусы — все закрыты либо остаются
|
||||
открытыми отдельными задачами, ни одна не дублирует #271).
|
||||
|
||||
## Как проверялось
|
||||
|
||||
1. Сверил числа из таблицы issue/ТЗ (реальная длина луча vs. текущий rebuild) с
|
||||
формулой в коде: `radius = MITRE_LIMIT * node.halfDepth + eps*2`,
|
||||
`extent = radius * 2` (`src/wall-thickness.ts:2032-2033`) — при `MITRE_LIMIT=4`
|
||||
это ровно `8×halfDepth`. Пример узла 2 `(2404.167, 1245.833)`: `H=62.5` →
|
||||
`8×62.5=500.000`, совпадает с «Текущий rebuild» в таблице ТЗ. Формула и цифры
|
||||
не выдуманы, а прослеживаются до реального кода.
|
||||
2. Проверил, что `MultiWallNodeRay` (`src/wall-thickness.ts:51-54`) действительно
|
||||
хранит только `{u, halfDepth}` без длины — корневая причина, заявленная в §3
|
||||
ТЗ, подтверждена чтением, не только цитированием issue.
|
||||
3. Сверил каждый обязательный раздел ТЗ с перечнем PROCESS.md §7.1: сценарий,
|
||||
что человек увидит, проблема, скоуп/не-скоуп, контракт, UX, модель
|
||||
данных/миграция, i18n, AC1…ACn с доказательством, план автотестов, риски,
|
||||
откат, release-артефакты — присутствуют все.
|
||||
4. Прочитал все девять AC на однозначность и способ доказательства; для каждого
|
||||
проверил, что критерий формулирует наблюдаемое условие (геометрия/присутствие
|
||||
material), а не расплывчатое «стало лучше».
|
||||
5. Проверил список «не входит» (§5) против реально открытых соседних issue
|
||||
(#272 — белые треугольные дыры вне probe #261; #273 — sub-grid островок при
|
||||
Optimize) — границы скоупа корректны, чужого не захватывают.
|
||||
6. Проверил путь ТЗ (`docs/specs/271-finite-multiwall-rays.md`) — issue не
|
||||
помечен `small`, файл обязателен и создан по имени `<NN>-<slug>.md`, что
|
||||
соответствует правилу.
|
||||
7. Проверил, что упомянутые файлы существуют: `test/wall-thickness.test.mjs`,
|
||||
`docs/ARCHITECTURE.md`, `docs/TESTING.md`, `docs/CONFIG-COMPATIBILITY.md` —
|
||||
все на месте, ссылки не битые.
|
||||
|
||||
Гейты кода в этом раунде не гоняются — стадия spec, продуктовый код не менялся
|
||||
(единственный коммит раунда — `docs(spec): ...`, класс C). `npm test`/`typecheck`
|
||||
/`build` не относятся к предмету ревью ТЗ и не запускались.
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. Ни одной High или Medium находки — ни в скоупе, ни вне его.
|
||||
|
||||
Разобрано отдельно и отклонено как находка:
|
||||
- **Полнота списка документации (§9).** ТЗ включает `docs/USER-GUIDE.md` /
|
||||
`docs/USER-GUIDE.ru.md` в список документов на обновление, хотя пользователю
|
||||
не добавляется ни один новый видимый термин или контрол. Это не дефект: раз
|
||||
видимая геометрия меняется (`User-Visible: yes` в §10), а требование
|
||||
AGENTS.md — обновлять UI-терминологию из USER-GUIDE при изменении видимого
|
||||
поведения — включение файла в список консервативно и не создаёт риска;
|
||||
решение оставить формулировку в тексте или сократить список — на усмотрение
|
||||
автора при реализации, Low, не фиксирую отдельно.
|
||||
- **Отсутствие имени конкретного нового smoke-файла в AC4/AC5.** Смок ещё не
|
||||
существует (создаётся в реализации), поэтому называть файл в ТЗ не требуется —
|
||||
PROCESS.md §7.1/2.5 просит указать *категорию* доказательства (`smoke`), а не
|
||||
имя ещё не написанного файла. Не находка.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- **Корневая причина** (§3 ТЗ) совпадает с кодом посимвольно: `MultiWallNodeRay`
|
||||
теряет длину, `bevelMultiWallBody` перестраивает луч на `8×H`. Не догадка —
|
||||
прослежено до строк кода.
|
||||
- **Сценарий и персона** (§1): администратор нажимает Optimize → Plan/View,
|
||||
видит несуществующую стену/тень — прямая связь с J1 («правдиво показывать
|
||||
дом») и J6 (одна геометрия для всех потребителей), обе строки есть в
|
||||
`docs/SCOPE.md`.
|
||||
- **Скоуп/не-скоуп** (§5) явно исключает соседние открытые дефекты (#272 белые
|
||||
дыры, #273 sub-grid островок, форма #249 bevel, `MITRE_LIMIT`/
|
||||
`MULTI_WALL_JOIN_LIMIT`) — задача не разрастается на смежные баги.
|
||||
- **Контракт §6** формулирует финитность луча через проверяемые условия:
|
||||
локальная полоса существует только на `t ∈ [0, length]`; правило дедупликации
|
||||
co-directional дубликатов явно запрещает «перекрыть зазор» присутствием
|
||||
соседнего короткого/толстого дубликата (типичная ловушка, которую легко
|
||||
упустить) — прямо закрыто текстом контракта.
|
||||
- **AC1-AC9** — каждый формулирует наблюдаемое состояние геометрии
|
||||
(присутствие/отсутствие material в конкретной точке, конкретные числа
|
||||
`20.833 → не 500`, `12.5 → не 110`) и называет способ доказательства (unit /
|
||||
geometry unit / targeted smoke / golden semantic probe / mutation). AC7
|
||||
отдельно требует, чтобы мутант **уронил** AC2 или AC4 — то есть тест на
|
||||
фальсифицируемость заложен в само ТЗ, а не оставлен на усмотрение код-ревью.
|
||||
- **Технические предположения (§13)** помечены явно как «assumed, change
|
||||
freely» и действительно являются техническими (внутреннее представление
|
||||
finite support), а не спрятанным продуктовым решением. Предположение про
|
||||
`wall_columns` унаследовано от собственного анализа владельца в комментарии
|
||||
аналитики, а не изобретено автором ТЗ.
|
||||
- **Совместимость/UX/perf/touch** (§7): персистентная модель не меняется,
|
||||
миграции нет, новых контролов/i18n/HA-вызовов нет, touch явно назван («новых
|
||||
keyboard/touch/focus/ARIA... нет»), perf ограничен явным запретом нового
|
||||
глобального `O(E²)` прохода.
|
||||
- **Откат (§12)** запрещает частичный откат только тестов — учтён урок, из-за
|
||||
которого регрессия становится снова невидимой.
|
||||
- Продуктовых вопросов владельцу нет и не должно быть: единственное решение
|
||||
задачи («физическое тело не может продолжаться дальше конца отрезка») уже
|
||||
прямо следует из J1 и не требует выбора между персонами или трактовки
|
||||
пограничного случая.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Не проверял реализацию (её нет — это стадия spec, код не менялся).
|
||||
- Не прогонял `typecheck`/`test`/`build`/`check-docs` — не относится к этому
|
||||
этапу, диапазон изменений раунда состоит из одного документного коммита.
|
||||
- Не воспроизводил приватные `1.json`/`2.json` владельца — они не в репозитории
|
||||
по правилу «не коммитить пользовательские данные»; проверка ограничилась
|
||||
числами, которые ТЗ и issue цитируют, и сверкой формулы в коде.
|
||||
- Не оценивал, оптимальна ли выбранная будущая технической реализация
|
||||
(union конечных spans vs. clipped polygon) — это по §13 оставлено автору
|
||||
реализации и будет предметом код-ревью.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Все обязательные разделы (PROCESS.md §7.1) присутствуют, каждый AC однозначен и
|
||||
называет способ доказательства, корневая причина подтверждена чтением кода, а
|
||||
не выдана за факт без опоры. Открытых продуктовых вопросов нет и не должно
|
||||
быть.
|
||||
|
||||
**Зелёный.**
|
||||
Reference in New Issue
Block a user