mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 19:58:50 +00:00
@@ -0,0 +1,198 @@
|
||||
# SPEC-REVIEW-329-r2
|
||||
|
||||
Issue: #329 · Этап: spec (S4-spec-review) · Заход: r2 · Трек: обычный ·
|
||||
Блокирующих циклов израсходовано до этого раунда: 1/4
|
||||
|
||||
ТЗ: `docs/specs/329-junction-limits.md`.
|
||||
Ревизия под ревью — коммит `783c04d1813b0b201efb21b8bae1b0c497978cf1`
|
||||
(«docs: spec #329 revision 2 — per-surface refusal channels, AC5 split,
|
||||
absolute thresholds»), базовый SHA раунда r1 — `8dce8453975121a89263d44243e49059f7000da7`.
|
||||
Класс C (`docs/specs/**`), продуктовый код не тронут — `git show --stat 783c04d1`
|
||||
подтверждает единственный файл в диффе.
|
||||
|
||||
## Скоуп ревью (по дельте, PROCESS.md §2.9)
|
||||
|
||||
Раунд не первый. Предыдущий вердикт — жёлтый, r1, найден в комментарии issue
|
||||
`claude[bot]` от 2026-08-27T16:37:06Z, зафиксирован на SHA `8dce8453` (назван
|
||||
в шапке `docs/reviews/SPEC-REVIEW-329-r1.md`, committed at `9f7d1fd4`). Автор
|
||||
объявил делту в комментарии от 2026-08-27T16:39:52Z: «Ревизия 2 (783c04d1):
|
||||
M1 — ..., M2 — ..., L1 — ...».
|
||||
|
||||
Дельта — `git diff 8dce8453..783c04d1 -- docs/specs/329-junction-limits.md`:
|
||||
38 строк (29 добавлено, 9 удалено) внутри одного файла, только в §2
|
||||
(нормативные ограничения/канал отказа) и §8 (AC5 → AC5a/AC5b). Остальной
|
||||
документ (§1, §3 body, §4, §5, §6, §7, AC1–AC4, AC6, AC8–AC10, §9, §10, §11)
|
||||
байт-не тронут diff'ом.
|
||||
|
||||
Делта локальна: это не ребейз на ушедший вперёд dev, не смена контракта
|
||||
поведения продукта (та же формулировка решений владельца, что и в r1), не
|
||||
задета новая подсистема. Полный разбор документа не требуется — разбираю
|
||||
делту плюс всё, до чего она дотягивается логически (это как раз и вскрыло
|
||||
находку ниже: обновлённое §2 разошлось с AC7, который delta не тронула).
|
||||
|
||||
## Как проверялось
|
||||
|
||||
- Прочитан диф `git diff 8dce8453..783c04d1` построчно — оба заявленных
|
||||
изменения (M1, M2) сверены с текстом находок r1 дословно; L1 тоже
|
||||
проверен, хотя автор не был обязан его чинить.
|
||||
- Перечитан `docs/USER-GUIDE.ru.md`, раздел «Resize» (строки 473–493,
|
||||
таблица 477–484) и «Толщина стены» (515–528) — сверка новой формулировки
|
||||
канала §2 с уже задокументированным поведением инструментов.
|
||||
- `git log --all --oneline | grep 313` + `git show 5e5dad27 --stat` —
|
||||
проверен прецедент #313, на который ссылается §2 для канала «Толщины»
|
||||
(commit message: «Ноль/пусто для независимой кладки отклоняется
|
||||
существующим тостом диапазона») — ссылка не выдумана, поведение реальное.
|
||||
- Перепроверена математика AC5b: равносторонний треугольник, сторона `a`,
|
||||
inradius `r = a/(2√3)`. При `a=60`: `r≈17.32` см, полутолщина стены
|
||||
33/2=16.5 см → остаток `r-half≈0.82` см, внутренний треугольник (offset)
|
||||
имеет сторону `a·(r-half)/r ≈ 60·0.82/17.32 ≈ 2.84` см, площадь
|
||||
`(√3/4)·2.84²≈3.5` см² — меньше 25 см², П5 отказывает при выполненном П1
|
||||
(60°≥15°). При `a=120`: `r≈34.64` см, остаток `34.64-16.5=18.14` см,
|
||||
сторона внутреннего треугольника `≈120·18.14/34.64≈62.8` см, площадь
|
||||
`≈1706` см² — намного больше 25 см², проходит. Числа в AC5b (`17.3`,
|
||||
`34.6`, «<25 см²», «проходит») подтверждаются независимым пересчётом.
|
||||
Побочно проверено, что синтетика AC5b не задевает другие правила
|
||||
(П2: 2 стены/узел ≤6; П3: длина стороны 60/120 см ≥ толщины 33 см) — тест
|
||||
действительно изолирует П5 от остальных ограничений, как заявлено.
|
||||
- Grep по `git show --stat` для `783c04d1` — подтверждено, что кроме
|
||||
`docs/specs/329-junction-limits.md` ничего не менялось: гейты кода
|
||||
(`tsc`/`test`/`build`/`check-docs`/инварианты/смоки) не относятся к
|
||||
чисто документационной ревизии на этапе spec, не прогонял — так же, как
|
||||
в r1.
|
||||
- Перечитаны §3, §6, §7, §9 целиком (не только делта) — чтобы убедиться,
|
||||
что обновлённое §2 не противоречит соседним разделам, которые delta не
|
||||
трогала (см. находку ниже про AC7).
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
| Находка r1 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| **M1** — единый «тост» заявлен как канал отказа для всех пяти поверхностей, включая Resize, что расходится с уже задокументированным контрактом ручек (USER-GUIDE, строки 482–483) | §2 переписан: явный список из трёх каналов по поверхностям — тост (рисование/черновики/независимые/merge-split), существующий контракт приглушённой ручки с объяснением по hover/focus/нажатию для Resize (тост явно исключён: «тост не используется»), тост-в-трее по образцу #313 для «Толщины». Формулировка Resize синтезирует уже документированные строки 482–484 USER-GUIDE (упор в последнюю допустимую позицию + приглушение с объяснением), не изобретает новый визуальный канал | `docs/specs/329-junction-limits.md` §2, строки 26–38 |
|
||||
| **M2** — AC5 сливал повтор фикстуры issue (нарушает П1 напрямую, дублирует AC1) и непроверяемую гипотезу «П5 независим от П1» без конкретных чисел | AC5 разделён: AC5a — сквозной смок фикстуры issue поверх AC1 (честно назван дублирующим по цели, не по механике: unit vs smoke); AC5b — синтетика с названными числами (сторона 60 см / стены 33 см → отказ по П5 при выполненном П1; сторона 120 см → проходит). Числа проверены пересчётом выше — корректны | `docs/specs/329-junction-limits.md` §8, строки 129–136 |
|
||||
| **L1** (Low, не обязана) — параллель «(1 клетка)» у абсолютных порогов П4/П5 могла увести к масштабированию на `cell_cm` | Скобки убраны, П4 и П5 явно помечены «порог абсолютный ... не зависит от `cell_cm`» | `docs/specs/329-junction-limits.md` §2, строки 49–50, 52–53 |
|
||||
|
||||
Все три находки закрыты по существу, не переформулированы уклончиво: M1 и M2
|
||||
дают именно то, что просил r1 (раздельные каналы по поверхности; отдельная
|
||||
синтетика с числами), а не косметическую перефразировку исходного текста.
|
||||
|
||||
## Находки (r2)
|
||||
|
||||
### r2-M1 (Medium, в скоупе) — AC7 не обновлён вместе с §2 и не проверяет заявленный канал отказа для Resize/«Толщины»
|
||||
|
||||
`docs/specs/329-junction-limits.md`, §8, AC7 (текст не менялся диффом
|
||||
r1→r2):
|
||||
|
||||
> «AC7. Resize/«Толщина», приводящие к нарушению любого из П1–П5, — отказ
|
||||
> fail-closed, план байт-неизменен.»
|
||||
|
||||
M1 в r1 требовал: «Явно расписать, какой канал обратной связи используется
|
||||
на КАЖДОЙ из пяти поверхностей» — и отдельно указывал, что «AC7
|
||||
(Resize/«Толщина») тоже не называет способ обратной связи ... что
|
||||
расходится с общей формулировкой §2». Автор исправил §2 (теперь там
|
||||
детальный, специфичный по каждой поверхности контракт — вплоть до
|
||||
формулировки «текст объяснения называет нарушенное правило П1–П5» для
|
||||
Resize и «причина показывается тостом с названием правила (П3/П5)» для
|
||||
«Толщины»), но **AC7 остался прежним** и по-прежнему не тестирует канал —
|
||||
только байт-неизменность плана. §6 (план тестов) тоже не называет
|
||||
конкретный тест на текст ручки/тоста для этих двух поверхностей — там есть
|
||||
только «юниты на каждую формулу П1–П5» и «смок репро-фикстуры #329»,
|
||||
которые формулу проверяют, а не канал отказа.
|
||||
|
||||
Это ровно тот класс дефекта, который правился в M1: нормативный текст §2
|
||||
теперь делает более специфичные утверждения о видимом поведении (что
|
||||
именно называет объяснение ручки, что именно показывает трей), чем было в
|
||||
r1 — но ни одна acceptance criteria не привязана к доказательству именно
|
||||
этой специфики, и §9 («принято предположительно») её тоже не перечисляет
|
||||
как допущение.
|
||||
|
||||
**Чем это грозит.** Риск, который в r1 сформулирован как последствие
|
||||
M1 («реализация по букве §2 добавит тост поверх существующей ручки, либо
|
||||
автор тихо перепишет UX Resize»), не устранён полностью: теперь у §2 есть
|
||||
правильный нормативный текст, но у AC7 нет проверки, что реализация ему
|
||||
соответствует. Разработчик, ориентирующийся на AC (а не на прозу §2) при
|
||||
написании тестов на этапе кода, может закрыть AC7 голым fail-closed-тестом,
|
||||
не проверив, что ручка называет П1–П5, а трей — П3/П5, и разойтись с §2
|
||||
незамеченным до код-ревью или позже.
|
||||
|
||||
**Что нужно сделать.** Дополнить AC7 (или завести AC7a/AC7b по аналогии с
|
||||
AC5) явной проверкой канала: для Resize — текст hover/focus/click называет
|
||||
нарушенное правило (П1–П5) и тост при этом не появляется; для «Толщины» —
|
||||
трей показывает отказ значения с тостом, называющим правило (П3/П5). Либо,
|
||||
если такая гранулярность признаётся избыточной для AC и достаточно прозы
|
||||
§2, явно снять эту находку в комментарии автора с той же аргументацией —
|
||||
но не оставлять молча, раз в этом раунде именно расхождение AC и §2 было
|
||||
предметом M1.
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Не проверялось заново — делта r1→r2 (`git diff 8dce8453..783c04d1`) эти
|
||||
разделы байт-не тронула, и ни одно новое r2-наблюдение до них логически не
|
||||
дотягивается:
|
||||
|
||||
- Продуктовая рамка (`docs/SCOPE.md`, соответствие J6/J1/J5/J7) — принято
|
||||
без повторной проверки.
|
||||
- §1 (сценарий), §4 (рендер легаси-острия, ссылки на #309/#310 в
|
||||
`docs/WALL-THICKNESS.md`), §5 (бэкенд, прецедент
|
||||
`invalid_partition_opening_jamb_margin`) — принято без повторной
|
||||
проверки.
|
||||
- §6 (артефакты/поверхности, i18n-ключи, golden-сцена), §7
|
||||
(производительность/touch) — принято без повторной проверки, за
|
||||
вычетом отмеченного выше пробела AC7↔§2 в §8, который относится к §8, а
|
||||
не к §6.
|
||||
- AC1–AC4, AC6, AC8–AC10 — формулировки не менялись диффом, границы и
|
||||
способ доказательства уже проверены в r1 — принято без повторной
|
||||
проверки.
|
||||
- §9 («принято предположительно»), §10 (риски), §11 (откат) — не менялись,
|
||||
принято без повторной проверки.
|
||||
- Обязательные разделы §7.1 присутствуют по содержанию, артефакт
|
||||
корректного класса (полноценный файл ТЗ, задача не `small`) — принято
|
||||
без повторной проверки.
|
||||
- Пять численных ограничений П1–П5 совпадают с решением владельца в чате
|
||||
issue дословно (проверено в r1) — сами числа delta не меняла (менялась
|
||||
только форма записи П4/П5 без «(1 клетка)», см. закрытие L1 выше),
|
||||
повторная сверка с чатом владельца не требовалась.
|
||||
|
||||
Источник: `docs/reviews/SPEC-REVIEW-329-r1.md` (committed at `9f7d1fd4`),
|
||||
вывод получен на SHA `8dce8453975121a89263d44243e49059f7000da7`.
|
||||
|
||||
## Что проверено и корректно (делта r2)
|
||||
|
||||
- M1 закрыт по существу: канал отказа расписан по всем пяти поверхностям
|
||||
отдельно, Resize явно НЕ использует тост (снимает риск дублирующего
|
||||
сообщения из r1), формулировка синтезирует уже задокументированное
|
||||
поведение USER-GUIDE (строки 482–484), а не изобретает новый визуальный
|
||||
контракт.
|
||||
- Канал «Толщины» (тост-в-трее по образцу #313) подтверждён существующим
|
||||
прецедентом — не выдумка, коммит `5e5dad27` содержит именно такое
|
||||
поведение для независимой кладки.
|
||||
- M2 закрыт по существу: AC5a/AC5b разделены корректно, числа AC5b
|
||||
математически верны (пересчитано независимо, см. «Как проверялось»),
|
||||
синтетика действительно изолирует П5 от П1/П2/П3.
|
||||
- L1 закрыт (не был обязателен) — абсолютность порогов П4/П5 теперь
|
||||
explicit, скобка с «клеткой» убрана, не вводит в заблуждение.
|
||||
- Никаких новых догадок, выданных за факт, в самой делте (кроме находки
|
||||
r2-M1, которая не про новую догадку в тексте, а про рассинхрон текста и
|
||||
AC) не обнаружено.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Весь материал, перечисленный в разделе «Унаследовано из r1» — сознательно
|
||||
не перепроверял, делта его не касается (см. обоснование там же).
|
||||
- Код не менялся в этом коммите (только `docs/specs/**`, класс C) — гейты
|
||||
`typecheck`/`test`/`build`/`check-docs`/инварианты модели/смоки не
|
||||
прогонял: они не относятся к чисто документационной правке на этапе
|
||||
spec-review.
|
||||
- Не проверял, как именно разработчик в итоге сформулирует текст
|
||||
ручки/тоста при реализации — это предмет код-ревью, а не спек-ревью;
|
||||
здесь оценивается только наличие проверяемого критерия в ТЗ (которого,
|
||||
по находке r2-M1, для этой специфики пока нет).
|
||||
- Не запрашивал у владельца дополнительных продуктовых уточнений —
|
||||
находка r2-M1 технического характера (согласованность AC с прозой),
|
||||
решается автором ТЗ, а не владельцем.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Жёлтый. Один Medium в скоупе задачи (r2-M1), High-находок нет. Оба Medium
|
||||
раунда r1 (M1, M2) закрыты корректно и не переоткрываются. Находка r2-M1
|
||||
чинится в этом же ТЗ (правка AC7/§8) без смены архитектуры документа;
|
||||
отдельный issue не заводится (#202, находка в скоупе).
|
||||
Reference in New Issue
Block a user