18 KiB
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-1 —
src/**/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(понятно конечному оператору) vsscripts/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.