Files
orchestrator/docs/work-items/ORCH-104/02-trz.md
claude-bot be90632068
All checks were successful
CI / test (push) Successful in 58s
analyst(ET): auto-commit from analyst run_id=653
2026-06-12 10:29:36 +03:00

18 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 analysis analyst ready-for-review 2026-06-12 claude-opus-4-8

02 — ТЗ (TRZ): ORCH-104 — Установочный скрипт для Lite

Work Item: ORCH-104 · Repo: orchestrator · Стадия: analysis

ТЗ описывает конкретные требования к реализации, выведенные из BRD и фактического кода. Архитектурное обоснование (структура скрипта, точные эвристики детекта, общий код с bootstrap_bundle.py, финальное имя файла) — задача архитектора (06-adr/). Открытые вопросы — §12.

1. Сводка изменения

Добавляется один интерактивный установщик scripts/install_lite.py, автоматизирующий ручной маршрут docs/deployment/LITE_SETUP.md §2§11 для Lite-тиража (Type A). Скрипт сканирует хост, детектит/предлагает доустановить зависимости, обнаруживает существующие Plane/Gitea (выбор при нескольких), интерактивно собирает и живо верифицирует токены/URL, выпускает секреты кирпичом gen_secrets.py, собирает .env/.env.watchdog из канон-.example, поднимает orchestrator + orchestrator-watchdog, регистрирует проект кирпичом onboard_project.py и проверяет health. Изменение аддитивно и вне рантайма: src/**/STAGE_TRANSITIONS/QG_CHECKS/схема БД — не трогаются; kill-switch не нужен (активация — только явный запуск). Каноны не форкаются.

2. Задействованные модули / пути

Путь Действие
scripts/install_lite.py создать — интерактивный установщик Lite (entry-point; имя — OQ-1)
scripts/gen_secrets.py переиспользовать (subprocess-кирпич), без изменений
scripts/onboard_project.py переиспользовать (subprocess-кирпич, apply/verify), без изменений
.env.example, .env.watchdog.example переиспользовать как канон-источник рендера, без изменений
docker-compose.yml переиспользовать (docker compose up -d --build), без изменений
scripts/bootstrap_bundle.py эталон-паттерн (parse_env/render_env/preflight_verdict/manual_checkpoint/exit-коды) — не изменяется; общий код — OQ-4
docs/deployment/LITE_SETUP.md обновить — указатель на установщик как рекомендованный путь + синхронизация шагов
tests/test_install_lite_script.py создать — unit (чистые функции) + структурные анти-дрейф тесты
tests/test_lite_setup_doc.py обновить — ассерт ссылки на установщик; существующие ассерты зелёные
CLAUDE.md, CHANGELOG.md, docs/architecture/README.md, docs/overview/ обновить (docs golden-source, правило агентов №2)

3. Функциональные требования

FR-1 — Entry-point и режимы

Скрипт scripts/install_lite.py, запускаемый из корня чекаута: argparse, позиционный mode ∈ {plan, apply, verify} (дефолт plan). Exit-коды (контракт): 0 — успех; 2 — остановка на manual-step / незавершённое предусловие / нет TTY; 1 — ошибка. plan — ноль мутаций (печать плана + read-only preflight-диагностика). apply — полный прогон step-движком check→ensure (повтор = каскад skip; «resume» = повторный запуск). verify — read-only пост-проверка (health-контракты + onboard_project.py verify). Привязка: BR-1, BR-7.

FR-2 — Скан предусловий хоста (preflight)

Read-only снимок хоста (по образцу bootstrap_bundle.collect_facts/preflight_verdict): наличие docker, docker compose v2, git, python3, node, claude CLI + читаемость кред; свободность портов (прод-порт ORCH_DEPLOY_PROD_TARGET_PORT дефолт 8500, при self-hosting-вилке staging 8501); uid/gid/docker-gid и владелец каталога репозиториев; наличие ssh-каталога. Чистая функция- вердикт возвращает (blockers, warnings); человекочитаемый список «есть/нет». Привязка: BR-2.

FR-3 — Управляемая установка зависимостей (D-1)

Для каждого блокера-зависимости: детект пакетного менеджера (apt/dnf по наличию бинаря / /etc/os-release) → точная команда установки (чистая функция «дистрибутив+пакет → команда»); печать команды; для безопасных — предложение выполнить с согласия (y/N, input()); отказ/нет TTY/неизвестный дистрибутив → печать инструкции и exit 2 (никакой молчаливой root-мутации). Привязка: BR-3, AC-3.

FR-4 — Детект существующих Plane/Gitea + выбор (D-2)

