44 lines
7.4 KiB
Markdown
44 lines
7.4 KiB
Markdown
---
|
||
work_item: ORCH-104
|
||
stage: architecture
|
||
author_agent: architect
|
||
status: proposed
|
||
created_at: 2026-06-12
|
||
model_used: claude-opus-4-8
|
||
---
|
||
|
||
# 10 — Технические риски: ORCH-104 — Установочный скрипт для Lite
|
||
|
||
Work Item: **ORCH-104** · Repo: **orchestrator** · Стадия: architecture
|
||
|
||
> Информационный (гейтом не парсится). Перечисляет риски реализации `scripts/install_lite.py` и их
|
||
> митигейшн. Опирается на BRD §8 (R-1…R-5) и архитектурные решения ADR-001 (D1…D15).
|
||
|
||
## Реестр рисков
|
||
|
||
| ID | Риск | Вер. | Влия. | Митигейшн |
|
||
|----|------|------|-------|-----------|
|
||
| TR-1 | Эвристика детекта Plane/Gitea ложно-положительна/отрицательна (нестандартные имена контейнеров/порты, reverse-proxy) → подставлен не тот URL. | Сред. | Сред. | D5: детект лишь **пред-заполняет догадку**; авторитет — живая верификация D6 (Plane `/projects/`, Gitea `/user`) ДО записи; ручной ввод URL — всегда доступный фолбэк; never-raise (NFR-3). Неверный URL не пройдёт верификацию → не запишется. |
|
||
| TR-2 | Утечка секрета в stdout/лог или перезапись существующего `.env` без согласия. | Низ. | **Выс.** | D7/NFR-2/INV-4: ввод секретов `getpass`; лог печатает только имена ключей/пути; запись `_write_private` (chmod 600); webhook-секреты — кирпич `gen_secrets.py` (отказ перезаписи без `--force`); idem-skip валидных значений. Покрыто AC-6 + AST-скан теста. |
|
||
| TR-3 | Управляемый авто-install выполняет небезопасную/неверную для дистрибутива root-команду. | Низ. | **Выс.** | D4/D-1: тихого авто-инсталла нет; выполнение только при TTY + явном `y/N` + команда из фиксированного allowlist; неизвестный дистрибутив (`install_command→None`)/нет TTY/отказ → инструкция + `exit 2`. Покрыто AC-3. |
|
||
| TR-4 | Установщик мутирует **чужую** инфраструктуру (raw-SQL в Plane-БД заказчика, правка `main`, force-push). | Низ. | **Выс.** | D9/INV-3/INV-5: webhook Plane = manual-step (печать инструкции, не исполнение SQL); 0 delete/force-операций (AST-скан AC-10); говорит только с локальным хостом и API заказчика; никогда не трогает `main`/прод. |
|
||
| TR-5 | Дрейф `install_lite.py` ↔ `LITE_SETUP.md` при будущих правках (шаги разойдутся). | Сред. | Сред. | D14/BR-9/NFR-5: норматив «меняешь шаги → обнови LITE_SETUP.md в том же PR»; анти-дрейф `test_lite_setup_doc.py` (ссылка на установщик + 13 разделов/кирпичи/key-sync зелёные). Reviewer-ось обзорных доков (ORCH-079/011). |
|
||
| TR-6 | Дублирование примитивов с `bootstrap_bundle.py` (D2) расходится со временем (поведенческий дрейф `parse_env`/`render_env`/`manual_checkpoint`). | Низ. | Низ. | D2: примитивы малы, генеричны, стабильны; скрипты автоматизируют разные runbook'и; юнит-тесты round-trip `parse_env`/`render_env` в `test_install_lite_script.py`; rule-of-three триггер выноса в общий модуль задокументирован. |
|
||
| TR-7 | Установщик случайно импортирует платформу (`src/**`) или сторонний пакет → ломает stdlib-only/работу до `docker compose up`. | Низ. | Сред. | D2/D13/NFR-6/INV-7: AST-скан import'ов из разрешённого stdlib-набора, запрет `from src …`/`import src …`; работа на голом `python3` подтверждается тестом без сети/docker. |
|
||
| TR-8 | Webhook Plane настроен оператором неверно (опечатка секрета/URL/событий) — установщик не может прочитать его в Plane CE → рапортует успех при неработающем webhook. | Сред. | Сред. | D9: истинный гейт webhook'а — **smoke** (D12/§11): задача в «To Analyse» → analyst-job в `/queue`; `manual_checkpoint` честно сообщает, что финальная проверка — на smoke; траблшутинг 401/HMAC — LITE_SETUP §13.1. |
|
||
| TR-9 | Не-интерактивный/CI-прогон без TTY молча зависает на `input()`/`getpass` или берёт неполные данные. | Низ. | Сред. | D11: `--non-interactive`/`not isatty()` → fail-closed `exit 2` с точным именем недостающего ключа; секреты из env, не из argv (анти-ps-leak); зеркало контракта `manual_checkpoint` эталона. |
|
||
| TR-10 | `apply` не идемпотентен: повтор создаёт дубль проекта/webhook, перевыпускает секреты или падает на сделанном шаге. | Низ. | Сред. | D3/D8: step-движок `check→ensure` (inline «уже сделано» → `skipped`); онбординг — идемпотентный кирпич `onboard_project.py`; секреты — idem-skip. Покрыто AC-8 (два последовательных `apply` с фейками). |
|
||
|
||
## Сводный вывод
|
||
|
||
Доминирующий класс — **гигиена секретов и кросс-граничные мутации** (TR-2/TR-3/TR-4): высокое
|
||
влияние при низкой вероятности, полностью снято архитектурой (getpass + 600 + кирпич-секреты;
|
||
consent-only allowlist-install; connect-only-граница без raw-SQL/delete/force). Остаточный риск для
|
||
**прод-конвейера self-hosting — нулевой**: установщик вне рантайма (`src/**`/`STAGE_TRANSITIONS`/
|
||
`QG_CHECKS`/схема БД байт-в-байт, INV-1), исполняется на хосте заказчика и не касается ни нашего
|
||
прода, ни `main`, ни общей БД. Эскалация `arch:major-change` **не требуется** (аддитивный
|
||
scripts+docs+tests артефакт, обратимый удалением файла); возврат в анализ не нужен — все 7 OQ ТЗ
|
||
разрешимы без нарушения принципов. Ведущие реализационные риски — **дрейф док↔скрипт (TR-5)** и
|
||
**ложный детект (TR-1)**: оба со средней вероятностью и снижены анти-дрейф-тестом и обязательной
|
||
живой верификацией с ручным фолбэком.
|