Files
houseplan-card/docs/reviews/CODE-REVIEW-113-r3.md
T
claude[bot] e88c23b8ee
Validate / docs (push) Failing after 34s
Validate / provenance (push) Successful in 45s
Validate / changes (push) Successful in 56s
Validate / process-gate (push) Failing after 58s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / smoke (push) Skipped
Validate / golden (push) Skipped
Validate / performance_smoke (push) Skipped
Validate / backend (push) Skipped
docs: review document for #113
Issue: #113
User-Visible: no
2026-08-19 00:11:27 +00:00

18 KiB
Raw Blame History

CODE-REVIEW-113-r3 — post-merge docs gate refresh, no product change

  • Issue: https://github.com/Matysh/houseplan-card/issues/113
  • ТЗ: docs/specs/113-optional-space-model.md, ревью ТЗ — docs/reviews/SPEC-REVIEW-113-r1.md (зелёный, Medium-1 → #184, не блокирует)
  • Предыдущие циклы:
    • docs/reviews/CODE-REVIEW-113-r1.md — зелёный, High 0, Medium 0. Автослияние не прошло (конфликт ветки с dev), возврат в S6-in-progress за ребейзом, не за переделкой.
    • docs/reviews/CODE-REVIEW-113-r2.md — зелёный, High 0, Medium 0, после ребейза на dev=c1676cf. Пайплайн слил ветку в dev и поставил S8-merged.
    • После слияния параллельный прогон Validate на dev показал красный job docs (node scripts/check-docs.mjs --external): встроенный в docs/images/screenshots.json sourceFingerprint устарел относительно src/**, изменённого продуктовым коммитом #113 (_spaceModel/src/space-model-selection.ts). Автор исправил это отдельным docs-only коммитом и вернул issue S6-in-progress → S7-code-review, чтобы не оставлять dev красным без повторной проверки (комментарий автора от 2026-08-19).
  • Диапазон: origin/dev..HEAD = один коммит acad3b3 («Refresh documentation source fingerprint»). git merge-base origin/dev HEAD = origin/dev (b443a33) — линейно, без дивергенции и без конфликта.
  • Цикл: r3/4 (счётчик по этапу код-ревью)
  • Роль: ревьюер кода (Claude), свежая сессия, без контекста реализации и без контекста собственных прогонов r1/r2.

1. Скоуп цикла r3

Единственный коммит диапазона, acad3b3:

docs/images/screenshots.json | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)

Меняются только два повторяющихся поля манифеста — sourceFingerprint (один раз, в шапке) и sourceSha256 (в каждом из 10 сценариев, то же самое значение). Ни один PNG-файл, ни captureScriptSha256, ни imageSha256, ни любой файл класса A/B в диапазоне не меняется — подтверждено самим git diff --stat (единственный изменённый путь) и построчным чтением diff'а (изменились ровно две пары хеш-строк на сценарий, форма и остальные поля манифеста — viewport/theme/language/file/imageSha256 — идентичны).

Класс файла — docs/** (класс C, AGENTS.md). Продуктовый код (src/houseplan-card.ts, src/space-model-selection.ts) в этом коммите не тронут — байт в байт совпадает с тем, что получило зелёный вердикт в r1/r2 (тот же вывод, что и в r2: origin/dev уже содержит реализацию #113, в этом коммите нет новых продуктовых строк).

Issue: #113 / User-Visible: no — корректно: манифест скриншотов документации не является пользовательским интерфейсом, а сами PNG не изменились (см. §2) — то есть это не «видимое изменение», а служебная синхронизация fingerprint-гейта с уже принятым исходным кодом.

Это не переход на новую фичу и не расширение скоупа #113: единственная причина коммита — починка гейта, который стал красным из-за уже принятого продуктового изменения этого же issue, не из-за постороннего кода. Формально это ближе к «предрелизному гейту» из PROCESS.md §11.4 (гейт называет дефект точно, исправление проверяется тем же гейтом), хотя docs — job, запускаемый на каждый push, а не строго pre-beta; автор осторожно выбрал полный цикл ревью вместо исключения §11.4, что процессом не запрещено и не требует правки с моей стороны.

2. Как проверялось — таблица гейтов

Гейт Команда Результат
Typecheck npx tsc --noEmit OK, без ошибок
Unit npm test 877/877 OK — идентично r2 (продуктовый код не менялся)
Build + 3 копии бандла npm run build, затем cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js и cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js OK, обе сверки — байт-в-байт совпадение
Именно упавший гейт node scripts/check-docs.mjs Documentation checks passed (7 files, 10 external links). — зелёный на итоговом дереве
Пересчёт fingerprint напрямую node -e "import('./scripts/source-fingerprint.mjs').then(({sourceFingerprint}) => console.log(sourceFingerprint(process.cwd())))" b58a522cc70add7b12071bb5340ad3a1ad694c1979a39b46c2cb0b73fd719333 — совпадает байт-в-байт с sourceFingerprint, записанным в коммите
Process gate node scripts/process-gate.mjs --issues диапазон origin/dev..HEAD, коммитов 1, гейт пройден, предупреждений 0

Не прогонялось, и почему:

  • Браузерные смоки (127+) — не прогонялись. Диапазон не меняет ни строки src/**, ни demo/**-кода, ни фикстур; единственный изменённый файл — JSON-манифест, потребляемый только check-docs.mjs. Ни одна из тронутых поверхностей (документационные скриншоты) не имеет функционального пути в карточке — прогон смоков не добавил бы информации к тому, что уже зелено в r1/r2 на идентичном продуктовом коде.
  • npm run golden:verify — не прогонялся. docs/images/screenshots.json — отдельный от golden-эталонов (demo/golden/baselines/**) манифест с собственным гейтом (check-docs.mjs), который прогнан и зелёный. Продуктовый рендер не менялся, пиксельного риска golden-эталонов нет.
  • python -m pytest tests_backend — не тронут ни один файл custom_components/**/*.py.
  • Performance-профили — не названы в AC, ни один hot-path не тронут; диапазон не содержит кода вообще, только JSON-метаданные.
  • Обоснование сознательное, соразмерное объёму диапазона (PROCESS.md §8): один изменённый файл, один назначенный ему гейт (check-docs.mjs), гейт прогнан и зафиксирован именно с помощью команды и её результата — не «verified» без доказательства.

3. Проверка AC (docs/specs/113-optional-space-model.md §10)

Продуктовый код, доказывающий AC1–AC10, не менялся в этом цикле (§1) — доказательства r1/r2 переносятся без изменений. Этот коммит не реализует ни одного AC заново; ниже — что именно перепроверено на итоговом дереве, а не процитировано.

AC Статус в r3
AC1–AC10 Код не менялся относительно r2 (единственный файл диапазона — docs/images/screenshots.json, не участвующий ни в одном AC из §10 ТЗ). npx tsc --noEmit и npm test (877/877) перепрогнаны на итоговом дереве и зелёные — подтверждают отсутствие регрессии, не переоткрывая доказательства по существу.

Единственное новое утверждение этого цикла — не AC ТЗ #113, а факт того, что манифест документационных скриншотов синхронизирован с текущим src/**. Оно доказано исполнением (check-docs.mjs зелёный + независимый пересчёт fingerprint, см. §2), а не пересказом.

4. Дисциплина «тест умеет падать» — что проверено исполнением

  • check-docs.mjs умеет падать на этом классе дефекта — до acad3b3 (на состоянии dev сразу после слияния r2) этот же скрипт краснел в CI ровно с сообщением screenshot source fingerprint is stale; run npm run build && node demo/docs/capture.mjs (см. слово автора и сам факт, что job docs был красным в Validate). Причина понятна и воспроизводима логикой скрипта (scripts/check-docs.mjs:118-119): сравнение manifest.sourceFingerprint !== sourceFingerprint(ROOT); это прямое сравнение, которое обязано покраснеть при любом расхождении, а не эвристика, которую можно обмануть.
  • Пересчёт fingerprint выполнен независимо от check-docs.mjs, отдельным вызовом sourceFingerprint() через node -e, и его значение сверено вручную с байтами, записанными в коммите — совпадение подтверждает, что коммит не мог быть подделан (вписан руками) и что он действительно является продуктом npm run build && node demo/docs/capture.mjs на этом дереве, как и заявлено автором.
  • PNG не менялись — сам git diff --stat не содержит ни одного .png-пути; отдельно check-docs.mjs сверяет scenario.imageSha256 с фактическим SHA-256 файла на диске для всех 10 сценариев и прошёл зелёным — то есть на диске лежат ровно те же байты, что были приняты в r1/r2, а не новый, неотрецензированный рендер.

5. Находки

Нет находок High. Нет находок Medium в диапазоне этого коммита.

Наблюдение вне скоупа диффа (не находка кода #113, заведено отдельным issue по правилу преамбулы PROCESS.md: «расхождение процесса с фактической автоматизацией не игнорируется, а заводится issue с меткой process»): канонический список Validate-джобов в AGENTS.md («CI is pinned to an exact SHA... Jobs: provenance, hacs, hassfest, frontend, smoke, golden, performance_smoke, backend») не упоминает job docs, который и стал причиной этого цикла. Строка AGENTS.md не менялась с 0f8d35f (2026-08-14), docs-job/check-docs.mjs появился позже, 88a647f (2026-08-16) — это и есть расхождение, а не пересказ известного факта. Заведён #191 (process, docs, P3), не блокирует #113 — сам этот коммит корректно работает с фактическим, не с задокументированным, набором гейтов.

6. Что проверено и корректно

  • Диапазон origin/dev..HEAD линеен (git merge-base origin/dev HEAD == origin/dev) — ветка не разошлась, конфликта нет, ребейз не требуется.
  • Единственный изменённый файл диапазона — docs/images/screenshots.json, класс C; не задевает ни одного файла класса A/B. Трейлеры коммита (Issue: #113, User-Visible: no) соответствуют содержанию (нет пользовательского поведения, только служебные хеши).
  • sourceFingerprint/sourceSha256, записанные в коммите, воспроизведены независимым прогоном sourceFingerprint() на этом дереве и совпали байт-в-байт — коммит не является догадкой или скопированным чужим значением.
  • captureScriptSha256 и все 10 imageSha256 в манифесте не изменились и совпадают с файлами на диске (подтверждено зелёным check-docs.mjs) — PNG не перегенерировались заново без рецензии, ранее принятые скриншоты используются как есть.
  • Продуктовый код (src/houseplan-card.ts, src/space-model-selection.ts) байт-в-байт идентичен версии, получившей зелёный вердикт в r1 и повторно в r2 — AC1–AC10 не требуют переоткрытия.
  • Быстрые гейты (tsc --noEmit, npm test 877/877, npm run build + сверка 3 копий бандла) — зелёные на итоговом дереве.
  • node scripts/process-gate.mjs --issues — зелёный, 0 предупреждений, диапазон 1 коммит.
  • docs/CHANGELOG.md/docs/CHANGELOG.ru.md корректно не тронуты — User-Visible: no.

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

  • Полный набор браузерных смоков и golden:verify — обоснование в §2 (диапазон не содержит ни строки src/**/demo/**-кода, только JSON-манифест документационных скриншотов).
  • pytest tests_backend — класс A/B бэкенда не тронут.
  • Performance-профили — не названы в AC, не затронуты (диапазон без кода).
  • Содержательное AC1–AC10 переисполнение «с нуля» — не требуется: продуктовый код не менялся байт в байт относительно r1/r2 (подтверждено git diff --stat, не предположением).
  • Medium-1/#184 (fallback-семантика ТЗ §6, explicit-id команды) — по-прежнему отдельный issue вне скоупа этого код-ревью.
  • Правомерность конкретно выбранного автором пути (полный цикл вместо §11.4-исключения) по существу не оценивалась дальше констатации, что оба варианта процессом допустимы для этого случая; выбор автора не создаёт находки.

8. Вердикт

Единственный коммит цикла — служебная синхронизация fingerprint-манифеста документационных скриншотов с уже принятым (дважды зелёным) продуктовым кодом #113; PNG не менялись, продуктовый код не менялся, упавший гейт (check-docs.mjs) воспроизведён и подтверждён зелёным, а записанный в коммите fingerprint независимо пересчитан и совпал байт-в-байт. Все быстрые гейты зелёные. High: 0. Medium: 0 в диапазоне диффа. Одно наблюдение вне скоупа диффа заведено отдельным issue (#191, process), не блокирует.

Вердикт: зелёный · цикл r3/4 · High: 0 · Medium: 0 → #191 (вне скоупа диффа, не блокирует) · Документ: docs/reviews/CODE-REVIEW-113-r3.md