Best-effort обнаружение (never-raise, NFR-3): кандидаты из docker ps (имена/образы, похожие на Plane: plane-*/makeplane/proxy; Gitea: gitea/gitea/gitea-*) и из слушающих портов (типовые Plane 80/8080/443, Gitea 3000). По кандидату — проба живости (Plane: GET /api/instances/; Gitea: GET /api/v1/version). Чистая функция формирует ранжированный список кандидатов. Поведение: 0 кандидатов → запрос ручного URL; ≥2 → нумерованный список + выбор (input() индекс), вне диапазона → ручной ввод; 1 → предложить с подтверждением. Выбор наполняет ORCH_PLANE_* / ORCH_GITEA_*. Привязка: BR-5, AC-4.

FR-5 — Интерактивный сбор данных + живая верификация

Honest-checkpoint контракт (как bootstrap_bundle.manual_checkpoint): для каждого требуемого секрета/параметра — печать откуда взять (ссылка на LITE_SETUP §5§8), скрытый ввод секрета (getpass), верификация ДО записи: Plane — GET /api/v1/workspaces/<slug>/projects/ с X-API-Key; Gitea — GET /api/v1/user с Authorization: token; Telegram — GET /bot<token>/getMe. Провал → повтор (до N) или exit 2 с подсказкой, значение не пишется. Авто-детект и пред-заполнение всего детектируемого (uid/gid/docker-gid/порты/пути/node/claude/выбранные URL) — оператор только подтверждает. Привязка: BR-4, AC-5.

FR-6 — Выпуск webhook-секретов кирпичом gen_secrets.py

ORCH_PLANE_WEBHOOK_SECRET / ORCH_GITEA_WEBHOOK_SECRET выпускаются строго субпроцессом gen_secrets.py (никакого собственного secrets.token_hex в установщике — анти-форк, AC-7); если уже присутствуют в .env и валидны — пропуск (не перетирать без --force). Привязка: BR-6, NFR-2.

FR-7 — Сборка .env / .env.watchdog

Идемпотентный рендер из канона (render_env-паттерн): существующий файл — обновить ключи- override, отсутствующий — отрендерить из .env.example / .env.watchdog.example; комментарии канона сохранены; неизвестные ключи — управляемым блоком в конец; запись правами 600; значения секретов в stdout/лог не попадают; молчаливой перезаписи нет. Watchdog-ключи (WATCHDOG_TG_*) кладутся только в .env.watchdog (файл-носитель, LITE_SETUP §4.3). Привязка: BR-6, NFR-2.

FR-8 — Подъём стека + готовность

docker compose up -d --build ровно orchestrator + orchestrator-watchdog (staging НЕ поднимается — за профилем). Ожидание готовности поллингом GET /health (таймаут). Перед записью ORCH_PROJECTS_JSON стек уже жив. Привязка: BR-1.

FR-9 — Регистрация проекта кирпичом onboard_project.py

Сбор параметров проекта (имя/repo/prefix/стек/тест-команда/порты/webhook-URL — флаги или интерактивно), вызов onboard_project.py apply затем verify субпроцессом; парс merged-ORCH_PROJECTS_JSON из отчёта и запись в .env; ручные пункты отчёта (manual-step) пробрасываются оператору. Никакого собственного создания статусов/лейблов/репо (анти-форк, 22 статуса — только онбординг-кирпич). Привязка: BR-6, AC-7.

FR-10 — Health-верификация + сводка

После apply (и в verify): GET /health → 200, GET /queue / GET /metrics → валидный JSON. Итоговая сводка по шагам (ok/skipped/manual-step) + общий вердикт; любой FAIL → exit 1 с диагностикой (хвост docker logs / снапшот). Привязка: BR-7, AC-11.

FR-11 — Синхронизация документации

LITE_SETUP.md дополняется указателем «рекомендованный путь — install_lite.py; ручной маршрut ниже как фолбэк/референс». Обновляются CLAUDE.md (раздел тиража), docs/architecture/README.md (Type A), docs/overview/ (если затронута витрина), CHANGELOG.md. Привязка: BR-9, AC-12.

4. Изменения API

Нет. Установщик — вне процесса орка; обращается только к существующим read-only эндпоинтам (/health, /queue, /metrics) как HTTP-клиент и к собственным Plane/Gitea/Telegram заказчика. Новых/изменённых эндпоинтов оркестратора не вводится.

5. Изменения схемы БД

Нет. Установщик не касается БД оркестратора (её создаёт сам орк пустой при первом старте, stateless-инвариант LITE_SETUP §12).

6. Требования к новым/изменённым QG checks

