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