Files
houseplan-card/docs/reviews/SPEC-REVIEW-376-r2.md
T
2026-08-29 17:53:15 +00:00

172 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-376-r2
Issue: [#376](https://github.com/Matysh/houseplan-card/issues/376) — «Пачка Low из аудита beta.4: title:null в
space-card, roomlabel в Background, персист цвета декора, iso-штрихи мебели,
стейл-док, truthy light_pools (а–е)»
Этап: `S4-spec-review` (лёгкий трек, `small`) · PROCESS.md §2.4, §2.10
Заход: r2 · блокирующих циклов израсходовано 1 из 2 (лимит лёгкого трека — 2, §4)
Материал: тело issue #376 на момент правки владельца от **2026-08-29T17:47:05Z**
(«редакция 2»), сверено с текущим `dev` @ `9e60ade8`.
## Предыдущий раунд — что найдено и на чём
Вердикт r1 (комментарий `claude`, 2026-08-29T17:44:30Z):
`красный · заход r1 · блокирующих циклов 1/2 · High: 1 · Medium: 2`
Ревьюер r1 не назвал явно, какая ревизия тела issue разбиралась — это и есть
находка процесса (см. §«Процессная находка» ниже). Восстановлено однозначно
через историю правок GitHub (`userContentEdits` GraphQL): между правкой автора
в 17:34:45Z («редакция 1») и следующей правкой в 17:47:05Z («редакция 2») лежит
ровно вердикт 17:44:30Z — значит r1 разбирал редакцию 1.
Находки r1:
- **H1 (блокирует).** Трек `small` не проходит критерии §5 одновременно:
пакет трогал минимум четыре модуля (`space-card.ts`, `houseplan-card.ts` —
две несвязанные зоны, `houseplan-editor-runtime.ts`, `validation.py`) плюс
документацию — не «одна поверхность»; пункт (в) вводил новый персистентный
серверный ключ `settings.decor_default_style` — новое compatibility-поле,
что тоже прямо исключено критериями лёгкого трека. Прецеденты: #369 (пачка
из семи Low того же аудита ушла на полный трек по формулировке «семь
несвязанных поверхностей»), #372 (родитель пункта (а), сам по себе
потребовавший полного трека). Ревьюер предложил ровно два пути: либо
выделить (в) отдельным issue на полном треке и оставить (а,б,г,д,е) на
`small`, либо снять `small` со всего #376.
- **M1 (в скоупе).** Раздел «откат» отсутствовал полностью — обязательный
минимум лёгкого трека.
- **M2 (в скоупе).** Пункты (б) и (д) были в разделе «Объём», но не имели
своего AC.
## Закрытие раунда r1
| Находка | Чем закрыта | Где это видно |
|---|---|---|
| H1 | Пункт (в) целиком вынесен в отдельный issue [#377](https://github.com/Matysh/houseplan-card/issues/377), помеченный полным треком (метки `377`: `P3`, `polish`, `S4-spec-review` — **без** `small`). В #376 явно записано: «Пункт **(в)** выделен в #377 (полный трек) по SPEC-REVIEW-376-r1 H1; здесь остаются (а, б, г, д, е)». Это ровно первый из двух путей, предложенных ревьюером r1, а не самопровозглашённое решение автора. | Тело issue #376, строка сразу после заголовка «# ТЗ (лёгкий трек, редакция 2)»; `gh issue view 377` подтверждает состояние и метки |
| M1 | Добавлен раздел «## 6. Откат»: «Обычный `git revert`: фича-флагов, миграций и персистентных данных нет… Уже сохранённые конфиги не затронуты ни в одном направлении» + строка «DoR-примечания: миграция/compatibility — нет; touch — не влияет» | Тело issue #376, раздел 6 (отсутствовал в редакции 1) |
| M2 | Добавлены **AC-б** («в USER-GUIDE и USER-GUIDE.ru, раздел Background-редактора, присутствует предложение о неперехвате указателя лейблами комнат… grep в код-ревью») и **AC-д** («`docs/TESTING.md` строка… несёт оговорку про `light_pools`… grep в код-ревью») | Тело issue #376, раздел «2. AC», пункты 2 и 4 (в редакции 1 их не было — было только AC-а/в1/в2/в3/г/е/общ) |
Дельта редакции 1→2 (полный текстовый diff получен через GraphQL
`userContentEdits`) ограничена ровно этими тремя правками плюс механическими
следствиями удаления (в): подраздел «### в) Персист…» в «1. Объём» удалён
целиком; AC-в1/в2/в3 удалены; мутант м2 перенацелен с «вырезать чтение
`decor_default_style`» на «вернуть прежний iso-путь… → красный AC-г»; из
«4. Риски» и «5. i18n/Release-артефакты» убраны все упоминания (в); из
«Принятые предположения» убран пункт про формат `decor_default_style`,
оставшийся пункт обобщён («правки не добавляют записи в store»). Текст
пунктов (а), (б), (г), (д), (е) в разделе «Объём» и их AC-а/AC-г/AC-е —
побайтово идентичен редакции 1.
Дельта локальна (не задета новая подсистема, нет ребейза, размер дельты
меньше исходного ТЗ) — полный разбор всего ТЗ заново не требуется по §2.10.
## Унаследовано из r1 (без повторной проверки)
Со ссылкой на SPEC-REVIEW-376-r1 (опубликован коммитом `9e60ade8`, тот же SHA
`dev`, что и на этом заходе — код между r1 и r2 не менялся, менялось только
тело issue):
- построчная сверка технических утверждений с `dev` — `space-card.ts:290,
811-813, 821, 842, 870`; `plan.styles.ts:863-865` и конкурирующее правило
`:617-619`; `furniture.ts:392-406`; `docs/TESTING.md:1704` — все подтвердились
дословно, догадок, выданных за факты, не найдено. Текст этих пунктов не
менялся редакцией 2, повторно построчно не сверял;
- содержательная адекватность AC-а (title:null↔''), AC-г (iso-компенсация=1) и
AC-е (truthy-гейт light_pools) как проверяемых критериев — r1 их не оспаривал,
текст не изменился;
- продуктовые решения владельца от 29.08 «(а) `title: null` ≡ `''` — компакт»
не пересматриваются;
- отсутствие дубликатов и корректность оценки трека (аналитика §2.2) — вне
предмета ревью ТЗ, не проверялось ни в r1, ни здесь.
## Проверено в этом раунде (r2)
1. **Полный текстовый diff редакции 1→2** — получен напрямую из GitHub
(`userContentEdits` через GraphQL), а не с чужих слов автора. Подтверждено,
что все три заявленных закрытия (H1, M1, M2) реализованы буквально, без
расхождений между сводкой автора («Редакция 2 по SPEC-REVIEW-376-r1: …») и
фактическим текстом.
2. **Существование и трек #377**: `gh issue view 377` — issue создан, открыт,
несёт `S4-spec-review`, `P3`, `polish`, **не несёт `small`** — подтверждает,
что (в) действительно ушло на полный трек, а не осталось меткой без
содержания.
3. **Признак «одна поверхность» после удаления (в)**: оставшиеся пункты
трогают код в двух модулях (`space-card.ts` — а,е; `houseplan-card.ts`/
`furniture.ts` — г) плюс документацию (USER-GUIDE(.ru) — б; TESTING.md — д).
Формально это не один файл, но именно этот остаток ревьюер r1 сам назвал
приемлемым путём разрешения H1 («либо выделить (в)… оставив (а,б,г,д,е) на
`small`»), поэтому не переоткрываю спор о границе критерия — это
технический вопрос, закрытый предыдущим вердиктом, а не открытый заново
дельтой.
4. **AC-б, AC-д как критерии приёмки**: обе формулировки называют способ
доказательства («grep в код-ревью»), что входит в допустимый набор
(unit/backend/smoke/golden/ревью кода, §2.5). Обе проверяемы по одной
строке текста в конкретном файле — однозначны.
5. **Раздел «Откат» (M1)**: адекватен скоупу после удаления (в) — единственный
пункт с записью в store был вынесен, поэтому «обычный `git revert`, без
миграций» для оставшихся правок (условие кадра, формула масштаба, truthy-
гейт, текст доков) — корректное утверждение, а не недосмотр.
6. **DoR-чеклист (§2.5) целиком для редакции 2**: AC1…ACn с доказательством —
есть на все пять пунктов плюс общий; i18n — «не задето», проверяемо (ни
один пункт не добавляет строк UI); миграция/compatibility — «нет», и это
верно только после удаления (в) (иначе было бы неверно — что и было
находкой H1); влияние на перф — «бюджет ≈ без изменений» в AC-общ; touch —
«не влияет»; откат — есть; открытых продуктовых вопросов нет. На лёгком
треке список сокращён самим §5 до «проблема · контракт · AC · откат» — все
четыре присутствуют.
7. **Строки кода, на которые опирается неизменная часть ТЗ**, перепроверены
заново лично (не только унаследованы из r1) для собственной уверенности,
так как дельта косвенно меняет состав пунктов: `space-card.ts:290`
(`if (!this._config.light_pools)`), `:821` (`compactTopFrame:
this._config.title === ''`), `:842` (`lightPools: this._config.light_pools
=== true`), `:870` (`${title ? html…}`); `styles/plan.styles.ts:863-865`
(`.stage.mode-decor .devlayer *`) и `:617-619` (`.stage.markup .roomlabel
{ pointer-events: auto; }` — база `.roomlabel { pointer-events: none }` на
строке 495); `furniture.ts:392-406` (`furniturePlanScreenScale`,
`Math.min(viewportW/viewW, viewportH/viewH)`); `docs/TESTING.md:1704`
(«static room cards show the same data/base projection but no live pools»,
без оговорки про `light_pools`). Все совпадают с текстом ТЗ.
8. **Гейты кода** — не запускались: этап `S4-spec-review`, ветки
`issue/376-*` не существует (`git branch -a` — пусто), кода нет. `npx tsc
--noEmit` / `npm test` / `npm run build` относятся к код-ревью (§2.7, §8) и
здесь неприменимы за отсутствием диффа.
## Находки этого раунда
Блокирующих (High) и находок в скоупе (Medium) нет. Два Low, оба решены
ревьюером на месте (не возвращают автору):
- **L1 (снят с записью).** AC-б называет два разных механизма доказательства
через «и»: «check-docs + grep в код-ревью». `check-docs.mjs` (§8 PROCESS.md)
проверяет отпечаток скриншотов документации против `src/**`, а не наличие
конкретного предложения в `USER-GUIDE.ru.md` — он всё равно прогонится в
код-ревью этой задачи (пункты а/е трогают `src/**`), но ничего не скажет о
содержимом раздела «Background-редактор». Реальное доказательство —
единственно «grep в код-ревью», уже названное там же. Снимаю без возврата:
формулировка избыточна, но не даёт ложного ощущения покрытия — способ
доказательства для код-ревьюера уже назван верно.
- **L2 (снят с записью, процессная).** Вердикт r1 не назвал ревизию тела
issue, которую разбирал (аналог требования называть SHA в код-ревью, §2.10
п.1). В этот раз расхождения это не вызвало — восстановлено однозначно по
времени правок (`userContentEdits`), но рекомендация на будущее: вердикт
спек-ревью лёгкого трека называет метку времени правки (`editedAt`), которую
разбирал, по аналогии с SHA для код-ревью.
## Чего не проверял
- Разбор аналитики (§2.2: дубликаты, ценность, приоритет, тип) — не предмет
ревью ТЗ, унаследован из комментария автора без критики.
- Содержательное ТЗ и трек issue #377 (выделенный пункт «в») — отдельная
задача со своим циклом ревью, не разбирался.
- Полнота формулировки предложения для USER-GUIDE(.ru) по пункту (б) —
ревью ТЗ проверяет наличие AC, а не итоговую формулировку доковой фразы;
это предмет код-ревью через названный в AC-б grep.
- Гейты кода (tsc/test/build/smokes/golden/invariants) — неприменимо на этом
этапе, см. п.8 выше.
## Вердикт
Все находки r1 закрыты дельтой и подтверждены построчно, а не заявлением
автора. Новых High/Medium дельта не вносит. DoR-чеклист §2.5 для лёгкого
трека выполнен целиком.
**Зелёный.**