--- work_item: ORCH-027 stage: architecture author_agent: architect status: proposed created_at: 2026-06-10 model_used: claude-opus-4-8 --- # 10 — Технические риски: ORCH-027 — Code coverage как гейт Work Item: **ORCH-027** · Repo: **orchestrator** · Стадия: architecture > Информационный (гейтом не парсится). Перечисляет риски реализации и их митигейшн. ## Реестр рисков | ID | Риск | Вер. | Влия. | Митигейшн | |----|------|------|-------|-----------| | TR-1 | **Флап на шуме измерения** — недетерминированное покрытие (порядок тестов/окружение) дрожит у границы → ложные заворота, петля rework. | Сред. | Сред. | `coverage_epsilon` (NFR-4/D3): дрожание ±доли % не заворачивает. Дефолт `policy=both` мягкий; абсолютный порог — backstop, не агрессивный. | | TR-2 | **Не освобождён merge-lease при FAIL.** Coverage идёт ПОСЛЕ merge-gate (lease уже held) — забытый release при откате заклинит serial-gate репо (другие задачи репо в defer навсегда). | Сред. | Выс. | Явный инвариант D1: rollback coverage вызывает `merge_gate.release_merge_lease` (как image-freshness rollback, `stage_engine.py:1165`); покрыто тестом TC-13. Backstop — crash-реклейм lease по возрасту (ORCH-043). | | TR-3 | **Гонка базовой линии** — два параллельных слияния в `main` конкурентно обновляют baseline, теряя/занижая значение. | Низ. | Сред. | Атомарный SQL compare-and-set `UPDATE ... WHERE coverage <= ?` (D5/08-data) + held merge-lease + per-repo сериализация merge (ORCH-043) → тройная защита. Покрыто TC-05. | | TR-4 | **Инфра-хрупкость инструмента** — `pytest-cov` несовместим с версией pytest / упал / метрика не парсится → конвейер клинит. | Низ. | Сред. | NFR-2/FR-6/D6: дефолт fail-open + громкий WARNING (анти-петля ORCH-061); `coverage_tool_fail_closed` для строгого режима. `measure_coverage`→`None` обрабатывается, не всплывает. Покрыто TC-09. | | TR-5 | **Исключение всплывает в `advance_stage`** — ошибка leaf-модуля роняет конвейер ВСЕХ проектов (общий прод-инстанс). | Низ. | Выс. | NFR-1/AC-7: `src/coverage_gate.py` — leaf (не импортирует `stage_engine`), контракт never-raise; любое исключение → `(False/True, reason)` по политике fail-open/closed. Покрыто TC-10. | | TR-6 | **Дабл-ран pytest** — coverage-прогон после merge-gate re-test удваивает время тестов на применимой задаче. | Выс. | Низ. | Ограничен `coverage_run_timeout_s`; фейлит ДО дорогого image-rebuild; follow-up — слияние измерения с merge-gate re-test (вне объёма v1). Влияет только на self-hosting `orchestrator`. | | TR-7 | **Стартовая петля заворотов** — высокий `coverage_min_percent` массово заворачивает существующие задачи в rework. | Сред. | Сред. | NFR-4/D3: bootstrap инициализирует baseline фактическим покрытием `main`; absolute-порог — мягкий backstop; cap `MAX_DEVELOPER_RETRIES` → Blocked+alert вместо бесконечной петли. | | TR-8 | **Self-hosting побочка** — гейт случайно трогает прод-контейнер/`main`/force-push. | Низ. | Выс. | NFR-3/AC-7: гейт только мерит/читает/пишет/решает в изолированном worktree; не вызывает деплой-хук, не рестартит прод, не пушит в `main`. Покрыто TC-12. | | TR-9 | **Регресс контрактов** — затронуты `STAGE_TRANSITIONS`/существующие `check_*`/вердикт-ключи. | Низ. | Выс. | NFR-5/AC-8: новый QG аддитивен, edge-врезка не меняет `STAGE_TRANSITIONS`; вердикт-ключи прежних доков байт-в-байт. Покрыто TC-15. | ## Сводный вывод Доминирующий класс рисков — **эксплуатация автономного self-hosting-конвейера**: самые тяжёлые по влиянию (TR-2 заклинивание serial-gate, TR-5 падение конвейера всех проектов, TR-8 побочка на прод) имеют **низкую вероятность** и закрыты структурными инвариантами, повторяющими проверенные паттерны соседних под-гейтов (security/merge/image-freshness): leaf never-raise, fail-open дефолт, явный release merge-lease при откате, kill-switch. Остаточный риск для прод-конвейера — **низкий** при условии тестового покрытия инвариантов TR-2/TR-5/TR-8 (`04-test-plan.yaml` TC-09…TC-13) и поэтапного раската через staging-гейт (8501). Решение **сквозное** (новый QG + edge-под-гейт + новая БД-таблица + новый артефакт) → эскалация лейблом **`arch:major-change`**. Возврат в анализ не требуется — ТЗ реализуемо без нарушения принципов архитектуры (Docker/один сервер/SQLite/собственная очередь сохранены).