diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index 211e78f3..ecdab35d 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,9 +1,10 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 165, issue: 77. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 166, issue: 78. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| +| #688 | [SPEC-REVIEW-688-r1.md](SPEC-REVIEW-688-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #687 | [SPEC-REVIEW-687-r1.md](SPEC-REVIEW-687-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #687 | [CODE-REVIEW-687-r1.md](CODE-REVIEW-687-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #686 | [CODE-REVIEW-686-r1.md](CODE-REVIEW-686-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-688-r1.md b/docs/reviews/SPEC-REVIEW-688-r1.md new file mode 100644 index 00000000..bf176ac2 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-688-r1.md @@ -0,0 +1,169 @@ +# SPEC-REVIEW-688-r1 + +**Issue:** #688 «Лестницы: привязать толщину всех линий к сантиметрам» +**Этап:** spec (ревью ТЗ, PROCESS.md §2.4) +**Заход:** r1 · блокирующих циклов израсходовано 0 из 4 +**Вердикт:** зелёный + +## Материал раунда + +- ТЗ — тело issue #688, раздел `## ТЗ` (owner-решение 2026-09-10, #517). +- sha256 нормализованного тела issue на момент ревью: + `780d993b5f8eee85ee9bdea58464fb7b8f6e5cd586c0c6c613d3312c70e4b0ac` + (полный текст тела issue, как отдан `gh issue view 688 --json body`). +- Аналитика и Q&A с владельцем (комментарии issue, 2026-09-28): вопросы + Q1 (нужна ли пользовательская настройка толщины) и Q2 (fallback для + старых лестниц) заданы и закрыты владельцем **до** публикации текста + `## ТЗ` — финальное ТЗ уже отражает решение владельца (без нового + поля, фиксированная константа 3,6 см для всех лестниц без миграции). + Открытых продуктовых вопросов к моменту ревью нет. +- Референс: код на `c047ca22304ec9c2c6f5780b23adc85fb7b51a66` (материал + этапа code, здесь используется только для проверки технической + выполнимости ТЗ, а не как предмет код-ревью). + +## Скоуп + +Перевод толщины всех линий символа лестницы (внешний контур, трапеция, +ступени, стрелка) с фиксированных экранных px на единую физическую +константу 3,6 см — по аналогии с уже исправленным контрактом мебели +(#361). Экран (View/Plan/draft/статический/2.5D) и PDF получают одно +вычисление. Персистед-модель не меняется, миграции нет, пользовательской +настройки не добавляется. Обслуживает J1 (`docs/SCOPE.md`): лестница — +часть плана, и одинаковые физические элементы должны сохранять +размерный смысл при zoom, как и остальная геометрия дома. + +## Как проверялось + +Ревью ТЗ здесь неотделимо от проверки технической выполнимости заявленных +формулировок, поэтому каждое фактическое утверждение ТЗ сверено с текущим +кодом на `c047ca22` (не как код-ревью — как проверка, что ТЗ не обещает +того, чего в модели нет, и не строит контракт на несуществующих +абстракциях): + +- `docs/SCOPE.md`, `docs/process/REVIEWER.md`, `AGENTS.md` — прочитаны + первыми, конфликтов с продуктовым скоупом не найдено. +- `docs/STAIRS.md` (канонический документ подсистемы) — сверен с ТЗ: + описание геометрии, persisted-модели, границ модулей (`stairs.ts`, + `stairs-view.ts`, `stairs-editor.ts`, `space-render.ts`) совпадает + с §9 ТЗ дословно. +- «До»-состояние толщины проверено чтением `src/styles/plan.styles.ts`: + контур/трапеция/ступени — `calc(2px / var(--hp-plan-screen-scale, 1))` + с `vector-effect: non-scaling-stroke`, стрелка — `2.5px`, hover/selection + отдельно подменяют `2.5px`/`3px` для контура. Это ровно компенсация + экранного зума (деление на screen-scale) — то есть заявленный в ТЗ баг + «фиксированная экранная величина» подтверждён на месте, а не с чужих слов. +- То же для PDF: `src/pdf/pdf-scene.ts` — outline/трапеция/ступени + `0.25 * MM`, стрелка `0.3 * MM` (строки 407–485), совпадает с §2 ТЗ. +- Существующий физический контракт мебели (#361), на который ссылается + ТЗ, — реален и пригоден для повторного использования по аналогии: + `src/grid-scale.ts` (`gridVisualScale`, эталон `cell_cm=5`), + `src/editors/decor/geometry.ts` (`decorCmToUnits`/`decorUnitsToCm`/ + `decorStrokeCm`, сигнатура `(cm, cellCm, gridPitch)` — ровно то, что + §5.3 ТЗ называет «текущие `cell_cm` и grid pitch»), `src/furniture.ts` + (`furniturePlanScreenScale`/`furnitureStrokePx` — «компенсировать + только локальный transform, сохраняя масштаб камеры», буквально + формулировка §5.5 ТЗ), `src/pdf/pdf-scene.ts:450` (`decorStrokeCm(...) + * 10 * MM / scale` — готовый прецедент формулы AC6 «3,6 см / print + scale» для декора, лестницам остаётся повторить тот же приём). +- Совпадение числа 3,6 см с `DEFAULT_DECOR_STYLE.widthCm` в + `src/editors/decor/geometry.ts:33` — не случайность и не необъявленный + дубль источника: ТЗ §15 explicit проговаривает это как сознательное + решение (независимая именованная константа в модуле лестниц, а не + снимок текущей настройки декора), поэтому будущее изменение + дефолтного decor-width не тянет лестницы за собой. Это зафиксированный + выбор, а не находка §8 «одно число — два источника» — при код-ревью + стоит лишь убедиться, что реализация не завела вместо этого второй + импорт того же литерала. +- Отсутствие клампа минимальной/максимальной экранной толщины (§15) — + сверено с прецедентом: у мебели (`src/furniture.ts`) такого клампа + тоже нет, несогласованности с существующим контрактом нет. +- `demo/golden/` (`harness.mjs`, `matrix.mjs`, `run.mjs`) поддерживает + сцены с разным zoom — план автотестов (AC2, §11) исполним + существующей инфраструктурой, не требует новой. +- Обязательные разделы §7.1 (сценарий · что человек видит · проблема · + скоуп/не-скоуп · контракт поведения · UX · модель данных и совместимость + · i18n · AC1…ACn с доказательством · план автотестов · риски · откат · + release-артефакты) — присутствуют все, в этом порядке или эквивалентном. + +## Находки + +Не найдено ни одной находки уровня High или Medium. + +Рассмотренные и отклонённые как «не находка»: + +- **Число 3,6 см возможно продублировано** (декор vs лестницы) — + разобрано выше: явно проговорено в §15 ТЗ как независимая константа, + а не скрытое совпадение. Не Medium. +- **AC2 использует «примерно вдвое»** — не дефект: golden/smoke-оракул с + допуском — обычная практика этого проекта (курсор на «примерно» — не + формулировка «на глаз», а численный допуск инструмента сравнения). +- **ТЗ не называет отдельно, на какой поверхности (View или Plan) + проверяется AC2 zoom** — не блокирует: AC5 требует паритета между + всеми поверхностями, поэтому выбор конкретной сцены для AC2 не меняет + результат; это техническое решение реализации, которое ТЗ явно отдаёт + автору (§7.1 «всё, чего пользователь не наблюдает — решает автор»). + +## Что проверено и корректно + +- Все обязательные разделы §7.1 присутствуют, включая первые два + (сценарий, что человек видит до/после) в продуктовых терминах, без + терминов реализации. +- Каждый AC1–AC9 сформулирован однозначно и содержит способ доказательства + (unit / golden / smoke / ревью кода), включая защитные AC7 (конфиг не + меняется) и AC9 (производительность) — таблица «чем краснеет» для них + не требуется на этапе спек-ревью (это требование код-ревью, §2.7), но + формулировки AC уже пригодны для такой таблицы на следующем этапе. +- Скоуп и не-скоуп разделены чётко и совпадают с «Не входит» из тела + issue, написанного до ТЗ (геометрия/шаг ступеней/цвета/hit-area/magnet/ + переход между этажами — везде согласованно исключены). +- Модель данных и совместимость: явно «поле не добавляется, миграции + нет» — не расходится ни с одним разделом `docs/STAIRS.md` и не создаёт + новых веток для `docs/CONFIG-COMPATIBILITY.md` (никакая запись реестра + не заводится, так как схема не меняется). +- Продуктовые вопросы (Q1/Q2) были заданы владельцу батчем с + предложенным дефолтом каждый, как того требует §7.1; ответ владельца + однозначен и уже интегрирован в текст ТЗ — открытых вопросов к + ревьюеру не осталось. +- Раздел «Принятые предположения» (§15) корректно отделяет то, что автор + решил сам (нет клампа, hover — экранный акцент, PDF без отдельной + поправки стрелки, константа независима от decor-default) — ревьюер эти + решения не оспаривает: они не наблюдаемы пользователем и согласуются + с прецедентом мебели. +- Touch/i18n/производительность/откат/release-артефакты — все пункты DoR + (§2.5) закрыты явными формулировками, включая явное «не меняется» там, + где это уместно. + +## Чего не проверял + +- Не проверял сам код реализации (её ещё нет на этой ветке к моменту + spec-ревью) — только техническую опору ТЗ на существующие + функции/константы, перечисленные выше. +- Не прогонял ни один автоматический гейт (`tsc`, `npm test`, + `npm run build`, golden, smoke): на этапе ревью ТЗ они неприменимы — + продуктовый код ещё не изменён, оценивается только текст ТЗ. Гейты + будут предметом код-ревью после реализации. +- Не проверял формулировки EN/RU i18n построчно — ТЗ утверждает «нет + новых/изменённых строк», это утверждение не требует построчной сверки + на спек-этапе, так как не заявляет конкретных ключей. + +## Вердикт + +Зелёный. ТЗ полно по §7.1, каждый AC однозначен и проверяем, технически +опирается на реально существующие в кодовой базе абстракции (не выдумывает +несуществующий контракт), продуктовая неоднозначность была вынесена +владельцу на этапе аналитики и закрыта до публикации текста ТЗ. High: 0, +Medium: 0. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `c047ca22304e` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `7103fd23a81c5d71840039b2ad6340b19c5d10a9` + ``` + git log --all --format='%H %T' | grep 7103fd23a81c + ``` +- Тело issue: `ff3c781175c80e1cd6b25014945a3f818215e934a513905099262bcb8e5c25c6` +- Вердикт конвейера: `green` · High 0