Files
orchestrator/docs/work-items/ORCH-103/02-trz.md

22 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-103 analysis analyst ready-for-review 2026-06-11 claude-opus-4-8

02 — ТЗ (TRZ): ORCH-103 — ORCH-10b Bundled-тираж: весь стек одним комплектом + bootstrap-скрипт

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

ТЗ фиксирует что должно измениться и где (артефакты/контракты/границы). Как (расположение bundle-каталога, состав сервисов Plane-стека, язык/режимы bootstrap, механизм сетевой связности) — решает архитектор в 06-adr/. Архитектурные решения здесь не принимаются.


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

Добавить в репо Bundled-комплект тиража (Type B эпика ORCH-10): (1) отдельный bundle-compose всего стека (орк + watchdog + Gitea + Plane-стек ~14 контейнеров), (2) bootstrap-скрипт, доводящий свежеподнятый стек до рабочего конвейера одним запуском (с явными manual-step чекпоинтами там, где Plane CE API не позволяет автоматизацию), (3) генерацию новых секретов на инсталляцию (reuse gen_secrets.py + bundle-внутренние креды), (4) инструкцию docs/deployment/BUNDLED_SETUP.md с требованиями к хосту, (5) структурные анти-дрейф тесты. Всё — вне рантайма и вне конвейера: src/**, корневой docker-compose.yml, Dockerfile, STAGE_TRANSITIONS/QG_CHECKS/схема БД — байт-в-байт (паттерн ORCH-009/ORCH-102). Kill-switch не требуется: активация — только явный запуск оператором на целевом хосте.


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

Путь Действие Назначение
deploy/bundled/docker-compose.yml (рабочая гипотеза; финальное расположение/имя — ADR; далее «bundle-compose») создать Compose-комплект всего стека (FR-1)
deploy/bundled/.env.bundled.example (имя — ADR; далее «bundle-конфиг-канон») создать Канон 100% переменных bundle (порты/версии/плейсхолдеры кред), паттерн .env.watchdog.example
scripts/bootstrap_bundle.py (имя/язык — ADR) создать Bootstrap-скрипт (FR-2)
docs/deployment/BUNDLED_SETUP.md создать Golden source инструкции Bundled-тиража (FR-4)
docs/operations/REPLICATION.md изменить (точечно) §1: строка Type B → ORCH-103 + ссылка на BUNDLED_SETUP.md (FR-6)
tests/test_bundle_compose.py создать Структура bundle-compose + изоляция корневого compose (FR-5)
tests/test_bundled_setup_doc.py создать Канон дока, env-ключи, FORBIDDEN/секрет-эвристика, кросс-рефы (FR-5)
tests/test_bootstrap_script.py создать Структурные/unit-ассерты bootstrap (FR-5)
CHANGELOG.md изменить Запись feat: ORCH-103
.gitignore изменить (при необходимости) Сгенерированные на хосте конфиги bundle не коммитятся (NFR-3)
НЕ трогать: src/**, корневой docker-compose.yml, Dockerfile, .gitea/workflows/**, .env.example (кроме явно обоснованного в ADR аддитива), onboarding/**, промпты .openclaw/agents/** NFR-1; анти-дрейф test_lite_setup_doc.py (TC-04: ровно 3 сервиса, нет plane*/gitea*) и test_no_host_hardcodes.py остаются зелёными

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