Нет. QG_CHECKS / check_* / STAGE_TRANSITIONS / machine-verdict ключи — байт-в-байт не трогаются (INV-1). Установщик не участвует в решении ни одного гейта.

7. Конфигурация

Новых рантайм-ключей config.py / kill-switch — нет (NFR-1; активация = явный запуск). Установщик читает/пишет только .env / .env.watchdog (канон ключей — .env.example / .env.watchdog.example, ORCH-101). CLI-флаги установщика (имена — OQ-7): режим + параметры проекта для onboard_project.py (--repo/--prefix/--stack/…), возможный --force (перевыпуск секретов), возможный --non-interactive/значения из env для CI.

8. Наблюдаемость

  • Прогресс-лог по шагам (ok/skipped/manual-step/error) — без значений секретов (только имена ключей/пути файлов, NFR-2).
  • Итоговая сводка PASS/FAIL + код выхода 0/2/1.
  • manual_checkpoint печатает точную инструкцию и верифицирует результат (молчаливый пропуск запрещён); без TTY → exit 2 с той же инструкцией.

9. Артефакты pipeline (создаются/обновляются)

  • scripts/install_lite.py (новый исполняемый артефакт).
  • tests/test_install_lite_script.py (новый), tests/test_lite_setup_doc.py (обновление).
  • docs/work-items/ORCH-104/06-adr/ADR-001-<slug>.md (архитектор) + опц. сквозной docs/architecture/adr/adr-NNNN-*.md.
  • docs/deployment/LITE_SETUP.md, CLAUDE.md, docs/architecture/README.md, docs/overview/, CHANGELOG.md — обновления (BR-9).

10. Совместимость / регресс

Аддитивно: новый файл-скрипт + новый тест + правки docs. Существующие кирпичи (gen_secrets.py, onboard_project.py) и compose — байт-в-байт. Полный регресс pytest tests/ -q остаётся зелёным. Обратимость — тривиальная (удаление нового файла/теста). Область раската — только хосты заказчиков Lite; наш прод не затронут (установщик исполняется на чужом хосте, говорит только с локальным хостом и инфраструктурой заказчика).

11. Инварианты (не нарушать)

  • INV-1src/** / STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict ключи / схема БД — байт-в-байт.
  • INV-2 — Каноны не форкаются: секреты — gen_secrets.py; статусы/лейблы/репо/webhook — onboard_project.py; env — из .env.example/.env.watchdog.example; стек — из docker-compose.yml.
  • INV-3 — Нет delete-операций (никаких docker … rm, rm -rf, удаления веток, force-push).
  • INV-4 — Секреты не печатаются; .env/.env.watchdog — права 600; без молчаливой перезаписи.
  • INV-5 — Никогда не трогает наш прод / main / force-push; говорит только с локальным хостом и собственными Plane/Gitea/Telegram заказчика.
  • INV-6 — Платформенные конвенции: репо orchestrator; имена compose-сервисов/профиля — константы; staging за профилем; ORCH_STAGING_PORT ≠ прод-порт (guard ORCH-058) — установщик уважает, не форкает.
  • INV-7 — stdlib-only (NFR-6).

12. Открытые вопросы для архитектора (OQ — не блокируют анализ)

  • OQ-1 — Финальное имя/путь: scripts/install_lite.py (понятно конечному оператору) vs scripts/bootstrap_lite.py (симметрия с bootstrap_bundle.py). Рекомендация анализа — install_lite.py.
  • OQ-2 — Точные эвристики детекта Plane/Gitea (паттерны имён/образов контейнеров, набор портов/URL-проб, ранжирование уверенности).
  • OQ-3 — Какие зависимости считать «безопасными для авто-выполнения с согласия» (напр. pip install -r requirements.txt в venv — да; apt install docker под sudo — только consent; claude CLI через npm); владелец distro-команд-карты.
  • OQ-4 — Общий код с bootstrap_bundle.py (вынести parse_env/render_env/manual_checkpoint в общий stdlib-модуль) vs самодостаточный один файл (ради «1 установочный файл» и stdlib-only). Trade-off DRY ↔ простота/одно-файловость.
  • OQ-5 — Драйвить ли путь Б Plane-webhook (raw-SQL, LITE_SETUP §5.4) автоматически (как bootstrap_bundle.step_plane_webhook) или всегда оставлять верифицируемым manual-step.
  • OQ-6 — Подтвердить: интерактивный логин claude CLI остаётся manual-step с верификацией (claude --version + читаемость кред), не автоматизируется.
  • OQ-7Набор CLI-флагов/env для не-интерактивного (CI) прогона: какие входы принимают флаги/env vs только prompt.