Files
orchestrator/docs/architecture/adr/adr-0040-lite-installer-canon.md
claude-bot a681d6e3f7
All checks were successful
CI / test (push) Successful in 56s
architect(ET): auto-commit from architect run_id=654
2026-06-12 10:42:03 +03:00

9.4 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-104 architecture architect proposed 2026-06-12 claude-opus-4-8

adr-0040: Установщик Lite-тиража — scripts/install_lite.py (ORCH-104, 10a)

Статус

Proposed

Контекст

Эпик ORCH-10 (D5 «Масштаб»), тип A — Lite. adr-0037 (ORCH-102) дал golden-source инструкцию docs/deployment/LITE_SETUP.md — надёжный, но ручной маршрут из 13 разделов («голый хост → работающий конвейер»): ~6 предусловий, ~20 ключей .env по 4 группам, webhook'и Plane/Gitea (иногда raw-SQL), два Telegram-бота, claude CLI, compose, онбординг, smoke. Долго; ошибки (опечатка секрета → 401 HMAC; неверный uid; занятый порт) всплывают поздно — на docker compose up, не в момент ввода. adr-0038 (ORCH-103) для Bundled уже доказал каркас установщика scripts/bootstrap_bundle.py.

ORCH-104 автоматизирует happy-path §2§11 одним интерактивным установщиком и добавляет раннюю валидацию. Сквозной характер: вводится новый операторский артефакт семьи тиража и нормативная граница connect-only (Lite подключается к чужой инфре, в отличие от Bundled, который её поднимает) — это правило обязательно для будущих задач эпика ORCH-10. Детальный пакет решений (D1…D15, исходы вопросов ТЗ OQ-1…OQ-7) — work-item ADR: docs/work-items/ORCH-104/06-adr/ADR-001-lite-installer.md.

Решение

  1. Новый установщик scripts/install_lite.py — «connect-only»-сородич bootstrap_bundle.py. Имя install_* (не bootstrap_*) понятнее оператору и сигналит семантику «подключение к готовой инфре» против «bring-up» bundle (OQ-1).
  2. Самодостаточный один файл, stdlib-only (OQ-4): проверенные примитивы эталона (parse_env/render_env/manual_checkpoint/_write_private 600/never-raise _http/ preflight_verdict-стиль/exit-контракт 0/2/1) реплицированы, а не вынесены в общий модуль. Так держится «один установочный файл» (BR-1) и bootstrap_bundle.py остаётся байт-в-байт (нулевой риск регресса Bundled). Вынос общего scripts/_replication_lib.py — позже, по rule-of-three (третий тиражный скрипт).
  3. Каноны не форкаются (как adr-0037/0038): webhook-секреты — субпроцесс gen_secrets.py (никакого своего token_hex); регистрация проекта и 22 статуса — субпроцесс onboard_project.py apply/verify (plane_sync._PLANE_NAME_TO_KEY); .env/.env.watchdog — рендер из .env.example/.env.watchdog.example; стек — docker-compose.yml (ровно орк+watchdog, staging за профилем не поднимается).
  4. Граница connect-only — нормативно (OQ-5): в Lite Plane/Gitea/Telegram — чужие инсталляции; установщик говорит с ними только по их API и не мутирует их. Webhook Plane = верифицируемый manual-step (печать инструкции пути A/Б, без исполнения raw-SQL в чужую БД — INV-5); истинный гейт webhook'а — smoke (§11). Контраст с bundle, который владеет Plane-БД и пробует INSERT.
  5. Управляемая установка зависимостей без тихого root (OQ-3): точная команда под дистрибутив (apt/dnf), выполнение только при TTY + явном согласии + команда из allowlist; неизвестный дистрибутив/нет TTY/отказ → инструкция + exit 2. Логин claude CLI — manual-step с верификацией (OQ-6). Не-интерактив/CI — fail-closed exit 2 с именем недостающего ключа; секреты из env, не из argv (OQ-7).
  6. Анти-дрейф — постоянная CI-гарантия: новый tests/test_install_lite_script.py (структурный + юнит чистых функций + фейки HTTP/процессов; без сети/docker/LLM): ссылки на кирпичи, запрет собственной генерации секретов и захардкоженных 22 статусов, stdlib-only (AST), 0 delete/force-операций, реюз FORBIDDEN/find_violations из tests/test_no_host_hardcodes.py, exit-контракт {0,1,2}. LITE_SETUP.md получает callout-указатель на установщик (рекомендованный путь; ручной маршрут — фолбэк), 13 ## N.-разделов сохраненыtest_lite_setup_doc.py остаётся зелёным + ассертит ссылку. Норматив сопровождения (NFR-5): меняешь шаги установки → синхронизируй LITE_SETUP.md в том же PR.

