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

16 KiB
Raw Blame History

SPEC-REVIEW-376-r2

Issue: #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, помеченный полным треком (метки 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 для лёгкого трека выполнен целиком.

Зелёный.