--- 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-страховки сохранены.