Files
houseplan-card/docs/reviews/SPEC-REVIEW-445-r2.md
T
2026-09-03 22:03:14 +00:00

16 KiB
Raw Blame History

SPEC-REVIEW-445-r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/445
  • Этап: spec (PROCESS.md §2.4), трек: full (не изменился с r1: сложность/риск > 3, контракт проходит через несколько модулей)
  • Материал: docs/specs/445-furniture-wall-face-snap.md, коммит a6d0c0b980bba09b24c4b514e865dce9e5fff564 на ветке issue/445-furniture-wall-face
  • Предыдущий раунд: docs/reviews/SPEC-REVIEW-445-r1.md, материал f6879b3788fc6ddc2626482ce0a890edb6b0200b
  • Заход: r2 · блокирующих циклов израсходовано 1 из 4 (r1 был жёлтым и потратил цикл; r2 не тратит цикл, если вердикт зелёный — §227)

Скоуп разбора — по дельте (§2.10)

Найден вердикт r1 (жёлтый, Medium: 1) и материал, на котором он получен — SHA f6879b3788fc6ddc2626482ce0a890edb6b0200b, объявлен в самом документе r1 («Материал раунда»). SHA резолвится (git log --oneline f6879b37..a6d0c0b9 проходит без ошибок), ребейза не было: merge-base ветки с origin/dev для f6879b37 и для текущего HEAD — один и тот же коммит 560ca214, origin/dev за это время не продвинулся.

Дельта объявлена командой git diff f6879b37..a6d0c0b9:

docs/reviews/SPEC-REVIEW-445-r1.md         | 251 +++++++++++++++++++++++++++++
docs/specs/445-furniture-wall-face-snap.md |  14 +-
2 files changed, 264 insertions(+), 1 deletion(-)

Изменения в docs/specs/445-furniture-wall-face-snap.md — ровно:

  1. новый раздел ### AC10. Выбор стены в углу детерминирован (9 строк);
  2. один новый пункт в «Плане тестирования», называющий AC10 witness;
  3. удаление одной хвостовой пустой строки в конце файла (косметика, без смыслового эффекта).

docs/reviews/SPEC-REVIEW-445-r1.md — публикация документа предыдущего раунда конвейером (класс C, не предмет разбора этого раунда, сам себя не проверяет).

Дельта локальна: не ребейз, не смена контракта (AC10 доказывает пункт контракта, который уже был в тексте r1 и признан приемлемым по содержанию — находка r1 была именно в отсутствии пронумерованного AC, а не в самом правиле tie-break), не новая подсистема (тот же модуль — выбор стороны физической поверхности стены), объём (9+1 строк) несопоставимо меньше исходного ТЗ (377 строк). Условия для полного повторного разбора (§2.10, абзац «Разбор остаётся полным») не выполнены — разбор по дельте оправдан.

Разбор ограничен: 1) содержанием добавленного AC10 против находки r1 и против контракта, который он призван доказать; 2) тем, что дельта не затрагивает доказательства AC1…AC9 (их текст не изменился — см. diff выше) и, значит, эти AC наследуются без повторной проверки; 3) процессной гигиеной раунда (трейлеры коммитов, класс файлов, отсутствие расширения скоупа).

