Files
houseplan-card/docs/reviews/CODE-REVIEW-562-r3.md
T
2026-09-13 07:04:49 +00:00

196 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CODE-REVIEW-562-r3
## Скоуп
Issue #562 «Process: отвязать роли и инфраструктурный трек от конкретных
агентов», заход r3, блокирующих циклов израсходовано 2/4 до этого раунда.
Прошлый вердикт — жёлтый (Medium в скоупе), документ
`docs/reviews/CODE-REVIEW-562-r2.md`, материал `8f000dd459393cd0d17e9cfa58513a68f7f5ffa1`.
**Материал этого раунда — ровно `d6180f7f5de6991fc7bc678a2203da820993c544`**,
рабочая копия уже на нём. `git fetch`/`checkout` не выполнялись.
Ветка приведена конвейером к `dev` между раундами: поверх авторского
`b75130f7` (тот же коммит, что вёл в комментарии автора к r3, локально
эквивалентен `d6180f7f` — см. проверку ниже) легло 2 коммита `dev`
(`744f502b` «ci: include dynamic backend inputs in gates (#542)» и
`f6e5651c` «docs: review document for #542»). После ребейза формально
другой код (§7.2) → **разбор в этом раунде ведётся полностью**, а не по
дельте.
Проверил цену этого решения предметно, а не только продекларировал:
`git diff b75130f7 d6180f7f --stat` показывает ровно 6 файлов —
`docs/TESTING.md`, `docs/reviews/CODE-REVIEW-542-r1.md`,
`scripts/check-inputs.mjs`, `scripts/mutation-gate.mjs`,
`test/check-inputs.test.mjs`, `test/gate-reuse.test.mjs` — это в точности
содержимое двух указанных коммитов `dev` (#542), никаких иных различий
между до- и после-ребейзным деревом нет. Дополнительно проверил, что три
коммита самой задачи #562 (`process:` / `fix: доказывать infra-трек…` /
`fix: подсказывать infra-вход…`) физически идентичны по содержимому
до и после ребейза: `git diff 8f000dd4 7b58f73e` (те же логические коммиты
пред- и пост-ребейз) отличается ровно на те же 6 файлов #542, то есть сам
diff задачи #562 ребейз не тронул ни байтом. Правки #542 (`check-inputs.mjs`,
`mutation-gate.mjs`, backend-гейт CI) и правки #562 (`task-packet.mjs`,
`process-gate.mjs`, `AGENTS.md`, `PROCESS.md`) не пересекаются ни одним
файлом — интерференции нет. Разбор веду полным по объёму (все AC заново),
но с этим установленным фактом на руках: риск, из-за которого правило §7.2
существует, здесь предметно не реализовался.
Полный диапазон `origin/dev(f6e5651c)..HEAD`, 5 содержательных для истории
задачи коммитов (2 — документы предыдущих раундов, не код):
```
3934f8d8 process: отвязать роли от конкретных агентов (#562) — материал r1
f5388259 docs: review document for #562 — документ r1
7b58f73e fix: доказывать infra-трек по diff (#562) — материал r2 (= 8f000dd4 до ребейза)
a66649a1 docs: review document for #562 — документ r2
d6180f7f fix: подсказывать infra-вход до появления ветки (#562) — материал r3 (= b75130f7 до ребейза)
```
`git diff origin/dev...HEAD --stat`: `AGENTS.md`, `PROCESS.md`,
`scripts/process-gate.mjs`, `scripts/task-packet.mjs`,
`test/process-gate.test.mjs`, `test/task-packet.test.mjs`, плюс два новых
файла `docs/reviews/CODE-REVIEW-562-{r1,r2}.md`. Класс изменений: A не
затронут вовсе (`AGENTS.md`/`PROCESS.md` — класс C, `scripts/**`/`test/**` —
класс B) — задача сама себя корректно относит к инфраструктурному треку.
Трейлеры на всех трёх содержательных коммитах: `Issue: #562`,
`User-Visible: no` — верно, продуктовое поведение не менялось, changelog не
нужен и не тронут.
## Как проверялось
| Гейт | Прогнан | Результат |
|---|---|---|
| `npx tsc --noEmit` / `npm test` (весь набор) / `npm run build` + сверка бандлов | нет, переиспользован | Validate на `d6180f7f` green: https://github.com/Matysh/houseplan-card/actions/runs/34743984705 |
| `node --test test/task-packet.test.mjs` | да | 10/10 зелёных |
| `node --test test/process-gate.test.mjs` | да | 35/35 зелёных |
| Тот же `test/task-packet.test.mjs` против кода r2 (`7b58f73e`, через `git worktree`) | да | 8/10 — новый тест `#562: before a branch exists the infra label prompts classification but grants no rights` падает (`AssertionError: /предварительно/` не совпало с `'полный'`), т.е. тест реально ловит регресс r2, а не проходит тавтологически |
| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | да | «Исполняемого frontend-диффа нет… Browser-smoke этим диффом не выбираются» — выбирать нечего |
| `node scripts/check-docs.mjs` | нет | diff не касается `src/**` |
| `golden:verify`, `pytest tests_backend`, `npm run invariants` | нет | diff не меняет рендер/геометрию/Python |
| `git diff`-инспекция интерференции с #542 (соседние коммиты `dev` от ребейза) | да | 0 пересекающихся файлов (см. «Скоуп») |
## Закрытие раунда r2
| Находка r2 | Чем закрыта | Где это видно |
|---|---|---|
| Medium — до появления ветки (`branch === null`) `infrastructure` был всегда `false`, и statusless issue с меткой `infra` получал от `task-packet.mjs` заведомо неверный ответ «вне процесса, ждать S-метку владельца» вместо «инфраструктурный вход, делай сразу» | Введён отдельный флаг `infrastructureHint = branch == null && status == null && labels.includes('infra')`. Track для этого состояния теперь `'инфраструктурный (предварительно; подтвердить путями/diff)'`, а `rightsFor` добавляет явную строку «метка infra — только подсказка, не доказательство и не право: до ветки проверь предполагаемые пути; без class A начинай сразу, при любом class A нужен продуктовый S-flow» и меняет `default`-ветку switch на «предварительный инфраструктурный вход: после проверки отсутствия class A реализовать → push ветки → S7-code-review; diff станет окончательным доказательством». Это ровно вариант, предложенный самой находкой r2 («явно писать неопределённость... маркировать как непроверенный diff'ом, а не как решённый факт»), а не решение «доверять метке безусловно» — поэтому находка r1 (метка = безусловное доказательство трека) этим не реанимируется | `scripts/task-packet.mjs:27,39-51,118-125`; воспроизвёл сам: `buildPacket({issue:{...}, labels:['infra']})` (без `branch`) на `d6180f7f` даёт `track: 'инфраструктурный (предварительно; подтвердить путями/diff)'` и три строки rights, включая подсказку — команда и полный вывод см. «Как проверялось» |
| (методологический риск: не поймать регресс тавтологичным тестом) | Новый тест `test/task-packet.test.mjs:125-136` (`#562: before a branch exists...`) целенаправленно вызывает `buildPacket` **без** `branch` — именно тот путь, который r2 поймал руками, а старые тесты не покрывали | Проверено запуском той же версии теста против кода r2 (`7b58f73e`) через `git worktree`: падает (`AssertionError`), то есть тест не тавтологичен |
Находка r2 закрыта: сценарий «взять задачу, вызвать пакет до push ветки» теперь
даёт согласованную рекомендацию «после проверки путей — начинай», а не
блокирующее «жди метку владельца», что для инфраструктурного трека
противоречило бы самому issue #562. При этом граница r1 (тематическая
метка НЕ даёт права на класс A и НЕ подменяет механический критерий, когда
ветка уже есть) не нарушена: `infrastructureHint` действует только при
`branch == null && status == null`, тест `#562: the infra label alone never
grants the accelerated track` (метка `infra` + реальный `S6-in-progress`)
остаётся зелёным и продолжает требовать `track === 'полный'`.
## Унаследовано из r2 / r1
Формально это полный разбор (ребейз, §7.2), но там, где текст между
раундами буквально не изменился, вывод предыдущих раундов подтверждён
повторным чтением, а не просто принят на слово:
- **AC1** (роли не закреплены за Codex/Claude в `AGENTS.md`/`PROCESS.md`;
локальный `CODEX-RUNBOOK.md` вне репозитория и вне материала ревью) —
перечитал `AGENTS.md` («Agent-neutral workflow») и `PROCESS.md` (раздел
ролей) целиком в этом раунде; текст идентичен тому, что проверяли r1/r2
(дельта `3934f8d8` не тронута ни `7b58f73e`, ни `d6180f7f` — оба диффа
ограничены `scripts/task-packet.mjs`/`test/task-packet.test.mjs`).
Документ первичного вывода: `docs/reviews/CODE-REVIEW-562-r1.md`, SHA
`53f0635e` (= `3934f8d8` после ребейза).
- **AC2** (оба документа одинаково описывают маршруты S1–S8 и
инфра-без-S → S7 ↔ S6 → S8) — то же самое: перечитал диаграмму `PROCESS.md`
§2 и абзац `AGENTS.md` про accelerated entry заново, они согласуются
друг с другом дословно так же, как на r1.
- **AC3** (независимость автора/ревьюера, автоматическое ревью и слияние,
разрешение владельца на выпуск) — механика конвейера (`S7-code-review`
триггерит автоматический ревью, зелёный вердикт мержит и ставит
`S8-merged`) не менялась ни одним из трёх коммитов #562; `process-gate.mjs`
и `test/process-gate.test.mjs` в этой задаче меняют только текст
сообщений/комментариев (см. далее), не логику.
- **AC4** (исторические документы ревью не переписаны) — `docs/reviews/
CODE-REVIEW-562-r1.md` и `-r2.md` в полном диапазоне `origin/dev...HEAD`
присутствуют только как добавленные файлы (`git diff --stat`: только
insertions, 0 deletions на этих путях) — ни один существующий файл
`docs/reviews/**` не тронут.
- `scripts/process-gate.mjs` / `test/process-gate.test.mjs` — перечитал
диф заново (полный разбор): оба файла в этом раунде меняют только строки
комментариев и текст сообщений (`#118` → `#562`, обновлённая
формулировка), логика `isInfrastructureRange`/`checkIssueStatuses` не
затронута — прогнал `test/process-gate.test.mjs` целиком (35/35) для
проверки, что переименования не сломали ни одной проверки.
## Проверка AC issue #562 (полная, по коду этого SHA)
| AC | Проверка | Результат |
|---|---|---|
| AC1: `AGENTS.md`/`PROCESS.md`/локальный `CODEX-RUNBOOK.md` не закрепляют работу за Codex/Claude | Прочитал оба файла целиком в затронутых разделах: `AGENTS.md` «Agent-neutral workflow» — «No task type is reserved for Codex, Claude or any other named model»; `PROCESS.md` — таблица ролей по агентам заменена абзацем «Роли не закреплены за моделями или именами агентов». Таблица `Исполнитель → роли` из старой версии удалена полностью (`git diff` подтверждает: `-\| Исполнитель \| Роли \|` и весь блок). `CODEX-RUNBOOK.md` — не в репозитории (путь `C:\Users\...`), вне материала ревью, как и на r1/r2 | Выполнено для двух документов в репозитории; третий вне доказуемости этим ревью — унаследовано с r1 |
| AC2: оба документа одинаково описывают продуктовый S1–S8 и инфраструктурный «без S → S7 ↔ S6 → S8» | `PROCESS.md` §2: `инфраструктурный трек (§1): без S → S7-code-review ⟲ S6-in-progress → S8-merged`; `AGENTS.md`: «Once the branch is ready and pushed, apply `S7-code-review`... green review... sets `S8-merged`; findings or a failed merge return the issue to `S6-in-progress`». Формулировки эквивалентны машиночитаемо (те же 4 состояния, та же стрелка возврата) | Выполнено |
| AC3: независимость автора/ревьюера, автоматическое ревью, автоматическое слияние, прямое разрешение владельца на выпуск | `AGENTS.md`: «Author and reviewer are independent agents/sessions... the reviewer must start without implementation context and must not be the author grading their own work»; releases остаются «explicitly commanded by the owner». Механизм автослияния (`S7-code-review` → controller → `dev` → `S8-merged`) в `PROCESS.md` не переписан по существу, только убрано закрепление за `Claude`/`Codex` в описании техреализации ревьюера («Текущая техническая реализация независимого ревьюера — `anthropics/claude-code-action`; это деталь автоматизации, а не закрепление роли») | Выполнено |
| AC4: исторические документы ревью не переписываются | `git diff origin/dev...HEAD --stat` показывает `docs/reviews/CODE-REVIEW-562-r1.md`/`-r2.md` только как новые файлы (100% insertions); ни один файл вида `CODE-REVIEW-*-r*.md`/`SPEC-REVIEW-*-r*.md` другой задачи не в диапазоне | Выполнено |
## Находки
Нет. High — 0, Medium — 0, Low — 0. Находка r2 закрыта предметно (см. таблицу
выше), новых находок в дельте `7b58f73e..d6180f7f` и в остальном полном
разборе не обнаружено.
## Что проверено и корректно
- Регресс r2 (statusless `infra`-issue без ветки получал команду «жди
S-метку») исправлен именно так, как просила находка: неопределённость
явно названа («подсказка, не доказательство и не право»), а не превращена
в новое безусловное доверие метке — граница r1 (метка не даёт прав, когда
ветка/diff уже есть) не нарушена, подтверждено прогоном теста «the infra
label alone never grants the accelerated track».
- Новый тест на регресс r2 не тавтологичен — воспроизвёл падение на
предыдущем SHA через `git worktree`.
- `classify()` для вычисления `branch.infrastructure` переиспользуется из
`scripts/process-gate.mjs` — тот же механический критерий, что у
блокирующего гейта, а не отдельная копия правила.
- Ребейз конвейера не внёс интерференции: файлы, добавленные `dev` в это
же дерево (#542, `check-inputs.mjs`/`mutation-gate.mjs`/`docs/TESTING.md`),
не пересекаются ни с одним файлом, который трогает #562.
- Трейлеры `Issue: #562` / `User-Visible: no` верны на всех трёх
содержательных коммитах; изменение чисто инфраструктурное (класс A не
тронут), changelog не требуется и не тронут.
- `docs/reviews/**` не переписан — только добавлены документы прошлых
раундов задачи.
## Чего не проверял и почему
- Полный `npx tsc --noEmit` / `npm test` / `npm run build` не перегонял —
переиспользован зелёный Validate именно на материале ревью (`d6180f7f`,
ссылка выше); прогнал таргетно изменённые тестовые файлы и негативную
пробу на предыдущем SHA вместо этого.
- `node scripts/check-docs.mjs`, browser-смоки, `golden:verify`,
`pytest tests_backend`, `npm run invariants` — не запускал: diff не
касается `src/**`, `demo/**`, Python или геометрии; `smoke-select`
подтвердил отсутствие исполняемого frontend-диффа.
- Локальный `CODEX-RUNBOOK.md` владельца — физически вне репозитория и вне
материала ревью, не проверялся (как и на r1/r2).
- Содержимое коммитов #542, попавших в дерево ребейзом, не ревьюировал
повторно по существу — они уже прошли собственный код-ревью
(`docs/reviews/CODE-REVIEW-542-r1.md`, зелёный вердикт) и не входят в
диапазон `origin/dev...HEAD` этой задачи; проверил только отсутствие
файловой интерференции с #562.
Вердикт: зелёный · заход r3 · блокирующих циклов 2/4 · High: 0 · Medium: 0
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/562-agent-neutral-workflow`, коммит `d6180f7f5de6` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `c34dca167de81bea95a3c17b8436bcecb1760dfd`
```
git log --all --format='%H %T' | grep c34dca167de8
```
- Тело issue: `520e2e2d0230ee82ee9e86795aa5e61e4172442aa24bea85a9429dd5aa7677ae`
- Вердикт конвейера: `green` · High 0