22 KiB
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-04tests/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):
- Preflight (fail-fast, до любых мутаций): docker+compose присутствуют; свободные RAM/диск ≥ задокументированных минимумов; целевые порты свободны; тома bundle отсутствуют (чистый хост) — иначе явный отказ с подсказкой (BR-7); наличие Claude CLI/кред — warning (не блокер: конвейер без LLM не поедет, но стек поднимется).
- Секреты (FR-3): генерация полного набора НОВЫХ секретов инсталляции.
- Up: подъём bundle-compose; ожидание готовности каждого сервиса (healthcheck/готовность БД/завершение миграций Plane и Gitea) с таймаутами и внятной диагностикой.
- Init Gitea: административная учётка + API-токен (через официальные механизмы Gitea — CLI/env/API; конкретика — ADR); branch protection НЕ настраивается (норматив D10 ORCH-009).
- Init Plane: instance-setup/workspace/API-токен. Всё, что недоступно в CE по API, — интерактивный manual-step чекпоинт: скрипт печатает точную инструкцию (URL/что нажать/ что ввести), ждёт подтверждения, проверяет результат (например, валидность введённого API-токена запросом) и только тогда продолжает (fail-safe; молчаливый пропуск запрещён).
- Онбординг sandbox-проекта: вызов
scripts/onboard_project.py apply+verify(22 статуса изplane_sync._PLANE_NAME_TO_KEY, лейблыautoApprove/autoDeploy/Bug, Gitea-репо, per-repo webhook под глобальным секретом). Собственная реализация этих шагов в bootstrap запрещена (BR-6, нулевой дрейф канона). - Git-доступ агентов: обеспечить push/fetch созданного репо из контейнера орка
(ssh-ключ + регистрация в Gitea ИЛИ токен-remote — механизм ADR); клон репо в repos-каталог
орка (
ORCH_HOST_REPOS_DIR). - Конфиг орка: собрать
.env(на базе.env.example: URL'ы Plane/Gitea bundle-инсталляции, токены, webhook-секреты,ORCH_PROJECTS_JSONиз вывода onboard) и.env.watchdog(из.env.watchdog.example); файлы остаются только на целевом хосте. - 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; повторный запуск НЕ перетирает существующие секреты без явного флага (паттерн--forcegen_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 (0–6) поверх bundle-инсталляции, зафиксированные в
BUNDLED_SETUP §smoke: config-резолв →
/health→/queue+/metrics→ onboard verify → тестовая задача (Plane issue → «To Analyse» → job в очереди) → минимальный сигнал: артефакты01–04в ветке → опционально полный цикл до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.md—feat: ORCH-103 ….- При выявлении инфра-предусловий целевого хоста —
07-infra-requirements.md(архитектор).
9. Открытые вопросы для архитектора (не блокируют анализ)
- OQ-1 Расположение/имя bundle-каталога и compose-файла (
deploy/bundled/vsbundle/; один 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/applyvs линейный визард); способ ожидания готовности (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.