Files
2026-09-28 11:48:48 +00:00

14 KiB
Raw Permalink Blame History

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