diff --git a/docs/work-items/ORCH-073/12-review.md b/docs/work-items/ORCH-073/12-review.md new file mode 100644 index 0000000..9ae1c12 --- /dev/null +++ b/docs/work-items/ORCH-073/12-review.md @@ -0,0 +1,75 @@ +--- +type: review +work_item_id: ORCH-073 +verdict: APPROVED +version: 1 +--- + +# Review ORCH-073 + +## Summary +Системный фикс эрозии `main` (фантомный merge ORCH-067/069) реализован строго по +ТЗ (FR-1…FR-5) и ADR-001. Все 11 критериев приёмки выполнены, документация обновлена +в том же PR, `pytest tests/ -q` → **941 passed**. Self-hosting-инварианты соблюдены +(merge только через Gitea PR-API, без force-push в `main`; non-self репо — no-op). +Блокирующих и must-fix замечаний нет. + +## Проверка по осям + +### 1. Соответствие ТЗ (02-trz.md) +- **FR-1** — `verify_merged_to_main` подтверждает merge ТОЛЬКО `git merge-base --is-ancestor origin/main`; OR-ветка `pr_already_merged` удалена; пустой SHA / git-ошибка → `False` (fail-closed, never-raise). ✓ +- **FR-2** — `pr_already_merged` понижен до idempotency-guard, явный in-loop фильтр `merged & head.ref==branch & base.ref=="main"` (не ненадёжный query `head`). ✓ +- **FR-3** — `merge_pr` выбирает open PR по `head.ref==branch` И `base.ref=="main"`; merge только `POST /pulls/{n}/merge`. ✓ +- **FR-4** — корневой `.gitattributes` с `CHANGELOG.md merge=union`; `docs/**` намеренно НЕ включён. ✓ +- **FR-5** — `check_main_regression` (детерминированный, no-LLM) + декларативный append-only `MAIN_REGRESSION_MARKERS`; вызов в `_handle_merge_verify` ПОСЛЕ SHA-в-main и ДО `done`; ALERT-only + HOLD; fail-open на git-ошибке грепа; kill-switch `regression_guard_enabled`. ✓ + +### 2. Соответствие ADR (06-adr/ADR-001 + adr-0014) +Реализация 1:1 соответствует Р-1…Р-5. G4-аудит и root-cause зафиксированы в ADR +(раздел «Root cause (G4 audit)»). Сквозной ADR-0014 заведён, `adr/README.md` обновлён, +`adr-0013` помечен как amended. Нарушений глобальных ADR не обнаружено. +**AC-1 подтверждён в `origin/main`:** `plane_issue_link`(8), `qg0_title_max`(config.py 3), +`verify_merged_to_main`(4). **AC-4 подтверждён:** `git check-attr merge CHANGELOG.md → merge: union`. + +### 3. Качество кода +- Строгий never-raise на всех публичных функциях merge_gate; INV-1…INV-5 соблюдены. +- Docstrings содержательные, со ссылками на FR/AC/INV; обоснован осознанный trade-off + fail-open для marker-grep против fail-closed SHA-в-main. +- `_hold_main_regressed` симметричен not-merged-HOLD; уведомления Plane/Telegram best-effort, + не ломают HOLD. +- Схема БД, реестр `QG_CHECKS`, `STAGE_TRANSITIONS`, внешние HTTP-эндпоинты — не тронуты (как и заявлено). + +### 4. Качество тестов +18 тест-кейсов (TC-01…18) в 6 файлах `tests/test_orch073_*.py`, не тривиальные: +- TC-02 воспроизводит исходный баг (merged docs-PR не подтверждает merge), проверяет, что + PR-флаг verify-ом более не запрашивается. +- TC-14/15 различают HOLD по «not-merged» и по «main-regressed». +- TC-10 — идемпотентность (нет второго POST merge). TC-17/18 — conditionality/kill-switch. +- TC-12 в throwaway-репо реально проверяет union-merge без конфликта. + +## Findings + +### P0 — Blocker +- нет + +### P1 — Must fix +- нет + +### P2 — Should fix +- нет + +### P3 — Nice-to-have +- Маркер `("ORCH-073", "check_main_regression", "src/merge_gate.py")` самозагрузочный + (попадёт в `origin/main` только после merge этой задачи) — поведение корректное и + оговорено в ADR (self-bootstrap), замечание чисто информационное. + +## Документация +Полностью обновлена в этом же PR (правило агентов §2/§6, AC-8): +- `docs/architecture/README.md` — раздел merge-verify переписан под FR-1 + добавлены регресс-гард (FR-5) и `.gitattributes` (FR-4). +- `CHANGELOG.md` — запись в `## [Unreleased]`. +- `docs/work-items/ORCH-073/06-adr/ADR-001-*.md` — новый ADR с G4-аудитом; `docs/architecture/adr/adr-0014-*.md` — сквозной ADR; `adr/README.md` обновлён. +- `.env.example` — задокументирован новый ключ `ORCH_REGRESSION_GUARD_ENABLED` + блок merge-verify. + +Требование «изменён `src/` → обновлена документация» выполнено. Блокеров по документации нет. + +## Вердикт +**APPROVED** — нет P0/P1; код, тесты и документация соответствуют ТЗ/ADR; self-hosting-страховки сохранены.