FR-1 — Bundle-compose всего стека (BR-1)

  • Отдельный файл, корневой docker-compose.yml не изменяется (жёсткое ограничение: анти-дрейф TC-04 tests/test_lite_setup_doc.py проверяет точное множество сервисов корневого compose и запрещает подстроки plane/gitea в именах сервисов/образов/контейнеров).
  • Состав стека: orchestrator (образ собирается из существующего корневого Dockerfile — без его правки), orchestrator-watchdog (существующий watchdog/Dockerfile), Gitea (+ её хранилище), полный Plane CE-стек (~14 контейнеров: web/admin/space/api/worker/beat/ live/migrator + postgres/redis/mq/minio/proxy — точный состав и версии пиннит архитектор по upstream-référence). Staging-контур орка (8501) — НЕ в дефолтном up (вне скоупа заказчика; включать ли за профилем — ADR).
  • Пиннинг версий всех сторонних образов (тег или digest; не latest) — NFR-6.
  • Тома: только именованные/каталожные тома bundle (узнаваемый префикс); чистый первый старт; пересечений с томами/путями нашего прод-контура нет.
  • Сеть и достижимость (двунаправленно): (a) Plane→орк и Gitea→орк webhooks доставляются; (b) орк→Plane API и орк→Gitea API доступны; (c) git push/fetch агентов в Gitea работает. Механизм (bridge-сеть + публикация портов, extra_hosts: host-gateway, host-network — что выбрать) — ADR; ТЗ фиксирует только инвариант достижимости, проверяемый smoke (FR-6).
  • Порты: карта портов по умолчанию задокументирована (BUNDLED_SETUP «Требования к хосту»); порты конфигурируемы через bundle-конфиг; конфликт порта → отказ preflight bootstrap (FR-2), не молчаливый сбой. Дефолт порта орка — существующий 8500 (ORCH_DEPLOY_PROD_TARGET_PORT).
  • Конфиг-канон: все параметры bundle (порты/версии/пути/плейсхолдеры кред) — в bundle-конфиг-каноне; key-set синхронизируется структурным тестом (паттерн key-sync .env.watchdog.example, D5 ORCH-102). Ключи орка НЕ дублируются — .env орка собирается bootstrap'ом из существующего канона .env.example.

FR-2 — Bootstrap-скрипт: один запуск до рабочего состояния (BR-2, BR-6, BR-7)

