Files
houseplan-card/legacy/reviews/v1.68.0/SPEC-REVIEW-226-r2.md
T
Claudeandclaude[bot] cca9bc856b docs(reviews): документы ревью линий до v1.77.0 — в legacy/reviews (#682)
Волна 5 эпика #674, перенос документов ревью (класс C), сделан
инструментом: `node scripts/reviews-archive.mjs --through=v1.77.0 --apply`.
965 документов 332 задач разложены по `legacy/reviews/<тег>/` (v1.63.0 …
v1.77.0) — 330 задач доказаны трейлерами своей линии, два документа без
трейлера (#68, #94, работа до правила трейлеров) — по линии, где их
добавили. В `docs/reviews/` остались 154 документа задач с трейлером после
v1.77.0 — текущая линия v1.78.0 — и INDEX.md, пересобранный тем же
построителем. История не переписана: SHA-якоря «Материала раунда» живы.
Счёт раундов (`reviewRounds` по живому каталогу и архиву) совпадает до и
после переноса: 694 пары «этап:задача». Строка в `legacy/README.md`.

Issue: #682
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
2026-09-27 22:10:47 +00:00

14 KiB
Raw Blame History

SPEC-REVIEW — issue #226, цикл r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/226
  • ТЗ: docs/specs/226-entity-parent-dedup.md, коммит 6162da8 (ветка issue/226-entity-parent-dedup)
  • Предыдущий раунд: r1, вердикт жёлтый, получен на коммите 5feabed (docs/reviews/SPEC-REVIEW-226-r1.md, назван явно в шапке документа — SHA не пришлось искать отдельной находкой).
  • Трек: обычный полный (не small), лимит циклов ревью ТЗ — 4
  • Ревьюер: Claude (роль «Ревьюер ТЗ», отдельная сессия от автора)
  • Вердикт: зелёный · цикл r2/4 · High: 0 · Medium: 0

Скоуп проверки

Это второй цикл — по §2.10 PROCESS.md разбор ведётся по дельте, а не заново.

Дельта объявлена: git diff 5feabed..6162da8. Затронут ровно один файл предмета ревью — docs/specs/226-entity-parent-dedup.md, плюс сам r1-документ (не часть ТЗ). Дельта в ТЗ:

  • §3.3 — одно уточняющее предложение о следствии правила «hidden sibling не удерживает остаток»;
  • §8 — одно уточняющее предложение о том же следствии применительно к сценарию #94, плюс явное «это ожидаемое следствие Q2, а не обход cover-first»;
  • §12 — новый тест-кейс 14 (граница #94: видимая entity:switch.reverse_direction
    • hidden-only cover.curtain), старый кейс 14 (Switch as X browser fixture) сдвинут на 15;
  • AC4 — добавлена ссылка на новый кейс 14;
  • AC7 — обновлена ссылка со старого номера 14 на новый номер 15.

Дельта локальна: не меняет контракт поведения (текст фиксирует то же решение Q2, которое уже было принято владельцем в r1), не задевает новую подсистему, не связана с ребейзом (origin/dev здесь не участвует, история линейная — 3af0484 → a20dd54 → 5feabed → ecf9473 → 6162da8). Полный разбор всего ТЗ не требуется; проверке подлежит закрытие находки M1 и любые AC, чьё доказательство эта дельта задевает — то есть только AC4 и AC7 (по номеру ссылки на тест-кейс, без изменения самого доказательства AC7).

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

  • git diff 5feabed..6162da8 — построчно, весь diff (см. выше состав).
  • Перечитаны актуальные редакции §3.3, §8, §12 (кейсы 12-15), AC4, AC7 в docs/specs/226-entity-parent-dedup.md на коммите 6162da8 целиком, не только diff-хунки — чтобы увидеть новый текст в контексте всего раздела, а не выдернутым из соседних решений.
  • git log --oneline -5 — подтверждён линейный путь от 5feabed (SHA r1) до текущего HEAD 6162da8, без ребейза и посторонних коммитов.
  • Прочитаны все комментарии issue #226 после публикации r1: комментарий вердикта r1 (жёлтый, M1) и ответный комментарий автора «Исправил SPEC-REVIEW r1, M1 в 6162da8» с перечислением четырёх правок — сверено построчно с фактическим diff, расхождений нет.
  • grep по всему файлу ТЗ на предмет устаревших ссылок на старую нумерацию тест-кейсов после сдвига 14→15 — не найдено (AC4/AC7/§14 мутационного гейта ссылаются на кейсы по номеру и/или по существу корректно, других мест, ссылающихся на «кейс 14» в старом смысле, нет).
  • Независимо (не по заявлению автора) перезапущены оба гейта документации, которые автор указал в хендоффе: git diff --check 5feabed..6162da8 → exit 0, чисто; node scripts/check-docs.mjs --external → Documentation checks passed (7 files, 10 external links), exit 0.
  • Код гейты (npx tsc --noEmit, npm test, npm run build) не запускались: стадия по-прежнему S4-spec-review (метки issue: bug, P1, S4-spec-review), продуктовый код не существует — их предмет отсутствует, а не отложен.
  • Остальные разделы ТЗ (§1-2, §4-7 кроме дельты, §9-11, §13 кроме AC4/AC7, §15-19) не перечитывались построчно повторно — их проверка унаследована из r1 (см. раздел ниже), т.к. дельта их текст не меняет.

Находки

Новых находок нет. Единственная находка r1 (M1) закрыта дельтой этого раунда — см. таблицу ниже.

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

Находка r1 Чем закрыта Где это видно
M1 — комбинация «явный marker на видимую вспомогательную сущность + единственный оставшийся сиблинг скрыт HA и функционально первичен (сценарий #94)» не имела ни AC, ни теста, исход был неочевиден (а) §3.3 получил явное предложение, фиксирующее исход: «если пользователь вынес видимую вспомогательную entity, а у родителя остался только HA-hidden функциональный sibling, auto-marker родителя исчезает»; (б) §8 получил зеркальное явное предложение применительно к #94 с явной пометкой «это ожидаемое следствие Q2, а не обход cover-first»; (в) §12 получил новый тест-кейс 14 с точным сценарием (видимый switch.reverse_direction + hidden-only cover.curtain → только entity-marker; явный device:D восстанавливает полную штору); (г) AC4 теперь явно ссылается на кейс 14 docs/specs/226-entity-parent-dedup.md:53-57 (§3.3), :162-166 (§8), :238-241 (§12, кейс 14), :258-260 (AC4) на коммите 6162da8; git diff 5feabed..6162da8 показывает все четыре правки одним связным diff-хунком по каждому разделу

Автор выбрал именно ту из двух альтернатив, что была предложена в r1 как «если это осознанно принимается»: auto-marker исчезает, а не «cover-first защита переживает это состояние». Это техническое решение автора о формулировке правила (PROCESS.md §7.1 — решается вердиктом ревьюера, не владельцем), и выбор согласуется с уже принятым default Q2 и с текстом, который сам владелец одобрил в r1. Ревьюер согласен: решение сформулировано явно, не как недосказанность, снабжено собственным тестом и не противоречит ничему из принятых владельцем решений Q1-Q3.

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

  • Новый текст §3.3/§8 не вводит догадку, выданную за факт: оба предложения прямо помечены как «следствие принято осознанно» / «ожидаемое следствие Q2», то есть явно относятся к уже принятому владельцем решению, а не изобретают новое продуктовое правило без него.
  • Новый тест-кейс 14 однозначен и доказуем: два состояния (только entity-marker после размещения; полная штора после добавления явного device:D) с конкретными сущностями (switch.reverse_direction, cover.curtain), не оставляет свободы трактовки.
  • Ссылки AC4→кейс14 и AC7→кейс15 (после сдвига) корректны, других мест с устаревшей нумерацией не осталось (проверено grep).
  • Оба гейта документации, заявленные автором в хендоффе, воспроизведены независимо и оба зелёные.

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

  • Полный текст ТЗ вне дельты (§1-2, §4-7 кроме тронутых предложений, §9-11, §13 кроме AC4/AC7-ссылок, §15-19) — не перечитывался заново; принят унаследованным из r1 (см. ниже), поскольку дельта этого текста не касается.
  • Код buildDevices()/seedHiddenBindings() реализации по-прежнему не существует — npx tsc --noEmit, npm test, npm run build, golden, browser smoke, performance, mutation-gate не запускались: предмет код-ревью (§2.7), не ревью ТЗ (§2.4), стадия не менялась.
  • docs/USER-GUIDE.ru.md/docs/USER-GUIDE.md/docs/FILTERING.md как release-артефакты будущей реализации — не проверялись повторно, дельта их не трогает (это по-прежнему только план в §16 ТЗ).

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

Документ: docs/reviews/SPEC-REVIEW-226-r1.md, SHA 5feabed.

Принято без повторной проверки в этом раунде, так как дельта 5feabed..6162da8 этого текста и вывода не касается:

  • Соответствие ТЗ обязательным разделам §7.1 PROCESS.md (сценарий/персона, что человек увидит, скоуп/не-скоуп, контракт поведения, модель данных и совместимость, i18n, AC1…AC10 с доказательством, план автотестов, риски, откат, release-артефакты) — все присутствуют по существу, отдельного дефекта не найдено.
  • Три продуктовых вопроса владельцу (Q1 partial ownership, Q2 hidden_by/#94, Q3 асимметрия device:D/entity:X) заданы пачкой с default и получили явные ответы до написания ТЗ — процесс §7.1 соблюдён.
  • Причина дефекта в §3 ТЗ соответствует коду src/devices.ts (claimed.add(m.binding) :1032, цикл авто-устройств :1039) и src/ha-binding-status.ts (hidden_by не участвует ни в одной активной проекции) — подтверждено построчным чтением в r1.
  • Защита #94 сформулирована дословной цитатой канона docs/FILTERING.md:190-217 и получила отдельный регрессионный тест (кейс 8, нетронутое устройство).
  • AC1…AC3, AC5, AC6, AC8, AC9, AC10 прослежены до конкретных тест-кейсов без пропусков — вывод r1 остаётся в силе, дельта этих AC не касается.
  • Алгоритм §6 (линейная сложность, запрет вложенного поиска), compatibility §9 (нет миграции/схемы/wire protocol), touch/kiosk §17 (release-blocking по docs/TOUCH-SUPPORT.md), track (обычный, не small) — выводы r1 остаются в силе без повторной проверки.
  • Раздел «Принятые предположения» §19 — признан техническими допущениями, не подменой продуктового решения; дельта этого раздела не трогает.
  • Mutation-gate §14 (два id вместо трёх из issue) — признан техническим решением автора о стратегии тестов, не продуктовой догадкой; дельта этого раздела не трогает.

Вывод

M1 закрыт по существу, новых находок дельта не создала. ТЗ готово к статусу «Готово к разработке» с точки зрения ревью ТЗ (формальный перевод статуса — не предмет этого документа).