Как проверялось

  1. gh issue view 445 — тело issue и 6 комментариев прочитаны целиком: аналитика → вопросы владельцу (Q1/Q2) → решение владельца → «ТЗ готово» (f6879b37) → вердикт r1 (жёлтый) → «Правки ТЗ после ревью r1» (a6d0c0b9).
  2. git diff f6879b37..a6d0c0b9 — построчно, содержание совпадает с тем, что заявлено в комментарии автора («Правки ТЗ после ревью r1»): AC10 добавлен, план тестирования дополнен, ничего другого не тронуто.
  3. Текст AC10 сверен с находкой r1 построчно:
    • r1 требовал: пронумерованный AC, метод доказательства unit, три ветки (разное расстояние → ближайшая поверхность; равное расстояние → сторона намерения раньше стабильного tie-break; полное равенство → инвариантность к перестановке массива) и названную мутацию.
    • AC10 содержит все четыре пункта дословно: «при разных расстояниях выигрывает физически ближайшая поверхность», «при равном расстоянии сторона точки намерения учитывается раньше стабильного tie-break», «при полном равенстве перестановка входного массива не меняет выбранную поверхность и конечные x/y/angle», «Mutation, возвращающая прежний выбор первого минимума из массива либо меняющая местами intent-критерий и стабильный tie-break, обязана сделать соответствующий witness красным». Соответствие точное, ничего не потеряно и не подменено более слабым утверждением.
  4. AC10 сверен с исходным контрактом («Выбор стороны», п.6: «В углу либо при равном расстоянии до нескольких стен выигрывает физически ближайшая поверхность, затем сторона намерения, затем стабильный tie-break. Перестановка входных массивов не меняет результат.») и со строкой таблицы крайних случаев «угол с двумя равноудалёнными стенами». AC10 доказывает именно эту фразу, ни расширяя, ни сужая её.
  5. Проверено, что нумерация AC1…AC10 не сломана и не задваивается (grep 'AC[0-9]' по файлу) и что «План тестирования» и «Карта реализации» не противоречат новому AC.
  6. Проверено, что docs/specs/README.md не менялся в этой дельте (запись про #445 уже была внесена в r1) — реестр не расходится.
  7. Трейлеры коммитов дельты: a6d0c0b9 — Issue: #445, User-Visible: no; eb5e15fb (публикация r1) — Issue: #445, User-Visible: no. Оба корректны для класса C, документация без видимого поведения.
  8. Гейты typecheck/test/build — не прогонялись, см. «Чего не проверял» (то же обоснование, что в r1, дельта снова docs-only).

Находки

Новых находок нет. Единственная находка r1 (Medium, в скоупе) закрыта — см. «Закрытие раунда r1» ниже.

Закрытие раунда r1

Находка r1 Чем закрыта Где это видно
Medium: угловой tie-break (контракт «Выбор стороны» п.6 и строка «угол с двумя равноудалёнными стенами») не имел пронумерованного AC — код-ревью не был бы обязан проверять эту ветку Добавлен ### AC10. Выбор стены в углу детерминирован с методом доказательства unit, тремя проверяемыми ветками (ближайшая поверхность / intent-side / permutation invariance) и названной мутацией; «План тестирования» дополнен пунктом про AC10 witness docs/specs/445-furniture-wall-face-snap.md:308-316 на коммите a6d0c0b980bba09b24c4b514e865dce9e5fff564; факт правки также подтверждён комментарием автора «Правки ТЗ после ревью r1» в issue

Унаследовано из r1

Дельта не задевает доказательства AC1…AC9, структуру документа, сверку терминологии, соответствие SCOPE.md и данные/touch-разделы — они приняты без повторной проверки по документу и материалу r1:

  • Документ: docs/reviews/SPEC-REVIEW-445-r1.md
  • Материал (SHA): f6879b3788fc6ddc2626482ce0a890edb6b0200b
  • Принято без повторной проверки:
    • соответствие «Подтверждённой проблемы» и карты реализации фактическому коду (_furnWalls, snapFurnitureToWall, ветка nl < 1e-9, test/furniture.test.mjs) — код в этой дельте не менялся;
    • перенос owner-defaults Q1/Q2 в контракт без искажений;
    • соответствие терминологии docs/USER-GUIDE.ru.md;
    • соответствие docs/SCOPE.md (J4/J6, вне scope collision model и др.);
    • структура разделов §7.1 и совпадение с шаблоном #442;
    • однозначность и метод доказательства AC1…AC9, включая названные для каждого mutation witnesses;
    • корректность разделов «Скоуп»/«Не-скоуп», «Данные и совместимость», «Touch, клавиатура и доступность»;
    • двусторонняя ссылка issue ↔ ТЗ и трейлеры коммита f6879b37.

Что проверено и корректно (дельта r2)

  • AC10 точно и без ослабления закрывает находку r1: метод доказательства назван (unit), все три ветки контракта пронумерованы и проверяемы, мутация, обязанная покраснить каждую ветку, названа явно.
  • Нумерация AC не задвоена, следующий за AC10 текст («План тестирования») ссылается на него корректно и не создаёт второго, конфликтующего описания того же сценария.
  • Правка не расширяет и не сужает скоуп задачи: изменений в «Скоуп»/ «Не-скоуп», контракте помимо самого пункта 6 (уже существовавшего в r1), данных, touch-разделах — нет.
  • Дельта не восстанавливает и не создаёт продуктовую догадку, поданную как факт: AC10 доказывает уже принятое в r1 предложение контракта, не вводит новое поведение.
  • Трейлеры и класс файлов (C, документация) корректны на обоих коммитах дельты; User-Visible: no обоснован — видимого поведения не появилось (ТЗ, не код).
  • docs/specs/README.md не расходится: запись #445 не нуждалась в правке.

Чего не проверял

  • Гейты typecheck/test/build/bundle:sync не прогонялись. Дельта раунда (git diff f6879b37..a6d0c0b9) касается исключительно docs/specs/445-furniture-wall-face-snap.md и docs/reviews/ SPEC-REVIEW-445-r1.md — класс C, ни одного файла src/**/test/**/ scripts/**. Прогон этих гейтов не дал бы сигнала об этой дельте: то же обоснование, что в r1, и оно не изменилось, потому что реализация ещё не начата — issue остаётся в S3-spec/S4-spec-review, кода нет.
  • node scripts/check-docs.mjs, model-invariants.mjs, browser smokes, golden, backend pytest — не прогонялись. Условия запуска (diff по src/** или по геометрии) не выполнены; часть плана тестирования будущего код-ревью, а не этого этапа.
  • Не проверял заново алгоритм «стабильного tie-break» для общей стены (раздел 2, п.4) — не изменился в этой дельте, был вне находки r1 и уже учтён в «Чего не проверял» r1 как технический выбор автора, свободный к пересмотру.

Материал раунда

  • Ветка: issue/445-furniture-wall-face
  • SHA материала: a6d0c0b980bba09b24c4b514e865dce9e5fff564
  • Дельта против материала r1 (f6879b3788fc6ddc2626482ce0a890edb6b0200b): docs/specs/445-furniture-wall-face-snap.md (+13/-1), docs/reviews/SPEC-REVIEW-445-r1.md (новый, публикация r1)
  • merge-base с origin/dev: 560ca214b0d7d9018ff7916b25ebaea96a80e912 (не изменился с r1 — ребейз не требовался)

Вердикт

Единственная находка r1 (Medium, в скоупе) закрыта полно и точно: AC10 дословно доказывает пункт контракта, из-за отсутствия доказательства которого r1 был жёлтым. Новых находок дельта не создала. High: 0, Medium: 0.

Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0


Материал раунда

  • Ветка: issue/445-furniture-wall-face, коммит a6d0c0b980bb — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: e9ae4165a69eb42230dfa85b3d12678bc0f4c615
    git log --all --format='%H %T' | grep e9ae4165a69e
    
  • ТЗ docs/specs/445-furniture-wall-face-snap.md, блоб 95d03a5425fc37f95095c2f53a49363e668edb40
    git log --all --find-object=95d03a5425fc37f95095c2f53a49363e668edb40 -- docs/specs/445-furniture-wall-face-snap.md