--- work_item: ORCH-104 stage: architecture author_agent: architect status: proposed created_at: 2026-06-11 model_used: claude-opus-4-8 --- # 10 — Технические риски: ORCH-104 — Установочный скрипт Lite-тиража (интерактивный installer) Work Item: **ORCH-104** · Repo: **orchestrator** · Стадия: architecture > Информационный (гейтом не парсится). Риски реализации и эксплуатации интерактивного > installer'а; решения — `06-adr/ADR-001-setup-lite-interactive-installer.md` (D1…D12). > Развивает реестр BRD §8 (R-1…R-6). ## Реестр рисков | ID | Риск | Вер. | Влия. | Митигейшн | |----|------|------|-------|-----------| | TR-1 | **Случайный запуск на хосте с живым продом** (R-1): дефолт-режим — `apply`-wizard, не `plan` | Низ. | Выс. | Структурные гарантии D2: фаза 0 `apply` ≡ `plan` (read-only), ранний guard НЕмаркированного `.env` → exit 2 ДО первого вопроса (D6), per-action consent с дефолт-ответом «нет», non-TTY → exit 2 до мутаций (D10); `--force` требует явного набора + согласия; на нашем mva154 запуск не предполагается вовсе | | TR-2 | **Оферы установки пакетов** (R-2) — вмешательство в систему заказчика; нативные репо могут дать не то (compose v1, старый docker) | Сред. | Сред. | Per-package consent с печатью точной команды ДО исполнения; закрытый набор менеджеров apt-get/dnf/yum/zypper; **re-check фактом после установки** (в т.ч. `docker compose version` → v2), не сошлось → MANUAL с официальной инструкцией; нет менеджера/sudo/отказ → честный MANUAL (D4) | | TR-3 | **SQL-вставка webhook в чужую Plane-БД** (R-3): инвазивная мутация прод-инсталляции заказчика; пользовательский ввод в SQL | Сред. | Выс. | Path A (UI) — дефолт-рекомендация; Path Б — только при 5 предусловиях D8 (docker-Plane + подтверждённый пользователем postgres-контейнер + согласие с показом SQL + идемпотентный INSERT + обязательная пост-верификация SELECT); только INSERT/SELECT (no UPDATE/DELETE); секрет/пароль — stdin/env, не argv; валидация slug `^[a-z0-9-]+$` (анти-инъекция); любой сбой → fail-safe в Path A | | TR-4 | **Дрейф скрипта от канона LITE_SETUP** (R-4): два источника маршрута расходятся | Сред. | Сред. | Канон-знания не дублируются (кирпичи субпроцессами, статусы — за `plane_sync` через onboarding, smoke — ссылкой на §11); footer-норматив «док + скрипт в одном PR» (FR-11/adr-0040); анти-дрейф: упоминание скрипта в доке, env-ключи ⊂ `.env.example`, зеркала needle-наборов (D12) | | TR-5 | **Зависание/недетерминизм в non-TTY** (R-5): CI/обвязка заказчика виснет на ожидании ввода | Низ. | Сред. | `isatty`-гейт: `apply` без `--yes` в non-TTY → немедленный exit 2 с подсказкой; headless — только env-prefill + явный `--yes`; `plan`/`verify` — полноценные non-TTY режимы; весь интерактив за инжектируемым I/O (детерминированные тесты TC-12) (D10) | | TR-6 | **Ложноположительный discovery** (R-6): чужой контейнер опознан как Plane/Gitea; неверный URL уезжает в конфиг | Низ. | Сред. | Опознание строго по image-префиксам (не по именам); выбор всегда за пользователем + пункт «ввести вручную» всегда; токен-верификация выбранного URL обязательна (FR-4) — неверный кандидат не пройдёт `collect` (D5/D9) | | TR-7 | **Утечка секретов** через транскрипт wizard'а / отчёт / файлы | Низ. | Выс. | Скрытый ввод (getpass-класс); значения не печатаются и не логируются (только имена ключей); итоговая таблица без значений; live-файлы `600`; файл-отчёт прогона сознательно НЕ вводится; анти-дрейф: тест транскрипта (TC-11) + секрет-эвристика на fenced-блоках дока (D3/D6/D10) | | TR-8 | **Коллизия resume ⟷ guard существующего `.env`**: после manual-step повторный запуск отбивается собственным артефактом ЛИБО guard ослабляется и перетирает чужой конфиг | Сред. | Выс. | Маркер managed-файла (первая строка): без маркера → отказ exit 2 (чужой конфиг), с маркером → resume-ensure без перетирания значений (D6); семантика покрыта unit-тестами (TC-03/TC-14) | | TR-9 | **Разнообразие хостов**: экзотический дистрибутив/пакетный менеджер/нестандартный docker — скан даёт неверный вердикт | Сред. | Низ. | Вердикты — чистые функции от фактов (тестируемы на фикстурах); неопределимое → честный MANUAL с generic-командами и ссылкой на § LITE_SETUP (никогда не падение); не-Linux/не-x86_64 → WARN «вне контура» (рамка Lite не расширяется) (D4) | | TR-10 | **Дрейф интерфейсов кирпичей** (`gen_secrets.py`/`onboard_project.py`): смена флагов/формата отчёта молча ломает installer | Низ. | Сред. | Контракты кирпичей закреплены их собственными тестами (`test_secrets_gen`, onboarding-тесты); builder аргументов — чистая функция под unit-тестом (ломается громко в CI); exit-коды кирпичей транслируются честно (2 → MANUAL, 1 → FAIL) (D11); норматив same-PR симметричен | ## Сводный вывод Доминирующий класс — **эксплуатационные риски целевого хоста заказчика** (TR-2/TR-3/TR-9): наш прод они не затрагивают и гасятся per-action consent'ом, контрактом manual-checkpoint, честными MANUAL-деградациями и обязательной верификацией каждого ввода. Специфика ORCH-104 против предшественников — два новых внимательных места: **дефолт-режим `apply`** (TR-1; закрыт структурными гарантиями D2, а не дисциплиной) и **маркер managed-файла** (TR-8; единственный механизм, примиряющий идемпотентный resume с защитой чужого `.env`). Рисков для прод-конвейера self-hosting **нет по построению** (BR-8: рантайм байт-в-байт, kill-switch не нужен — активация только явным запуском оператора; полный регресс и все существующие анти-дрейф тесты остаются зелёными, пиннинг «13 разделов» LITE_SETUP не меняется). Эскалация `arch:major-change` не требуется: новых стадий/компонентов рантайма/смены БД нет — задача целиком в слое дистрибуции (паттерн ORCH-101/102/103). Возврат в анализ не требуется: ТЗ выполнимо без нарушения принципов архитектуры.