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

196 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `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
```