Issue: #516 User-Visible: no
14 KiB
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.mjspatchId теперь исключает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— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
5f06a75613c26bf52de93b06acecb38930ea7c9fgit log --all --format='%H %T' | grep 5f06a75613c2 - Вердикт конвейера:
green· High 0