Files
houseplan-card/docs/reviews/CODE-REVIEW-454-r4.md
T
claude[bot] 5784a0e271
Проверка (CI) / Классификация изменённых файлов (push) Successful in 25s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 51s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 53s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 19s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 18s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 7m16s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 9m37s
Проверка (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
docs: review document for #454
Issue: #454
User-Visible: no
2026-09-04 17:45:17 +00:00

16 KiB
Raw Blame History

CODE-REVIEW — issue #454 · заход r4

  • Issue: https://github.com/Matysh/houseplan-card/issues/454
  • Материал: git rev-parse HEAD = 2a883217c156c349e4cca9bc3bd5a75d85b7b928 (ветка issue/454-review-round-counter).
  • Предыдущий раунд: r3, жёлтый, документ docs/reviews/CODE-REVIEW-454-r3.md, материал 4b443d8c (там же был rev-parse HEAD того раунда).
  • Дельта r3→r4: git diff 4b443d8c..HEAD — три коммита:
    • 9e7ae520 docs: публикация документа r3 (сам ревью-файл, не код);
    • d5e11452 fix: закрытие M1 (комментарий засчитывается вердиктом только по документу своей задачи), 5 файлов, +174/−27;
    • 2a883217 chore: пересборка бандла под новый отпечаток исходников — несвязанная поддержка (см. «Вне дельты» ниже), уже с Baseline-Reviewed. Ребейза не было, дельта локальна (диапазон origin/dev...HEAD не изменился по существу с r3, кроме этих трёх коммитов) → разбор по дельте (PROCESS.md §2.9/§2.10), а не заново.

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

Находка Чем закрыта Где видно
M1 (Medium, в скоупе) — резервный счёт по комментариям матчил голую подстроку маркера (CODE-REVIEW/SPEC-REVIEW) в любой прозе, включая цитаты чужих задач и чужого этапа; на самих данных #454 это дало код-ревью-раунду имя r3 вместо r1, а заявление ТЗ §3 «перерасчёт невозможен по построению» не выполнялось для attemptComments/spentComments Правило заменено на два условия: комментарий обязан (а) объявлять вердикт строгой строкой verdictDeclaration, (б) называть документ этой задачи и этого этапа — <MARKER>-<NUM> вместо голого <MARKER>. Формулировка §3 ТЗ смягчена до факта («удвоение невозможно, завышение одной из компонент — возможно»). Добавлен ::warning:: при расхождении attemptComments/attemptFiles, привязка к номеру задачи и уточнение гарантии — все три направления, предложенные в r3, взяты одновременно scripts/review-doc-guard.mjs:452-486 (stageVerdictComments, commentCounters), коммит d5e11452; .github/workflows/process.yml:97-190 (счёт по комментариям вынесен из inline-jq в модуль, --comments/--spent-list); docs/specs/454-review-round-counter.md §3 и таблица AC5; тест вердикт этапа опознаётся по документу ЭТОЙ задачи (#454 AC5, #89) и чужой номер задачи не засчитывается своим (#454 AC5), test/review-doc-guard.test.mjs:456-472; мутант review-comment-source-ignores-issue-number (scripts/mutation-gate.mjs:2442-2455)

Перепроверено исполнением, не со слов автора. Собрал реальные данные #454 (gh issue view 454 --json comments, файл docs/reviews/CODE-REVIEW-454-r3.md — единственный опубликованный код-ревью-документ на ветке) и прогнал новый CLI node scripts/review-doc-guard.mjs --counters --marker=CODE-REVIEW --num=454 ... буквально так, как его вызывает process.yml:

::notice::раунды по файлам 3; заход: файлы 4, комментарии 2; циклы: файлы 0, комментарии 1
attempt=4
spent=1

attemptComments=2 (было 3 на живом логе guard r3-прогона) — оба посторонних совпадения (зелёный SPEC-REVIEW r2-вердикт и хендофф-комментарий «Реализация готова», оба цитировавшие чужие CODE-REVIEW-* документы в прозе) больше не матчат own-фильтр, потому что ни один не содержит буквальную подстроку CODE-REVIEW-454. Единственный засчитанный — сам r3-вердикт (жёлтый), spentComments=1. attemptFiles=4 (раунд 3 существует → следующий r4), spentFiles=0 — документ CODE-REVIEW-454-r3.md не объявляет вердикт машиночитаемой строкой внутри себя (раздел «## Вердикт» там — проза без строки Вердикт: жёлтый · …, это отдельный, унаследованный из ТЗ §2 класс «документ есть, строка Вердикт: в нём нет» — не новый дефект дельты и не относится к M1). max(4,2)=4, max(0,1)=1 — совпадает с «заход r4 · циклов 1/4» из шапки задачи. M1 закрыта.

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

Без повторной проверки принимаю (документ docs/reviews/CODE-REVIEW-454-r3.md, материал 4b443d8c):

  • AC1 (attempt = max(номер)+1), AC2/AC2b (фикстуры #449 реальная и реконструированная), AC3 (имя файла не повторяется), AC4 (зелёный цикл не тратит), AC6 (отказ публикации не занижает счёт), AC7 (нет ветки/мусор на входе не роняет guard), AC9 (логика в тестируемом модуле, не в inline-shell) — дельта их не касается, файлы/тесты, доказывающие их, не менялись между 4b443d8c и HEAD (проверено git diff 4b443d8c..HEAD -- test/review-doc-guard.test.mjs — новые тесты только про AC5/комментарии).
  • AC8 (process.yml идентичен в main и dev) — план зеркалирования после мержа обоснован в r3 и не изменился.
  • Класс изменения B, User-Visible: no на всех коммитах — трейлеры проверены отдельно ниже для новых коммитов дельты, старые (8d826320, dc76c5b2, 4b443d8c) не перепроверял.
  • Наблюдение r3 (не находка): docs/specs/README.md — строка #454 вставлена не по возрастанию номера. Косметика, не блокирует, не повторяю как находку.

Вне дельты, но заслуживает упоминания — 2a883217

Коммит 2a883217 (пересборка бандла) не относится к предмету #454 (счёт раундов ревью), это независимая починка красного dev, найденная и исправленная автором по собственной инициативе между r3 и r4 (дефект: package.json, изменённый в #455, не был прогнан через bundle:sync, фингерпринт разошёлся). Проверил сам, а не поверил описанию:

  • git show 2a883217 -M для houseplan-card-*.js (крупнейший переименованный чанк, 96 изменённых строк из 5676): все 44 изменившиеся пары строк дают одинаковую длину старой и новой стороны (проверено построчно, включая гигантские минифицированные строки 20037/74688/193139 байт) — сильный признак того, что правки это подстановка фингерпринта и имён чанков, а не смена логики; я не нашёл ни одной пары разной длины.
  • Трейлеры коммита: User-Visible: no, Issue: #454, Baseline-Reviewed: .../actions/runs/33895243347 (ссылка на упавший прогон, который и обнаружил расхождение — process-gate требует Release либо Baseline-Reviewed для коммита только класса D, оба варианта допустимы по scripts/process-gate.mjs:246-249, содержательной проверки «зелёности» самой ссылки правило не делает).
  • Дифф не трогает src/**, custom_components/**/*.py — не App-код.

Не блокирует и не относится к AC #454; упоминаю для полноты, не как находку.

Как проверялось — гейты

Дешёвые гейты уже подтверждены Validate на 2a883217 (green, run 33900588440) — tsc, npm test, npm run build со сверкой бандла перегонять не обязан, но перегнал сам для дельты (код изменился с r3):

Гейт Команда Результат
Typecheck npx tsc --noEmit чисто, без вывода
Unit-тесты npm test 1940 pass / 0 fail / 1 skip
Mutation gate node scripts/mutation-gate.mjs --check exit 0; все 4 review-* мутанта, включая новый review-comment-source-ignores-issue-number, пойманы (ok)
check-docs node scripts/check-docs.mjs passed (7 files, 12 links) — не обязателен (src/** не тронут), прогнан для полноты
Реальный прогон CLI на живых данных #454 node scripts/review-doc-guard.mjs --counters --marker=CODE-REVIEW --num=454 --comments=<gh issue view --json comments> --docs=<CODE-REVIEW-454-r3.md> attempt=4, spent=1 — совпадает с ожидаемым и с шапкой задачи

Не гонял: npm run golden:verify, demo/smoke_*.mjs, python -m pytest tests_backend, performance-профили, npm run invariants — дельта не трогает src/**, рендер, геометрию, custom_components/**/*.py ни бэкенд. smoke-select.mjs не запускал по той же причине (диапазон вне поверхностей демо-стенда).

AC — таблица доказательств (только задетые дельтой)

AC Критерий Доказано Комментарий
AC5 Вердикт чужого этапа/чужой задачи не влияет на счёт (#89) — по имени файла и по прозе комментария unit + мутант, перепроверено исполнением на реальных данных #454 stageVerdictComments/commentCounters (review-doc-guard.mjs:452-486), тесты test/review-doc-guard.test.mjs:456-472, мутант review-comment-source-ignores-issue-number. Живой прогон подтвердил: attemptComments упал с 3 (r3) до 2 (r4) — оба ложных совпадения исчезли
AC9 Логика в тестируемом модуле, не в inline-shell unit, чтением тест «guard считает раунды скриптом, а не inline-shell» по-прежнему проходит после смены аргументов --comment-attempt/--comment-spent → --comments/--spent-list

Остальные AC не задеты дельтой — см. «Унаследовано из r3».

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

  • M1 закрыта: причина (голая подстрока маркера) устранена, решение подтверждено и юнитом, и мутантом, и независимым прогоном на реальных данных задачи, а не только словами автора.
  • Регекс own = new RegExp(\${marker}-${num}(?![0-9])`)устойчив к коллизиям номеров-подстрок (проверил вручную:num=454не матчитCODE-REVIEW-4540-..., не матчит CODE-REVIEW-1454-...; num=45не матчитCODE-REVIEW-454-...` — во всех случаях out благодаря негативному lookahead и жёсткой смежности марker-num).
  • CLI-обвязка (--comments, --spent-list) согласована с форматом gh issue view --json comments — проверил gh issue view 454 --json comments вживую: ключ comments, элементы несут .body/.url, ровно то, что читает commentCounters/payload.comments || payload.
  • spent_list теперь строится тем же кодом, что и число (не рассинхронизируется).
  • Трейлеры коммитов d5e11452, 9e7ae520, 2a883217: Issue: #454 есть у всех, User-Visible: no корректно для класса B/D, changelog не требуется.
  • process.yml идентичен между HEAD и веткой на момент проверки; расхождение с main ожидаемо и объяснено (зеркалирование после мержа).

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

  • golden:verify, smoke_*.mjs, pytest tests_backend, performance, npm run invariants — diff не касается рендера/геометрии/бэкенда/perf.
  • Реальный прогон изменённого guard-джоба целиком на GitHub Actions (сам workflow ещё не в main/dev) — логика проверена юнитами, мутантом и прямым вызовом CLI на данных, снятых с живого API; часть про git ls-remote/постраничный лимит contents не менялась в этой дельте и не перепроверялась повторно (наследую из r3).
  • Побайтовое сравнение бандла 2a883217 вне одного (крупнейшего) чанка houseplan-card-*.js — остальные переименованные чанки различаются 2 строками (импорт по новому имени), не разбирал их так же подробно; риск оценил как низкий (переименование = констант-строка, тот же паттерн).

Вердикт

Один Medium закрыт без нового Medium/High. Дельта локальна, гейты зелёные (сам прогнал + Validate на HEAD уже зелёный), AC5 передоказан на реальных данных задачи.

Документ: docs/reviews/CODE-REVIEW-454-r4.md (публикуется шагом конвейера).


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

  • Ветка: issue/454-review-round-counter, коммит 2a883217c156 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: a7f0666a126e40cb40f4ba8eb33b0278f3fe3ec1
    git log --all --format='%H %T' | grep a7f0666a126e
    
  • ТЗ docs/specs/454-review-round-counter.md, блоб 2d236d4f481565d3188ceb2670f97df003783084
    git log --all --find-object=2d236d4f481565d3188ceb2670f97df003783084 -- docs/specs/454-review-round-counter.md