16 KiB
CODE-REVIEW — issue #441 · заход r2
Ветка issue/441-vacuum-route-draft, HEAD на ревью 75478905 (проверено
git rev-parse HEAD непосредственно перед выводом, §2.7).
Почему это заход r2, а не r1
Заголовок задачи, переданный этой сессии, утверждает «заход r1 · блокирующих циклов 0 из 2». Это не подтверждается материалом:
- в комментариях issue #441 уже есть терминальный вердикт код-ревью:
Вердикт: жёлтый · заход r1 · блокирующих циклов 1/2 · High: 0 · Medium: 1 → в задаче(комментарийclaude,IC_kwDOTOcLQM8AAAABSa2lLw, 19:35:18 UTC); - следом (19:35:28 UTC) владелец подтвердил: «Автоматическое ревью не
отработало… Статусная метка не менялась» — то есть вердикт реальный,
но шаг конвейера, переставляющий метку после вердикта (§10.4), не
выполнился, и задача осталась висеть в
S7-code-review, откуда её забрала эта сессия повторно; - полный документ того раунда уже закоммичен в ветку самим конвейером
(
75478905 docs: review document for #441, авторclaude[bot]) — это штатный механизм публикации (§10.4: «кладёт документ вdocs/reviews/ветки задачи»), не постороннее вмешательство; - SHA того раунда назван в документе —
fa41d298— и он не осиротел:git diff fa41d298..HEADрезолвится и виден ниже.
Таким образом это второй заход ревью, разбор — по дельте (§2.10), а не
заново. Файл docs/reviews/CODE-REVIEW-441-r1.md уже существует, второй
документ с тем же номером затёр бы его, поэтому этот — r2.
Присвоенный этой сессии заголовок «r1 · 0/2», видимо, следствие того же
сбоя конвейера, который не переставил метку: трекер раундов не увидел
уже опубликованный r1. Само по себе это не код-находка issue #441 и не
блокирует вердикт, но чтобы бюджет §4 не потерялся — ниже он посчитан по
факту (см. «Вердикт»), а не по переданному заголовку.
Материал предыдущего раунда
- Документ:
docs/reviews/CODE-REVIEW-441-r1.md(в этой же ветке, коммит75478905). - SHA раунда:
fa41d298(fix: keep vacuum routes pending until a floor is chosen). - Вердикт r1: жёлтый, High 0, Medium 1 в скоупе — красный
check-docs.mjsнаfa41d298(устаревший отпечаток скриншотов документации).
Дельта r1 → r2
git diff fa41d298..HEAD --stat
docs/images/screenshots.json | 25 ++--
docs/reviews/CODE-REVIEW-441-r1.md | 246 +++++++++++++
Два файла, оба класса C (документация/артефакт ревью). Продуктовый код
(src/**), тесты и смоки, тронутые в fa41d298, дельтой r1→r2 не
задеты — git diff fa41d298..HEAD -- src test demo scripts docs/CHANGELOG.md docs/CHANGELOG.ru.md пуст. Это делает дельту
локальной по §2.10: полный повторный разбор AC не требуется, только
проверка закрытия находки r1 плюс дешёвые гейты.
docs/reviews/CODE-REVIEW-441-r1.md — служебный артефакт публикации
предыдущего раунда, не правка автора; содержательного разбора не
требует.
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
Medium: node scripts/check-docs.mjs красный на fa41d298 — отпечаток скриншотов документации устарел после правки src/editors/vacuum-maps-section.ts |
Коммит 0ea9c0f5 docs: refresh canonical screenshots for #441 обновил sourceFingerprint/sourceSha256 в docs/images/screenshots.json на все 10 сценариев; imageSha256 каждого сценария не изменился (диалог, который правит #441, ни в одном сценарии не рендерится — пиксели те же), манифест получил acceptance.lastWriteWasFingerprintOnly: true — след легитимной приёмки scripts/docs-accept.mjs (fingerprint-only ветка acceptedDocsManifest, docs-accept.mjs:107), а не самодельной правки JSON |
git diff fa41d298..HEAD -- docs/images/screenshots.json; перепрогнан node scripts/check-docs.mjs на HEAD 75478905 → Documentation checks passed (7 files, 10 external links) (было ERROR screenshot source fingerprint is stale) |
Находка закрыта корректно и через штатный инструмент приёмки
(docs-accept.mjs, а не ручная правка screenshots.json мимо
проверки совпадения пикселей) — именно та дисциплина, которую требует
§8 («скриншоты снимаются только… принимаются локально docs:accept»).
Унаследовано из r1
Без повторной проверки принято (документ docs/reviews/CODE-REVIEW-441-r1.md,
материал — SHA fa41d298, тот же SHA подтверждён этой сессией как
резолвящийся предок HEAD):
- AC1 (черновик до выбора этажа) — доказательство
beginVacuumRouteDraft(src/vacuum-route-edit.ts:34) иtest/vacuum-routes.test.mjs:279— код не менялся дельтой; для собственного спокойствия эта сессия всё же независимо повторила мутацию r1 (не обязательна по §2.10, сделана как дешёвая проверка): временно заменилаspace: routes.length ? '' : dockSpaceнаspace: dockSpace, пересобралаtest-build(npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs) и прогналаnode --test test/vacuum-routes.test.mjs→not ok 25 - новый маршрут живёт в черновике до выбора этажа (#441 AC1),# fail 1; откат мутации вернул# pass 32 / # fail 0. Рабочее дерево после отката чисто (git status --shortпуст). AC1 подтверждён на текущем SHA, а не только унаследован по документу. - AC2 (только валидная атомарная запись) —
commitVacuumRouteDraft(src/vacuum-route-edit.ts:39-56),test/vacuum-routes.test.mjs:287, смокиnoEmptySpaceEverSubmitted/rejectedPayloadWasValid/retryKeepsExactIdentity— код не менялся, наследуется по документу r1. - AC3 (отмена/отказ не оставляют фантом) —
persistRoutes/confirmDraft(src/editors/vacuum-maps-section.ts), смокиcancelLeavesAcceptedRoutes/rejectionRestoresAcceptedMarker/rejectionKeepsEditorUsable— код не менялся, наследуется по документу r1. - Наблюдение r1 про побочное усиление
retarget/drop(переход на общийpersistRoutes/rollbackOptimistic) и про отсутствие новых ключей i18n — без изменений, код не тронут дельтой. - Оценка
docs/SCOPE.md(J4/J6) — без изменений, продуктовый скоуп не менялся.
Гейты — что прогнал в этом раунде и с каким результатом
Дельта r1→r2 не трогает src/**/test/**, поэтому по §2.10 достаточно
дешёвых гейтов; они прогнаны заново на HEAD 75478905, а не унаследованы:
| Гейт | Команда | Результат |
|---|---|---|
| Typecheck | npx tsc --noEmit |
чисто, без вывода |
| Тесты | npm test |
# tests 1857 · # pass 1856 · # fail 0 · # skipped 1 — совпадает с заявленным в r1 |
| Сборка + синхронизация бандла | npm run build, затем git status --short |
dist пересобран, working tree чист после сборки — dist/houseplan-card.js и custom_components/houseplan/frontend/houseplan-card.js совпадают в коммите (cmp → без вывода, идентичны) |
| Документация | node scripts/check-docs.mjs |
зелёный: Documentation checks passed (7 files, 10 external links) — находка r1 закрыта (см. выше) |
| Мутация AC1 (доп. проверка этого раунда) | временный откат src/vacuum-route-edit.ts:34 → space: dockSpace, npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs && node --test test/vacuum-routes.test.mjs |
not ok 25 на мутанте, # pass 32 / # fail 0 после отката — дисциплина «тест умеет падать» подтверждена независимо |
| Смок AC1–AC3 | node demo/smoke_vacuum_route_draft.mjs (после npm run bundle:sync, иначе смок падает на отсутствующем demo/srv/assets/houseplan-card.js — сгенерированный, не коммитится, #255) |
все 14 проверок true, OK |
Не прогонялись повторно (дельта их не задевает, обоснование см. в
документе r1, наследуется): smoke-select.mjs по полному диффу,
golden:verify, pytest tests_backend, npm run invariants,
performance-профили, остальные точечные смоки (smoke_vacuum_firstuse,
smoke_vacuum_multifloor, smoke_save_race, smoke_config_writer) —
их результат на fa41d298 уже зафиксирован в r1 и код, который они
покрывают, не менялся.
Трейлеры дельты: 0ea9c0f5 — Issue: #441, User-Visible: no (верно:
обновление служебного отпечатка, а не пользовательского поведения,
changelog не требуется); 75478905 — Issue: #441, User-Visible: no
(служебный артефакт публикации ревью, класс C).
Находки
Нет. Единственная находка r1 (Medium, в скоупе) закрыта корректно и через штатный инструмент. Новых находок дельта r1→r2 не вносит — она состоит из точечного обновления отпечатка документации и служебного коммита самого конвейера.
Что проверено и корректно (без отдельной находки)
docs/images/screenshots.json: у всех 10 сценариевimageSha256не изменился при обновленииsourceFingerprint— подтверждает заявление r1, что правка не задевает ни один заскриншоченный экран (диалог второго маршрута пылесоса нигде не снимается для документации).- Приёмка прошла через
scripts/docs-accept.mjs(веткаlastWriteWasFingerprintOnly), а не через ручную правку JSON — соответствует требованию §8 «коммит скриншотов делает человек» и «приёмка отказывает, если кандидат снят не с этого дерева»: сам скрипт это проверяет (verifyDocsCandidate), а не декларация автора. docs/reviews/CODE-REVIEW-441-r1.mdкорректно оформлен как документ своего раунда и не требует правок задним числом (документы ревью не переписываются, только дополняются новым заходом).
Чего не проверял
- Полный повторный разбор AC1–AC3 по коду и всем смокам — не требуется
по §2.10, т.к. дельта не трогает
src/**/test/**/demo/**; AC1 дополнительно перепроверен мутацией (см. «Гейты»), AC2/AC3 унаследованы. npm run golden:verify,pytest tests_backend,npm run invariants, performance-профили — не прогонял; обоснование то же, что в r1 (View, backend.py, геометрия/ссылки на неё не затронуты ниfa41d298, ни дельтой r1→r2).node scripts/smoke-select.mjs --base origin/dev --head HEADпо полному диффу — не перегонял: набор символов на изменённых строках не изменился с r1 (дельта не трогает код), решение по каждому пункту из r1 остаётся в силе.- Реальность прогона CI-джобы
Docs screenshotsдля коммита0ea9c0f5(не видна из репозитория) — доверие основано на структурном доказательстве самогоscripts/docs-accept.mjs(совпадениеimageSha256с уже закоммиченными файлами и наличиеacceptance.lastWriteWasFingerprintOnly), а не на слепом заявлении автора; независимый пересчётvisualFingerprint(root)на HEAD не делал отдельно отcheck-docs.mjs, который эту сверку и выполняет.
Вердикт
Зелёный. AC1–AC3 подтверждены (AC1 — независимо на HEAD этой сессией,
AC2/AC3 — унаследованы из r1 по неизменному коду), единственная
Medium-находка r1 закрыта штатным инструментом и подтверждена зелёным
check-docs.mjs на HEAD 75478905. Новых находок нет.
Бюджет циклов (§4): r1 был жёлтым и потратил 1 цикл из 2 (лёгкий/короткий трек, лимит код-ревью — 2, §5.1). Этот заход (r2) зелёный и цикл не образует (#227) — израсходовано остаётся 1 из 2, а не 0 из 2, как было в заголовке этой сессии; расхождение объяснено в разделе «Почему это заход r2».
Материал раунда
- Ветка:
issue/441-vacuum-route-draft, коммит75478905d5eb— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
6e2f7f4813e3b45927eb282b1e5fdd62b872d019git log --all --format='%H %T' | grep 6e2f7f4813e3