42 lines
7.2 KiB
Markdown
42 lines
7.2 KiB
Markdown
---
|
||
work_item: ORCH-117
|
||
stage: architecture
|
||
author_agent: architect
|
||
status: proposed
|
||
created_at: 2026-06-15
|
||
model_used: claude-opus-4-8
|
||
---
|
||
|
||
# 10 — Технические риски: ORCH-117 — sandbox-only fail-closed изоляция записи в Plane
|
||
|
||
Work Item: **ORCH-117** · Repo: **orchestrator** · Стадия: architecture
|
||
|
||
> Информационный (гейтом не парсится). Риски реализации решения ADR-001 и их митигейшн.
|
||
|
||
## Реестр рисков
|
||
|
||
| ID | Риск | Вер. | Влия. | Митигейшн |
|
||
|----|------|------|-------|-----------|
|
||
| TR-1 | **Ложноположительный детект тест-процесса** в боевом/staging рантайме (`pytest` каким-то образом импортирован в процесс uvicorn) → блокировка легитимной боевой/sandbox записи (молчаливая потеря Plane-индикации, слой B ORCH-066). | Низ. | Сред. | Штатный entrypoint `uvicorn src.main:app` **не** импортирует `pytest`; merge-gate/coverage гоняют pytest **отдельным субпроцессом** (его блок легитимен). Признак консервативный (`sys.modules`+`PYTEST_CURRENT_TEST`), читается на момент вызова. Аудит-WARNING делает любой блок видимым (BR-6) → ложный блок в проде немедленно заметен, а не молчалив. Зафиксированное допущение: «прод-процесс не импортирует pytest». |
|
||
| TR-2 | **Ложноотрицательный детект** (worktree-тест-процесс не распознан как pytest) → дефект ORCH-114 остаётся. | Низ. | Выс. | Инцидентный путь (worktree `python -m pytest`) **гарантированно** имеет `pytest` в `sys.modules`. Двойной слой: даже при сбое рантайм-leaf conftest-floor (D5) держит default-deny. Обязательный регресс-тест AC-1/TC-01 (красный до фикса) доказывает покрытие именно инцидентного пути. |
|
||
| TR-3 | **Захват на импорте** (`PLANE_HEADERS`/`PROJECT_ID`, стр. 17/57): размещение гарда не там → ложное чувство защиты (NFR-4). | Низ. | Выс. | Архитектурно жёстко: гард — на момент **вызова** примитива, до сети, не зависит от токена/`os.environ.setdefault` (ADR-001 D1/D2). AC-7 проверяет это буквально. |
|
||
| TR-4 | **Kill-switch как чёрный ход:** будущий агент «добавляет общий выключатель гарда», который в off-состоянии переоткрывает прод-запись из pytest (NFR-6). | Сред. | Выс. | Дизайн **умышленно без** prod-блок kill-switch (ADR-001 D4): реверс — только sandbox-bound opt-in. Норматив зафиксирован в ADR-001, adr-0046 и `10-tech-risks` как анти-дрейф; прецедент `_no_telegram` (тоже без «разрешить» флага). Reviewer ловит реинтродукцию выключателя как finding ≥P1. |
|
||
| TR-5 | **Регрессия существующего сьюта:** autouse-фикстура `_plane_sandbox_only` ломает тесты, которые ждали реальную/иную запись или ассертили на мок-вызов. | Низ. | Сред. | Большинство тестов уже **мокируют** `plane_*`/`add_comment` (TRZ §7) → реальной записи и так нет; гард лишь делает это гарантией по умолчанию. Фикстура форсит лишь безопасные дефолты (opt-in off), не подменяет сами примитивы. AC-11 (полный регресс зелёный) — обязательный гейт. |
|
||
| TR-6 | **Sandbox-e2e ложно блокируется** (opt-in не доезжает / порядок фикстур). | Низ. | Сред. | Прецедент уже отработан в репозитории: `test_merge_verify`/`test_orch114_*` ре-энейблят свои флаги **после** autouse. AC-2 проверяет реальную sandbox-запись под opt-in; `staging_check.py` Block C — smoke. |
|
||
| TR-7 | **Утечка GET до гарда:** даже без PATCH/POST примитив мог бы сходить в боевой workspace `find_issue_id`/`stage_to_state`. | Низ. | Низ. | Гард размещён **до** любого сетевого шага (сразу после локального `_resolve_project_id`) — ни GET, ни мутации (ADR-001 D1). |
|
||
| TR-8 | **Кросс-каттинг с ORCH-066/094/061:** гард меняет поведение общего `plane_sync`, потенциально задевая deploy-status guard (ORCH-094), staging-tolerance (ORCH-061), статусную модель (ORCH-066). | Низ. | Сред. | Гард — no-op в боевом/staging рантайме (`_in_test_process()` False) → ORCH-094/061/066 в проде/стейджинге **не затронуты**. В тестах те фичи и так под своими дефолтами/моками. Маркер-инвариант не ломается (правка примитивов аддитивна, не трогает машинные ключи). |
|
||
|
||
## Сводный вывод
|
||
|
||
Доминирующий класс — **корректность детекта тест-процесса** (TR-1/TR-2) и **анти-дрейф kill-switch**
|
||
(TR-4). Все три закрываются архитектурно: консервативный признак «pytest-в-процессе» на момент
|
||
вызова + двойной независимый sandbox-bound слой (рантайм-leaf + conftest-floor) + обязательный
|
||
регресс-тест инцидентного пути (AC-1). Остаточный риск для прод-конвейера (self-hosting) — **низкий**:
|
||
гард инертен в боевом и staging рантайме по построению и never-raises, поэтому не способен ни уронить
|
||
конвейер, ни заблокировать легитимную боевую запись; худший реалистичный исход (ложный блок в проде)
|
||
требует несуществующего в штатном entrypoint импорта pytest и был бы немедленно виден через аудит.
|
||
|
||
**Эскалация не требуется:** решение аддитивно, в границах принципов (Docker/SQLite/leaf-pattern/
|
||
never-raise), не трогает `STAGE_TRANSITIONS`/`QG_CHECKS`/схему БД, не вводит новую стадию/QG/компонент
|
||
инфраструктуры. Лейбл `arch:major-change` не ставится; возврат в анализ не нужен.
|