Files
houseplan-card/docs/reviews/CODE-REVIEW-516-r2.md
T
claude[bot] 9293109ba1
Проверка (CI) / Классификация изменённых файлов (push) Successful in 35s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 53s
Проверка (CI) / Мутанты по диффу (1/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (2/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (3/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / HACS: валидация репозитория (push) Failing after 22s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 22s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m1s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 11m54s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 4m28s
docs: review document for #516
Issue: #516
User-Visible: no
2026-09-09 21:39:17 +00:00

14 KiB
Raw Blame History

CODE-REVIEW-516-r2

Issue: #516 — «merge-candidate: patch-id кандидата включает собственный документ ревью» Заход: r2 · блокирующих циклов израсходовано 0 из 2 (лёгкий трек) Материал: 18eded340c40891115a182276b12e01afb376539 (рабочая копия, зафиксировано пайплайном) Вердикт: зелёный · High: 0 · Medium: 0

Скоуп

Class B (scripts/**, test/**) — внутренняя механика конвейера ревью, не продуктовый код src/**. docs/SCOPE.md не применим напрямую: задача не закрывает Core user job, а чинит собственную инфраструктуру ревью (патч-id кандидата ошибочно включал docs/reviews/**, из-за чего каждый зелёный кандидат после сдвига dev возвращался «дифф изменился» — #514, #508).

ТЗ (лёгкий трек, тело issue), три AC:

  • AC1 — сдвиг dev только документами ревью не возвращает зелёный кандидат на повторное ревью (тест на реальном git).
  • AC2 — реальное изменение содержимого патча при ребейзе по-прежнему возвращает в S7 (существующий тест).
  • AC3 — мутант пойман штатным раннером. User-Visible: no.

Почему разбор снова полный, а не по дельте

Между материалом r1 (8c13b5d1, см. вердикт в issue) и текущим 18eded34 нет ни единой строки нового кода: git log --oneline origin/dev..HEAD показывает ровно два коммита — 6ee9a461 (тот же код, что читал r1) и 18eded34 (публикация документа CODE-REVIEW-516-r1.md, class C). Диапазон между ними — чистый ребейз на dev, который за это время подвинулся на ad2858a8 (документы ревью #508 и #515). Это буквально случай из §7.2 — «ребейз на ушедший вперёд dev, после ребейза это другой код» — поэтому по инструкции разбор веду полным, а не как экономию по находкам r1 (которых и не было: r1 дал 0/0).

Отдельно: ожидание владельца, что механизм reuse (#499) применит зелёный вердикт r1 без вызова модели, здесь не сработало — иначе меня бы не вызвали. Причина в бутстрэпе, не в этом diff'е: #515 (сосед по истории dev, 5a1cddea) чинит именно то, что якоря материала в документе ревью снимаются после ребейза, а не до — но документ r1 для #516 создавался в переходном окне, когда эта правка либо ещё не была в dev, либо якорь всё равно указывал на осиротевшее дерево. Это не дефект #516: scripts/merge-candidate.mjs и scripts/review-doc-guard.mjs --reuse — разные шаги конвейера, и вопрос принадлежит #515/#499, не этой задаче. Упоминаю как объяснение, почему модель снова читает тот же код, а не как находку.

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

Дешёвые гейты не гонял целиком — Validate с мутантами уже зелёный на точном материале 18eded34: https://github.com/Matysh/houseplan-card/actions/runs/34407159664 (комментарий владельца в issue подтверждает: красный workflow_sync был устранён зеркалом aeb0a473, повторный dispatch зелёный). tsc/build/полный npm test не перегонял по этой причине.

Прогнал сам, точечно, поскольку код — предмет этого раунда:

  • node --test test/merge-candidate.test.mjs → 13/13, включая новый #516 AC1 на настоящем git.
  • node scripts/mutation-gate.mjs --id=merge-rereviews-own-review-doc → ok чистый прогон + ok merge-rereviews-own-review-doc: тест покраснел, как обязан → поймано 1 из 1. Дисциплина «тест умеет падать» выполнена этим же прогоном (гейт сам откатывает патч и проверяет красный/зелёный статус).
  • node scripts/mutation-gate.mjs --check → весь реестр структурно валиден. Побочно нашёл дублирующийся id: 'openings-filled-tunnel-dark' (два определения с одним id) — этот diff его не касается (не входит в список изменённых файлов), дублирование существовало и до #516. Вне скоупа этой задачи, отдельный issue не завожу: находка мелкая, не блокирует и не доказана как реальный дефект поведения гейта (может быть двумя вариантами сценария под одним именем) — стоит того, чтобы кто-то посмотрел, не стоит того, чтобы заводить S1-new по неподтверждённому подозрению.
  • node scripts/smoke-select.mjs --base origin/dev --head HEAD → «Исполняемого frontend-диффа нет» — смоки не выбираются, src/** не тронут. Ничего не прогонял из demo/smoke_*.mjs.
  • Полное чтение scripts/merge-candidate.mjs и всего diff (git show 6ee9a461).

Не применимо и не прогонялось: check-docs (нет src/**), инварианты модели (нет геометрии/layout/marker.space), golden:verify (нет рендера), pytest tests_backend (нет custom_components/**/*.py), performance-профили (не названы в AC).

Разбор по AC

AC1 — подтверждено #516 AC1 (test/merge-candidate.test.mjs:271) на настоящем git: dev двигается только чужим документом ревью (CODE-REVIEW-8-r2.md), ветка несёт свой (CODE-REVIEW-9-r1.md); после ребейза patchId(materialBase, material) === patchId(devNow, candidate) (оба через новый pathspec ':!docs/reviews', scripts/merge-candidate.mjs:116-120), decideMerge идёт в push через Validate, комментария «дифф изменился» нет. Прогнал лично — зелёный.

AC2 — существующий тест patch-id изменился при ребейзе — S7-code-review (test/merge-candidate.test.mjs:130, fakeOps) не тронут этим diff'ом и остаётся зелёным: он проверяет ветку decideMerge при patchIdEqual: false, логика которой в этом diff'е не менялась (менялся только состав диффа, который в неё попадает, не сама ветка решения). Отдельно реальный git-тест «чистый ребейз с равным patch-id и изменённым поведением идёт через Validate» (:172) подтверждает, что exclusion docs/reviews не открыл дыру для настоящих поведенческих изменений вне docs/reviews — там patch-id равен намеренно (сценарий «20→40»), и это не про AC2, а про соседний инвариант, который diff не задевал.

AC3 — merge-rereviews-own-review-doc (scripts/mutation-gate.mjs, find/replace возвращает старый git diff --full-index from to без pathspec) поймано штатным mutation-gate.mjs 1 из 1, лично воспроизведено. User-Visible: no — оба коммита (6ee9a461, 18eded34) несут Issue: #516 и User-Visible: no; changelog не тронут — корректно, никакого видимого пользователю поведения нет.

Симметрия с reviewedFresh

Заявление автора «patch-id обязан считаться так же, как reviewedFresh» проверено чтением: reviewedFresh (scripts/merge-candidate.mjs:174-176) уже использовал ops.diffNames(material, actual, ['.', ':!docs/reviews']) — эта строка не входит в diff #516 (существовала раньше), и patchId теперь получил тот же pathspec. Симметрия реальна, не декларативна.

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

  • Единственная содержательная правка — scripts/merge-candidate.mjs patchId теперь исключает docs/reviews/**, ровно по описанной причине в issue.
  • Тест и мутант независимо подтверждают обе стороны: patch-id равен, когда разница — только документы ревью (AC1); patch-id по-прежнему различается при настоящем изменении контента (AC2, не тронут).
  • Трейлеры на месте на обоих коммитах ветки.
  • Диапазон изменений не выходит за scripts/**, test/** — class B, issue переиспользован корректно (тот же #516).
  • Дублирование id в реестре мутантов — предсуществующее, не в скоупе, не блокирует.

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

  • npx tsc --noEmit, npm test (полный), npm run build — не гонял: зелёный Validate с мутантами уже есть на точном SHA (ссылка выше), включает эти гейты.
  • check-docs, инварианты модели, golden:verify, browser-смоки, pytest tests_backend, performance — не применимы диффом (нет src/**, нет геометрии, нет рендера, нет Python).
  • Историю бутстрэпа reuse/#499/#515 (почему модель вызвана снова вместо переиспользования вердикта r1) не разбирал глубже уровня «это другой шаг конвейера, не предмет #516» — это не входит в AC этой задачи.

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

r1 (материал 8c13b5d1) дал вердикт зелёный, High: 0, Medium: 0 — находок не было, закрывать нечего.

Находка r1 Чем закрыта Где видно
— — r1 не содержал находок; таблица пуста по построению

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

Ничего не принято вслепую — код между материалом r1 (8c13b5d1) и текущим материалом (18eded34) идентичен (см. раздел «Почему разбор снова полный»), поэтому весь разбор AC1–AC3 в этом документе — самостоятельная повторная проверка, а не перенос заявлений автора. Единственное, что действительно наследуется без личного перезапуска: зелёный результат полного Validate (tsc/test/build/mutants) на этом точном SHA 18eded34 (https://github.com/Matysh/houseplan-card/actions/runs/34407159664) — беру его как основание не гонять tsc/build/полный npm test самому, как и разрешает вводная инструкция для этого раунда. Документ r1 (docs/reviews/CODE-REVIEW-516-r1.md) как источник для этого использован только как ссылка на факт «модель уже читала этот код 09.09», не как замена собственной проверки.


Материал раунда

  • Ветка: issue/516-patch-id-without-review-docs, коммит 18eded340c40 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 5f06a75613c26bf52de93b06acecb38930ea7c9f
    git log --all --format='%H %T' | grep 5f06a75613c2
    
  • Вердикт конвейера: green · High 0