16 KiB
CODE-REVIEW-749-r1
Issue: #749 · Репозиторий: Matysh/houseplan-card · Этап: code · Трек: show Заход: r1 · блокирующих циклов израсходовано 0 из 2
Материал раунда
- SHA:
9bf35aecb0180b7fce7b54340574902448489f4c - Диапазон:
git log --oneline origin/dev..HEAD→ один коммит9bf35aec fix(process): integrate runs every pipeline script from one dev snapshot (#749) git diff origin/dev...HEAD --stat:.github/workflows/_process.yml,PROCESS.md,scripts/mutation-registry.mjs,test/process-integrate-tools.test.mjs(новый),test/process-track.test.mjs,test/publish-push-refusal.test.mjs,test/review-doc-guard.test.mjs,test/review-result-gate.test.mjs,test/reviews-index.test.mjs,test/status-label.test.mjs— 351 добавлено / 45 удалено.- Ветка
issue/749-integrate-scripts-from-devкdevне приводилась (трек show, §10.4, #696):devвпереди на 13 коммитов, слияние без конфликта (git merge-base=ffa13c66, чистый диапазон). Это ожидаемо дляshowи не находка. - Validate на этом SHA зелёный:
https://github.com/Matysh/houseplan-card/actions/runs/36875424244 — дешёвые
гейты (
tsc --noEmit,npm test,npm run build+ сверка бандла) приняты без повторного прогона.
Скоуп
Класс B (инфраструктура: scripts/, .github/**, тесты) + класс C
(PROCESS.md). Задача — механическая: привести job integrate к одному
приёму «скрипты конвейера — из dev», уже принятому в трёх других местах
(#707, #698, #723/#726). Продуктовый код (src/, интеграция) не затронут.
User-Visible: no — корректно, изменение не видно пользователю карточки.
Маршрут §5 (трек show, не ask):
- complexity — заявлено 3/10 владельцем, подтверждаю: правка не вводит новой логики, только перенаправляет уже существующие вызовы на общий снимок.
- surfaces — одна поверхность: job
integrateодного workflow-файла. - migration — нет миграции конфига и compatibility-полей.
- ux-contract — нет, карточки это не касается.
- perf-touch — нет влияния на производительность и touch.
- undocumented — приём уже задокументирован прецедентом в трёх местах конвейера (§10.4 до правки, шаг трека #707, страж ребейза #698, разбор push #723/#726); здесь он доводится до записи в канон тем же абзацем.
Все критерии пройдены → route: fix, criterion не требуется.
Как проверялось
Прочитаны (в порядке из промпта): docs/SCOPE.md, AGENTS.md,
docs/process/REVIEWER.md, тело issue #749 и три комментария (оценка
владельца, взятие в работу, отчёт автора), раздел PROCESS.md §10.4 (новый
абзац). docs/USER-GUIDE.ru.md и канонические документы подсистем не
применимы — видимого поведения карточки нет.
Прочитан полный git diff origin/dev...HEAD по каждому файлу.
AC1 — якорь и проверка #413 читают версию dev
Доказательство — test/publish-push-refusal.test.mjs, тест
«#749 AC1 _process.yml на настоящем bash: якорь и проверка #413 — версия dev,
скрипт ветки задачи не исполняется» (новый, строки 452–491). Сценарий: ветка
несёт свою версию review-doc-guard.mjs, которая пишет маркер
BRANCH-VERSION и выходит кодом 7; шаг публикации и шаг #413 исполняются на
настоящем bash против временного origin. Прогнал:
node --test test/publish-push-refusal.test.mjs
29/29 зелёных, включая новый тест. Тест умеет падать: проверено по коду —
без TOOLS в шаге скрипт резолвился бы как scripts/review-doc-guard.mjs
(рабочая копия, версия ветки) и упал бы кодом 7, тест поймал бы это через
assert.equal(r.status, 0, ...) и assert.ok(!existsSync(branchLog), ...).
Проверено исполнением теста, не только чтением.
AC2 — контракт job integrate: ни один шаг не зовёт scripts/ рабочей копии
Доказательство — новый test/process-integrate-tools.test.mjs, три теста:
- ни один шаг
integrateне содержитscripts/...мимо$TOOLS/, нетimport("./scripts/..."), нет своего извлечения ($tools,publish-tools,route-tools) вне самого шага снимка; подсчитано число вызовов каждого из 6 скриптов и сверено с ожидаемым (review-result-gate×1,review-doc-guard×5,reviews-index×1,merge-candidate×3,process-track×1,status-label×1 — итого 12 в 6 шагах, как заявлено автором); - снимок один на job, строится после
setup-nodeи до первого потребителя, тем жеif, что у checkout, берёт.github/workflows/validate.ymlвместе соscripts; - снимок самодостаточен: шаг исполняется как есть на временном
origin/devс нынешнимиscripts/иvalidate.yml,ci-proof.mjsрезолвитresolveJobRules()без исключения, каждый из 6 скриптов импортируется из каталога снимка безnode_modules.
Прогнал:
node --test test/process-integrate-tools.test.mjs
3/3 зелёных. Тест умеет падать — проверено не чтением, а исполнением:
временно откатил один вызов (status-label.mjs) обратно на node scripts/…
и прогнал тест заново — первый subtest упал с doesNotMatch на нужной
строке; откат отменён, git status --short -- .github/workflows/_process.yml
— чисто.
Независимая сверка по grep: оставшиеся в файле вызовы node scripts/... и
import("./scripts/...") (строки 197, 233, 649, 680, 773, 908, 1349) все лежат
в job guard/prepare/model_review, не в integrate — совпадает с
разделом issue «Не входит» (job prepare — отдельный кандидат) и с
исключением для model_review, записанным в правку PROCESS.md §10.4. Скоуп
AC2 не занижен и не завышен.
Проверил также, что ни один из 6 вызываемых скриптов не тянет npm-пакет
(grep ^import у review-doc-guard, merge-candidate, status-label,
process-track, review-result-gate, reviews-index — только node:* и
относительные импорты друг на друга), то есть снимок без node_modules
действительно самодостаточен для всех шести, а не только для тех, что
исполнил тест AC2.3.
AC3 — совместимость и канон
test/process-track.test.mjs(40/40),test/review-doc-guard.test.mjs,test/review-result-gate.test.mjs,test/reviews-index.test.mjs,test/status-label.test.mjs(вместе 101/101) — прогнаны, зелёные, правки в них синхронны с новым$TOOLS.- Правка PROCESS.md §10.4 — абзац «Скрипты конвейера — из
dev» (#749) прочитан; содержит все пункты, которые требует К3 issue: исключениеmodel_review, «рабочая копия — материал, не инструмент», следствие «слияние задачи, меняющей конвейер, судит версия dev», требование совместимости правки контракта Validate. Соответствует. scripts/mutation-registry.mjs: якорь мутантаprocess-label-step-combined-againпереведён наnode "$TOOLS/scripts/status-label.mjs"— без правки мутант потерял бы точку привязки (строка дляfindне нашлась бы в YAML). Прогналnode scripts/mutation-gate.mjs --check— зелёный (205 browser guards, ориентир 200, это существующее стандартное предупреждение, не regression этого диффа;warnings: 4в реестре — тоже не относится к #749, в диффе мутации не менялись содержательно, только путь вfind).node scripts/entry-cost.mjs --check— зелёный, бюджеты digest'ов не нарушены.node --test test/process-digests.test.mjs— 5/5, конспект-канон согласованы.
Трейлеры и видимые числа
Коммит один: Issue: #749, User-Visible: no — верно, изменений в
docs/CHANGELOG.md/docs/CHANGELOG.ru.md нет и не требуется. Число,
видимое пользователю карточки, в диффе отсутствует — изменение только в
конвейере ревью.
Что проверено и корректно
- Снимок строится ровно один раз на job, тем же условием запуска, что и
checkout, после
setup-nodeи до первого потребителя — проверено и тестом, и чтением YAML. - Все 12 вызовов 6 скриптов в job
integrateидут через$TOOLS; старые точечные извлечения (publish-tools,route-tools) убраны, а не задублированы. validate.ymlвходит в снимок и реально читаетсяci-proof.mjsоттуда — проверено исполнением (AC2, subtest 3), а не на слово.- Снимок не тянет
node_modules, и это безопасно, так как ни один из 6 вызываемых скриптов не импортирует npm-пакет (проверено grep по всем шести, не только по тем, что покрывает тест). - Поведение job
guard,prepare,model_reviewне затронуто (сверено построчно — оставшиеся вызовыnode scripts/...внеintegrate), скоуп соответствует «Не входит» issue. - PROCESS.md §10.4 дополнен абзацем, содержащим все пункты К3.
- Мутант
process-label-step-combined-againсинхронизирован с новым вызовом. - Тесты AC1 и AC2 умеют падать — проверено исполнением (откат вызова для AC2, разбор пути резолва для AC1), а не заявлением автора.
Чего не проверял
npx tsc --noEmit,npm test(полный прогон черезnpm run test),npm run build+ сверка трёх копий бандла — не перегонял: Validate на9bf35aecзелёный (ссылка выше), дешёвые гейты подтверждены этим прогоном. Личная попыткаnode --test test/*.test.mjsбез предварительногоtsc -p tsconfig.test.json(как требует npm-скриптtest) ожидаемо упала на одном скомпилированном тесте — это особенность прямого вызова мимо npm-скрипта, а не находка: Validate уже прогнал правильную команду и она зелёная.npm run golden:verify— не прогонял: меткиci:goldenнет, диффа в пути отрисовки плана нет.python -m pytest tests_backend -q— не прогонял:custom_components/**/*.pyне менялся.npm run invariants -- --config <export>— не прогонял: геометрия и ссылки на неё не затронуты.- performance-профили — не прогонял: не названы в AC, диффа в производительность-чувствительном коде нет.
- Браузерные смоки — прогнал
node scripts/smoke-select.mjs --base origin/dev --head HEAD: ответ «Исполняемого frontend-диффа нет (src/**/*.tsне тронут). Browser-smoke этим диффом не выбираются — выбирать нечего». Прямого совпадения, зарегистрированной связи или НЕОПРЕДЕЛЁННОСТИ с конкретными смоуками инструмент не назвал — чистое «нечего выбирать» при нулевом фронтенд-диффе, смоуки не требуются. actionlint— попытка черезnpx actionlintне нашла исполняемый (бинарь не установлен в этом окружении как npm-пакет); не являюсь источником истины по синтаксису YAML отдельно от Validate — сам Validate уже подтверждён зелёным на этом SHA, что косвенно доказывает синтаксическую валидность файла (workflow выполнялся).- Ручное/визуальное тестирование конвейера (реальный GitHub Actions прогон
integrateна реальном issue) — не проводилось; весь разбор AC1/AC2 — через детерминированные bash/node-тесты на временных origin, что и требует промпт как эквивалент исполнения.
Находки
Нет. High: 0, Medium: 0, Low: 0.
Вердикт
Зелёный. AC1–AC3 доказаны исполнением тестов, оба контрактных теста (AC1, AC2) проверены на способность падать прогоном с намеренно испорченным кодом/веткой. Скоуп соответствует разделу «Не входит» issue, канон PROCESS.md дополнен требуемым абзацем, мутант синхронизирован, трейлеры корректны.
Материал раунда
- Ветка:
issue/749-integrate-scripts-from-dev, коммит9bf35aecb018— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
3075c1fc6dae8e27b976eb4bd7cb67c760072a7cgit log --all --format='%H %T' | grep 3075c1fc6dae - Тело issue:
919ed6e376e783bf41ef44ab421e87da6a984ead0f91203f0011393437c2485e - Вердикт конвейера:
green· High 0 · маршрутfix