mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 05:08:53 +00:00
150 lines
11 KiB
Markdown
150 lines
11 KiB
Markdown
# CODE-REVIEW-515-r1
|
||
|
||
Материал: `5a1cddeaf0fbac3e96bdc7ace20091a4549691c1`, ветка
|
||
`issue/515-material-anchors-after-rebase`, `origin/dev` не ушёл с этой темы
|
||
дальше — единственный коммит в диапазоне `origin/dev..HEAD`.
|
||
|
||
## Скоуп
|
||
|
||
Issue #515 (light track, ТЗ в теле issue): якоря материала ревью (`sha`,
|
||
`tree`, `specs`), которые публикация зашивает в машинный блок документа,
|
||
снимались в шаге «Перейти на ветку задачи» — **до** шага «Привести ветку к
|
||
dev». Когда `dev` ушёл вперёд, конвейер ребейзит ветку и делает
|
||
force-push; коммит и дерево, снятые до ребейза, становятся недостижимыми
|
||
на origin. Это ломало reuse (#499, всегда `reuse=false` в свежем клоне) и
|
||
красило пост-шаг «Материал раунда воспроизводим (#413)» на зелёном раунде.
|
||
|
||
Диффа два файла, оба класса B (Гейты и инструменты, PROCESS.md §1):
|
||
`.github/workflows/process.yml` (перенос снятия `tree`/`specs` из шага
|
||
`branch` в шаг `material`, который уже существовал и уже снимал `sha`
|
||
после ребейза; смена источника `MATERIAL_SHA/TREE/SPECS` в шаге публикации
|
||
с `steps.branch.outputs.*` на `steps.material.outputs.*`) и
|
||
`test/review-doc-guard.test.mjs` (новый контрактный тест на текст
|
||
workflow). Класса A (продуктовый код) диффа не задевает.
|
||
|
||
Замечание не по существу проверки: задача помечена `infra`/`process` и по
|
||
механическому признаку §1 (ни одного файла класса A) могла бы идти «вне
|
||
флоу» без код-ревью вовсе — но провести пайплайн-ревью пайплайна через сам
|
||
пайплайн разумно именно потому, что часть AC (см. ниже) в принципе
|
||
проверяется только живым прогоном следующей задачи. Решение маршрутизации
|
||
не моё, и на итог ревью не влияет.
|
||
|
||
## Как проверялось
|
||
|
||
- Полное чтение диффа (`git diff origin/dev...HEAD`) и контекста вокруг
|
||
него в `process.yml`: шаги `branch` (id=branch), `rebase` (id=rebase),
|
||
`material` (id=material), `reuse` (id=reuse, #499), «Материал раунда
|
||
воспроизводим» (#413), «Опубликовать документ ревью», «Слить ветку в
|
||
dev», «dev ушёл вперёд, пока шло ревью» — все места, где раньше или
|
||
теперь читаются `steps.branch.outputs.*` / `steps.material.outputs.*`.
|
||
- Чтение `scripts/review-doc-guard.mjs`: `anchorTreeFrom`, `anchorLiveness`,
|
||
`reusableGreenVerdict`, ветки `--reuse` и `--doc=` в CLI — то есть
|
||
фактическую механику, которая потребляет якоря, записанные новым кодом.
|
||
- `grep -rn "steps\.branch\.outputs\.\(tree\|specs\)"` по всему репозиторию
|
||
(md/yml/mjs) — ноль совпадений, старый источник нигде не остался.
|
||
- **Тест умеет падать** — исполнено, не заявлено: временно подменил
|
||
`.github/workflows/process.yml` на версию `origin/dev` (до фикса),
|
||
прогнал `node --test test/review-doc-guard.test.mjs`. Новый тест `#515`
|
||
красный:
|
||
`error: 'дерево — из шага material'`, актуальный текст шага `material`
|
||
в выводе ассерта — старая версия без `tree=`. Вернул файл на HEAD
|
||
(`git status --short` — пусто, рабочая копия чистая), прогнал тест ещё
|
||
раз: `49/49 pass`, включая новый.
|
||
- `python3 -c "import yaml; yaml.safe_load(...)"` — YAML `process.yml`
|
||
валиден.
|
||
- `bash -n` на извлечённых телах трёх изменённых `run:`-блоков (`branch`,
|
||
`material`, «Опубликовать документ ревью») — синтаксис чист.
|
||
- `node scripts/smoke-select.mjs --base origin/dev --head HEAD` →
|
||
«Исполняемого frontend-диффа нет… Тронуто файлов: 2» — смоки не
|
||
выбираются, подтверждено инструментом, не по названию.
|
||
- Дешёвые гейты (`tsc --noEmit`, `npm test`, `npm run build` со сверкой
|
||
бандла) на этом SHA уже зелёные в Validate
|
||
(https://github.com/Matysh/houseplan-card/actions/runs/34404945290) —
|
||
не перегонял.
|
||
|
||
### Что не проверял и почему
|
||
|
||
- `npm run golden:verify`, `check-docs.mjs`, `npm run invariants`,
|
||
`pytest tests_backend` — diff не трогает `src/**`, рендер, геометрию или
|
||
`custom_components/**/*.py`; неприменимо.
|
||
- Полный набор browser-smoke — инструмент явно сказал «выбирать нечего».
|
||
- **AC2 и AC3 живым прогоном** — не выполнено и не могло быть выполнено в
|
||
рамках этого ревью: оба требуют повторного `S7` конвейера на реальной
|
||
задаче после зеркалирования `process.yml` в `main` (#454, п.3 ТЗ, вне
|
||
этого коммита). Сам текст ТЗ отдаёт эту проверку живому прогону, а не
|
||
ревью. Ниже — «проверено чтением, не исполнением» с прослеженной
|
||
цепочкой вызовов, но не заменяющее реальный прогон.
|
||
|
||
## Разбор по AC
|
||
|
||
**AC1** (после ребейза блок якорей называет пост-ребейзный коммит/дерево,
|
||
достижимые с origin; тест краснеет на возврате к `steps.branch.outputs`).
|
||
Доказано автотестом, тест проверен на падение (см. выше). Дополнительно
|
||
прочитан путь данных: `material.sha/tree/specs` → env `MATERIAL_*` шага
|
||
«Опубликовать документ ревью» → `review-doc-guard.mjs --anchor=... --sha=
|
||
--tree= --specs=` → `materialAnchorBlock` в тексте документа. Момент снятия
|
||
(`material`, после `git push --force-with-lease` в шаге `rebase`) гарантирует,
|
||
что дерево уже лежит в запушенном коммите. **Выполнен.**
|
||
|
||
**AC2** (повторный `S7` без изменений кода поверх зелёного документа даёт
|
||
`reuse=true` без вызова модели). Проверено чтением: `differs(tree)` в
|
||
`--reuse` сначала делает `git cat-file -e <tree>^{tree}` — до фикса дерево
|
||
было пре-ребейзным и в свежем клоне не существовало физически (осиротело
|
||
force-push'ем), это и давало жёсткое `differs=true` независимо от
|
||
реального содержимого, что дословно совпадает с симптомом в issue.
|
||
После фикса дерево — то, что реально запушено на ветку, и `cat-file`
|
||
находит его в клоне следующего прогона; дальше сравнение идёт по
|
||
содержимому, как и задумано. Логика заявленный дефект устраняет. Живым
|
||
прогоном не подтверждено — по объективной причине (см. выше).
|
||
|
||
**AC3** (пост-шаг #413 не красит зелёный раунд с ребейзом). Проверено
|
||
чтением: `anchorLiveness` для типа `tree` ищет объект перебором `%T` по
|
||
`--remotes=origin --tags`; при верном (запушенном) дереве это ровно тот
|
||
поиск, который срабатывает. До фикса — то же дерево, что и в AC2,
|
||
осиротевшее и не входящее ни в один `%T` с origin. Логика согласуется.
|
||
Живым прогоном не подтверждено — та же причина.
|
||
|
||
**AC4** (`User-Visible: no`). Коммит содержит трейлеры `Issue: #515` и
|
||
`User-Visible: no` — соответствует. Продуктовых CHANGELOG-файлов дифф не
|
||
трогает, что и требуется при `User-Visible: no`.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- Единственное place, где раньше писались `tree`/`specs` (шаг `branch`),
|
||
теперь только поясняющий комментарий, само снятие убрано полностью — не
|
||
осталось дублирующего, конфликтующего источника.
|
||
- `material`-шаг выполняется на обеих стадиях (`spec` и `code`): его
|
||
`if: steps.rebase.outputs.conflict != 'true'` истинен и когда `rebase`
|
||
пропущен целиком (стадия `spec`, где ребейза не бывает) — поведение для
|
||
`spec` не регрессирует, дерево там совпадает что до, что после (ребейза
|
||
нет, снимать раньше или позже — один и тот же коммит).
|
||
- Через `material.sha` (не через сегодняшний дифф — использовалось и
|
||
раньше) уже строился системный промпт ревьюера («Материал ревью — ровно
|
||
`…`»); эта правка выравнивает и опубликованный якорь с тем же источником
|
||
— раньше `MATERIAL_SHA` в анкоре и SHA в промпте ревьюера могли
|
||
расходиться, теперь один источник для обоих.
|
||
- Комментарии перенесены по смыслу, а не скопированы бездумно: у `branch`
|
||
теперь короткое объяснение «почему не здесь», у `material` — полное
|
||
объяснение «почему здесь».
|
||
|
||
## Находки
|
||
|
||
Нет ни High, ни Medium.
|
||
|
||
## Вердикт
|
||
|
||
Зелёный.
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/515-material-anchors-after-rebase`, коммит `5a1cddeaf0fb` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||
- Дерево материала: `ec563a09b642fd1e7742dbcfa089c25ef7b8b8df`
|
||
```
|
||
git log --all --format='%H %T' | grep ec563a09b642
|
||
```
|
||
- Вердикт конвейера: `green` · High 0
|