Последовательность (нумерация — норматив поведения; механика шагов — ADR):

  1. Preflight (fail-fast, до любых мутаций): docker+compose присутствуют; свободные RAM/диск ≥ задокументированных минимумов; целевые порты свободны; тома bundle отсутствуют (чистый хост) — иначе явный отказ с подсказкой (BR-7); наличие Claude CLI/кред — warning (не блокер: конвейер без LLM не поедет, но стек поднимется).
  2. Секреты (FR-3): генерация полного набора НОВЫХ секретов инсталляции.
  3. Up: подъём bundle-compose; ожидание готовности каждого сервиса (healthcheck/готовность БД/завершение миграций Plane и Gitea) с таймаутами и внятной диагностикой.
  4. Init Gitea: административная учётка + API-токен (через официальные механизмы Gitea — CLI/env/API; конкретика — ADR); branch protection НЕ настраивается (норматив D10 ORCH-009).
  5. Init Plane: instance-setup/workspace/API-токен. Всё, что недоступно в CE по API, — интерактивный manual-step чекпоинт: скрипт печатает точную инструкцию (URL/что нажать/ что ввести), ждёт подтверждения, проверяет результат (например, валидность введённого API-токена запросом) и только тогда продолжает (fail-safe; молчаливый пропуск запрещён).
  6. Онбординг sandbox-проекта: вызов scripts/onboard_project.py apply + verify (22 статуса из plane_sync._PLANE_NAME_TO_KEY, лейблы autoApprove/autoDeploy/Bug, Gitea-репо, per-repo webhook под глобальным секретом). Собственная реализация этих шагов в bootstrap запрещена (BR-6, нулевой дрейф канона).
  7. Git-доступ агентов: обеспечить push/fetch созданного репо из контейнера орка (ssh-ключ + регистрация в Gitea ИЛИ токен-remote — механизм ADR); клон репо в repos-каталог орка (ORCH_HOST_REPOS_DIR).
  8. Конфиг орка: собрать .env (на базе .env.example: URL'ы Plane/Gitea bundle-инсталляции, токены, webhook-секреты, ORCH_PROJECTS_JSON из вывода onboard) и .env.watchdog (из .env.watchdog.example); файлы остаются только на целевом хосте.
  9. Health + итог: GET /health, GET /queue, GET /metrics зелёные; финальная сводка PASS/FAIL по всем шагам + следующая команда оператора (smoke FR-6).

Требования к скрипту:

  • Идемпотентность: повторный запуск на уже-инициализированном bundle безопасен (ensure/skip-семантика, как onboard_project.py apply); никаких delete-операций.
  • Exit-коды: 0 — успех; 2 — остановка на manual-step/незавершённое предусловие; 1 — ошибка (паттерн onboard_project.py).
  • Логи без секретов (NFR-3): значения кред не печатаются (только имена ключей/пути файлов).
  • Никогда не адресует наш прод: в скрипте нет боевых хостов/путей (FORBIDDEN-скан), работает только с локальным docker целевого хоста.
  • Желателен режим plan (печать шагов без мутаций, паттерн ORCH-009) — финально ADR.

FR-3 — Инициализация секретов: новые на каждую инсталляцию (BR-4)

  • Webhook-секреты орка — строго через существующий scripts/gen_secrets.py (не реализовывать заново).
  • Bundle-внутренние креды (генерирует bootstrap, криптослучайно, stdlib secrets): пароли postgres/redis*/mq/minio Plane-стека, секрет-ключи Plane, админ-пароль и API-токен Gitea. В репо — только плейсхолдеры в bundle-конфиг-каноне; ни одного дефолтного пароля.
  • Внешние секреты заказчика (не генерятся, чек-лист в доке): Anthropic/Claude CLI доступ, Telegram-токены (опционально), ORCH_PLANE_API_TOKEN (если выдаётся вручную на manual-step).
  • Сгенерированные файлы: только на целевом хосте, права 600, в .gitignore; повторный запуск НЕ перетирает существующие секреты без явного флага (паттерн --force gen_secrets).

FR-4 — docs/deployment/BUNDLED_SETUP.md (BR-5)

  • Канон LITE_SETUP (ORCH-102): нормативные разделы в порядке маршрута оператора; каждый исполняемый шаг = fenced-команда + явная «Проверка:» с PASS/FAIL; хост-специфика — только плейсхолдеры; запрещены FORBIDDEN-литералы и реальные секреты (структурный тест).
  • Обязательные разделы (минимум; точные заголовки — автор дока, проверяемость — тест): (1) рамка Bundled (что входит/что НЕ входит: Claude CLI, Telegram, HTTPS; границы vs Lite); (2) требования к хосту — RAM/диск/CPU/порты, явно «Plane ≈ 14 контейнеров», финальные цифры — по замеру на тестовом развёртывании; (3) предусловия (docker/compose/sudo); (4) получение кода; (5) секреты; (6) запуск bundle-compose; (7) bootstrap (включая перечень manual-step чекпоинтов Plane); (8) LLM/Claude CLI (ссылкой на канон LITE_SETUP §7); (9) Telegram (ссылкой на LITE_SETUP §8); (10) онбординг следующих проектов (ссылкой на ONBOARDING.md); (11) smoke (шаги REPLICATION §4); (12) stateless-проверка; (13) остановка/полный сброс инсталляции; (14) траблшутинг (минимум: webhook не доходит, не хватает RAM/OOM, порт занят, claude не найден, Plane-миграции не завершились).
  • Канон не форкается: общие с Lite шаги — ссылками (LITE_SETUP §5§8, ONBOARDING §1, REPLICATION §2§4), не копипастой; fail-closed имена Confirm Deploy/STOP и «22 статуса» — согласованы с plane_sync._PLANE_NAME_TO_KEY (число — сверкой импорта в тесте, не литералом).

FR-5 — Структурные анти-дрейф тесты (BR-9)

Все тесты — без docker/сети/LLM/subprocess-мутаций (CI-безопасные; паттерн test_lite_setup_doc.py):

  • bundle-compose: файл существует, валидный YAML; обязательные сервисы присутствуют (orchestrator, orchestrator-watchdog, Gitea, Plane-стек — по списку из ADR); все сторонние образы пиннованы (нет :latest/безтегового образа); корневой docker-compose.yml НЕ изменён (множество сервисов == текущему эталону);
  • док: BUNDLED_SETUP.md существует, несёт обязательные разделы (включая «Требования к хосту»), каждый env-ключ из дока существует в канонах (.env.example bundle-конфиг-канон), кросс-ссылки на LITE_SETUP/ONBOARDING/REPLICATION присутствуют;
  • гигиена: FORBIDDEN-литералы (импорт списка из test_no_host_hardcodes.py) отсутствуют в bundle-compose/доке/bootstrap; секрет-эвристика (hex ≥32 / alnum ≥40, паттерн D8 ORCH-102) по новым файлам;
  • bootstrap: скрипт существует; структурно ссылается на gen_secrets/onboard_project (не дублирует канон); не содержит delete-операций уровня docker volume rm/rm -rf вне явного отдельного «сброс»-режима; чистые функции (preflight-решение, сборка плана шагов, рендер .env) покрыты unit-тестами;
  • кросс-рефы: REPLICATION.md §1 несёт отметку Type B → BUNDLED_SETUP.md; CHANGELOG содержит ORCH-103.

FR-6 — Smoke и наблюдаемость результата (BR-3)

  • Smoke Bundled = шаги REPLICATION §4 (06) поверх bundle-инсталляции, зафиксированные в BUNDLED_SETUP §smoke: config-резолв → /health/queue+/metrics → onboard verify → тестовая задача (Plane issue → «To Analyse» → job в очереди) → минимальный сигнал: артефакты 0104 в ветке → опционально полный цикл до done.
  • Прохождение фиксируется оператором по PASS/FAIL каждого шага; это ручная приёмка AC-2 (e2e в CI не гоняется — нет docker/LLM).

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

Нет. Эндпоинты орка не добавляются/не меняются; bundle использует существующие /health, /queue, /metrics, вебхуки /webhook/plane, /webhook/gitea.

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

Нет (схема БД орка не тронута). БД Plane/Gitea внутри bundle — их собственные, на чистых томах инсталляции; к схеме орка отношения не имеют.

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

Нет. Реестр QG_CHECKS/check_*/STAGE_TRANSITIONS — байт-в-байт. Bundled-тираж — это артефакты дистрибуции, а не гейты конвейера.


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

  • Kill-switch не требуется (паттерн ORCH-009): артефакты вне рантайма; в нашем контуре ничего их не исполняет; активация — явный запуск оператором на целевом хосте.
  • Нулевая регрессия: корневой compose/Dockerfile/src/** не изменены ⇒ наш прод, staging-контур и enduro-trails не затронуты по построению; существующие анти-дрейф тесты (test_lite_setup_doc.py, test_no_host_hardcodes.py, канон-тесты ORCH-009) остаются зелёными без правки их ассертов.
  • Обратимость: удаление bundle-каталога/скрипта/дока возвращает репо в текущее состояние; на целевом хосте полный сброс = задокументированная процедура (FR-4 §13).
  • Эскалация: если при реализации выяснится необходимость править src/**/корневой compose (например, недостающая параметризация, не закрытая ORCH-101) — это выход за рамки ТЗ: остановиться и вернуть задачу с обоснованием (CLAUDE.md правило 4), не «дотачивать молча».

8. Артефакты pipeline (создать/обновить в ТОМ ЖЕ PR)

  • docs/work-items/ORCH-103/06-adr/ADR-001-<slug>.md — решения архитектора (см. §9 OQ); при сквозном значении — зеркало в docs/architecture/adr/adr-NNNN-<slug>.md.
  • docs/architecture/README.md — раздел «Bundled-тираж (ORCH-103)» рядом с 10-common/Lite.
  • CLAUDE.md — краткий абзац Type B (паттерн абзацев ORCH-101/102).
  • docs/operations/REPLICATION.md §1 — отметка Type B (FR-6).
  • CHANGELOG.mdfeat: ORCH-103 ….
  • При выявлении инфра-предусловий целевого хоста — 07-infra-requirements.md (архитектор).

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

  • OQ-1 Расположение/имя bundle-каталога и compose-файла (deploy/bundled/ vs bundle/; один compose vs include-композиция); судьба staging-контура орка в bundle (исключить vs профиль).
  • OQ-2 Точный состав/версии Plane CE-стека (по upstream selfhost-référence) и Gitea; стратегия пиннинга (тег vs digest).
  • OQ-3 Перечень физически автоматизируемых шагов инициализации Plane CE (instance-setup/ workspace/API-токен): что через API/CLI/seed, что — manual-step чекпоинт.
  • OQ-4 Язык и режимы bootstrap (python stdlib vs bash; plan/apply vs линейный визард); способ ожидания готовности (healthchecks vs poll).
  • OQ-5 Механизм сетевой связности орк (host network?) ⟷ bundle bridge-сеть: публикация портов, host-gateway, либо весь bundle в host-network — и согласование URL вебхуков.
  • OQ-6 Механизм git-доступа агентов к bundle-Gitea (ssh-ключ vs http-токен) и наполнение repos-каталога.
  • OQ-7 Делать ли отдельный явный «сброс»-режим (teardown) частью скрипта или только документированной процедурой в BUNDLED_SETUP §13.