Что НЕ меняется

src/**, docker-compose.yml, Dockerfile, существующие scripts/** (включая bootstrap_bundle.py/gen_secrets.py/onboard_project.py); STAGE_TRANSITIONS, состав QG_CHECKS, семантика check_*, machine-verdict ключи, схема БД — байт-в-байт. Новый QG не вводится (структурные тесты — в существующих гейтах). Kill-switch не нужен: активация — только явный запуск оператором на его хосте (паттерн ORCH-009/101/102/103). Прод-контейнер в рамках задачи не рестартуется. 07-infra-requirements.md/08-data-requirements.md — N/A (топология нашего орка и схема БД не меняются; предусловия хоста — golden source LITE_SETUP §2, не форкаются).

Альтернативы

  • Общий модуль _replication_lib.py (DRY сейчас) — отвергнуто: правка замороженного bootstrap_bundle.py = риск регресса Bundled + противоречит «одному файлу»; вынос по rule-of-three.
  • Имя bootstrap_lite.py — отвергнуто: install_* понятнее оператору и верно сигналит connect-only.
  • Авто-драйв webhook Plane raw-SQL (как bundle) — отвергнуто: в Lite Plane чужой; raw-SQL в чужую БД нарушает INV-5 и часто недостижим.
  • Тихий sudo-install / сторонний TUI (rich/click) — отвергнуто: D-1 (только consent) и NFR-6 (stdlib-only до первого docker compose up).
  • Замена LITE_SETUP.md установщиком — отвергнуто: runbook остаётся golden source и фолбэком.

Последствия

  • Type A эпика ORCH-10 получает автоматизированный happy-path поверх ручного канона; ошибки секретов/URL ловятся в момент ввода (живая верификация), не на up. Полнота/анти-форк/отсутствие delete защищены CI.
  • Цена: ~150 строк осознанного дублирования примитивов с bootstrap_bundle.py (rule-of-three триггер задокументирован); webhook Plane остаётся ручным (граница connect-only), верифицируется на smoke.
  • Откат: удалить scripts/install_lite.py + tests/test_install_lite_script.py, вернуть callout-врезку LITE_SETUP.md и doc-правки — состояние 1:1 (scripts+docs+tests, без миграций и рантайм-изменений).

Связи

adr-0037 (ORCH-102 — Lite-канон/LITE_SETUP.md; этот установщик автоматизирует его §2§11), adr-0038 (ORCH-103 — bootstrap_bundle.py, эталон каркаса; connect-only vs bring-up), adr-0036 (ORCH-101 — фундамент 10-common: gen_secrets.py, .env.example, расхардкод хоста), adr-0035 (ORCH-009 — onboard_project.py/22 статуса, переиспользуются субпроцессом; D10 — запрет branch protection), adr-0033 (ORCH-100 — watchdog, C-1 отдельный бот в .env.watchdog), adr-0008/INV-4 (ORCH-058 — staging-порт guard; merge-актор — основание connect-only-границы). Детально — docs/work-items/ORCH-104/06-adr/ADR-001-lite-installer.md, docs/work-items/ORCH-104/10-tech-risks.md.