mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,145 @@
|
||||
# SPEC-REVIEW — issue #209 · заход r1
|
||||
|
||||
- Этап: spec (PROCESS.md §2.4)
|
||||
- Артефакт ТЗ: `docs/specs/209-vacuum-trail-smoothing.md` (SHA `43516cc1`, ветка `issue/209-vacuum-trail-smoothing`)
|
||||
- Вердикт: **зелёный**
|
||||
- Блокирующих циклов израсходовано: 0 из 4
|
||||
|
||||
## Скоуп ревью
|
||||
|
||||
Первый раунд, дельта не применяется (§2.9 — правило дельты действует только
|
||||
для r2+). Разобрано полностью:
|
||||
|
||||
1. Тело issue #209 и все 3 комментария (анализ Codex, два решения владельца,
|
||||
финальная передача на ревью).
|
||||
2. Полный текст `docs/specs/209-vacuum-trail-smoothing.md`.
|
||||
3. `docs/SCOPE.md` — соответствие Core user jobs.
|
||||
4. `PROCESS.md` §2.4, §7.1 — обязательные разделы ТЗ и порог продуктовых
|
||||
вопросов.
|
||||
5. `docs/VACUUM.md`, `docs/USER-GUIDE.ru.md` (раздел «Позиция и путь»),
|
||||
`docs/USER-GUIDE.md` (раздел «Robot vacuums»), `docs/ARCHITECTURE.md` — как
|
||||
канонические источники терминологии и текущего контракта.
|
||||
6. Исходный код `src/houseplan-card.ts` (`_renderVacuums`, ~11819–11905) и
|
||||
`src/vacuum.ts` (`normalizeVacPath`, `resolveCurrentVacPath`,
|
||||
`trimVacPathTarget`, `VAC_PATH_MAX_SEGMENTS/POINTS`, `TRAIL_MAX`) и
|
||||
`custom_components/houseplan/trails.py` (`TRAIL_CAP`) — сверка каждого
|
||||
факта, на который ссылается ТЗ.
|
||||
7. `docs/TESTING.md` — существование `scripts/mutation-gate.mjs` и практики
|
||||
мутационных гвардов, на которые ссылается план автотестов ТЗ.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Продуктовая часть (docs/SCOPE.md, персона, сценарий) читалась первой и
|
||||
отдельно от технической, как требует §7.1. Технические утверждения ТЗ
|
||||
(номера строк, имена функций, константы лимитов, порядок affine → build →
|
||||
`_scenePoint()`) верифицированы построчным чтением текущего кода, а не
|
||||
доверием тексту ТЗ. Отдельно перепроверено математическое обоснование предела
|
||||
17,5 см в §6.2 (см. ниже) — это не тривиальное утверждение, и ложное
|
||||
доказательство было бы поводом для High.
|
||||
|
||||
## Находки
|
||||
|
||||
Находок нет — ни High, ни Medium, ни Low.
|
||||
|
||||
Разобранные кандидаты, которые не подтвердились как дефект:
|
||||
|
||||
- **Отсутствие docs/USER-GUIDE.md (EN) в списке release-артефактов §13.**
|
||||
Проверено: `docs/USER-GUIDE.md` раздел «16. Robot vacuums» не описывает
|
||||
форму линии следа (M/L vs кривая) — он делегирует детали в `VACUUM.md`
|
||||
одной фразой. `VACUUM.md` (канонический для этого контракта, EN) в списке
|
||||
§13 присутствует. Правки нечего вносить в `USER-GUIDE.md`, значит его
|
||||
отсутствие в перечне не является пропуском.
|
||||
- **Утверждение issue-body про поверхность «статический рендер».** Тело issue
|
||||
перечисляет «View, киоск, статический рендер» как поверхности показа следа.
|
||||
Проверено: `src/space-card.ts` и `src/space-render.ts` (инертная
|
||||
`houseplan-space-card`) не содержат ни одного упоминания vacuum/trail —
|
||||
сейчас след там не рисуется. Само ТЗ, однако, этой ошибки не наследует: §1
|
||||
описывает только View/киоск/редакторы, а §4 Scope формулирует охват как
|
||||
«поверхности, где след уже рисуется» — не перечисляя конкретный список.
|
||||
§5 Non-scope прямо запрещает «добавление следа ... на поверхности, которые
|
||||
его сейчас не имеют». Формулировка ТЗ самодостаточно корректна независимо
|
||||
от неточности в исходном issue-анализе.
|
||||
- **Математика предела в §6.2.** Проверено: для точки на `conv{P, B, Q}`
|
||||
расстояние до `B` ограничено `r = min(17.5см, |AB|/2, |BC|/2)` в силу
|
||||
выпуклости нормы (максимум выпуклой функции на симплексе достигается в
|
||||
вершине); P и Q лежат на исходных отрезках, поэтому граница до исходной
|
||||
ломаной действительно ≤ r ≤ 17,5 см. Отдельно проверено недопущение
|
||||
наложения соседних скруглений: раз `r_B2 ≤ |s2|/2` и `r_B3 ≤ |s2|/2` для
|
||||
общего отрезка `s2`, точка `Q` вершины `B2` не может оказаться дальше по
|
||||
отрезку, чем точка `P` вершины `B3` — соседние скругления не меняются
|
||||
местами. Довод в тексте ТЗ корректен, не голословен.
|
||||
- **Эпсилон разворота ~180°.** Помечен явно как техническое решение автора
|
||||
реализации, фиксируемое unit-тестом (§14 п.3), а не выдан за факт — это
|
||||
ровно то отличие «предположения» от «незамеченной догадки», которое требует
|
||||
проверять инструкция ревью.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- **Персона/сценарий/до-после** — первые два раздела (§7.1) заполнены
|
||||
корректно и без терминов реализации; соответствуют J1 (`docs/SCOPE.md`:
|
||||
«Show the whole home and what's happening right now»).
|
||||
- **Продуктовые вопросы владельцу** заданы по существу (граница сглаживания,
|
||||
вкл/выкл, previous run) — все три ровно того типа, что разрешён §7.1
|
||||
(«что видно», «объём видимых изменений»), без технических вопросов,
|
||||
вынесенных наружу. Ответы получены и зафиксированы в issue до отправки ТЗ
|
||||
на ревью — блокировка снята в срок.
|
||||
- **Все обязательные разделы §7.1 присутствуют**: сценарий, до/после,
|
||||
проблема, scope/non-scope, контракт поведения, UX/a11y/touch/i18n, модель
|
||||
данных и совместимость, AC1–AC11 с методом доказательства для каждого,
|
||||
план автотестов, риски, release-артефакты, откат.
|
||||
- **AC однозначны и проверяемы**: каждый сформулирован как измеримое
|
||||
утверждение (endpoints совпадают, отклонение ≤17,5 см, число команд ≤2N,
|
||||
таблица режимов не меняется и т.д.), не «сделать нормально»/«работает как
|
||||
ожидается».
|
||||
- **Факты о коде подтверждены построчно**: `VAC_PATH_MAX_SEGMENTS = 64`,
|
||||
`VAC_PATH_MAX_POINTS = 4000` (`src/vacuum.ts:14-15`), `TRAIL_MAX = 600`
|
||||
(`src/vacuum.ts:477`), `TRAIL_CAP = 2000`
|
||||
(`custom_components/houseplan/trails.py:27`), `resolveCurrentVacPath`,
|
||||
`trimVacPathTarget`, `normalizeVacPath` (`src/vacuum.ts:169,201,222`) —
|
||||
все совпадают с ТЗ. Текущий рендер (`_renderVacuums`,
|
||||
`src/houseplan-card.ts:11819-11905`) действительно строит current как
|
||||
единый `path` с `M`/`L` по подпутям и previous — отдельным `polyline`
|
||||
(`:11855`), обе ветки применяют affine и затем `_scenePoint()` на каждую
|
||||
точку — план ТЗ перенести этот порядок на «affine всего подпути → builder →
|
||||
проекция» архитектурно согласован с существующим кодом, не выдумка.
|
||||
`src/vacuum.ts` уже существует и уже владеет `normalizeVacPath`/
|
||||
`resolveCurrentVacPath`/`trimVacPathTarget` — ровно тот модуль, куда ТЗ
|
||||
просит добавить pure builder (§9), это не новый файл и не смена владения.
|
||||
- **Non-scope согласован со scope**: явно исключены изменения хранения,
|
||||
лимитов, arbitration, trail modes, добавление следа туда, где его нет —
|
||||
ни один пункт scope не противоречит этому списку.
|
||||
- **Терминология согласована** с `docs/USER-GUIDE.ru.md` («Никогда/Во время
|
||||
уборки/Всегда», «текущий путь»/«последний завершённый путь») — таблица
|
||||
§6.4 ТЗ не меняет и не путает этот контракт.
|
||||
- **i18n/touch/миграция/откат** — по каждому пункту явное «нет изменений» с
|
||||
обоснованием, а не молчание.
|
||||
- **Track = полный** обоснован верно: видимый контракт подачи меняется,
|
||||
задействовано несколько поверхностей и golden-эталоны — критерий `small`
|
||||
не проходит.
|
||||
- **Продуктовая оценка (польза/сложность/риск)** реалистична и не
|
||||
противоречит `docs/SCOPE.md`: ценность признана косметической (4/10), что
|
||||
корректно для P3-полировки, не блокирующей и не требующей ускоренного
|
||||
трека.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Реализацию — её не существует, стадия spec.
|
||||
- `npx tsc --noEmit` / `npm test` / `npm run build` — не прогонял: гейт не
|
||||
применим к этапу ревью ТЗ (нет кода для компиляции), а не пропущен по
|
||||
экономии.
|
||||
- Golden/смоки/инварианты модели — не прогонял: задача геометрию модели
|
||||
(рёбра, `layout`, `marker.space`, `open_spans`) не трогает (явный
|
||||
non-scope), это этап spec, инструментальные гейты этого раунда не
|
||||
применимы.
|
||||
- Не проверял, действительно ли выбранный владельцем способ (quadratic
|
||||
Bézier по хордам) — лучший вариант из трёх предложенных в issue
|
||||
(Catmull-Rom/Chaikin/Безье): ТЗ прямо отдаёт выбор техники автору
|
||||
реализации, зафиксировав только измеримую границу (17,5 см) и семантику
|
||||
(endpoints, gaps, no bridge) — это корректная граница ответственности
|
||||
spec-ревью, а не пробел.
|
||||
|
||||
## Итог
|
||||
|
||||
ТЗ полное, однозначное, без выданных за факт догадок, предметно
|
||||
верифицировано по коду и документам. Продуктовые вопросы владельцу заданы и
|
||||
закрыты до отправки на ревью. Готово к статусу «Готово к разработке».
|
||||
Reference in New Issue
Block a user