Files
orchestrator/docs/architecture/adr/adr-0038-bundled-replication-canon.md

11 KiB
Raw Permalink Blame History

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

adr-0038: Канон Bundled-тиража — deploy/bundled/ + bootstrap + BUNDLED_SETUP.md (ORCH-103, 10b)

Статус

Proposed

Контекст

Эпик ORCH-10 (D5 «Масштаб»), тип B — Bundled: заказчик без собственной инфраструктуры получает весь стек одним комплектом (орк + watchdog + Gitea + Plane CE ≈1314 контейнеров) и bootstrap, доводящий его до рабочего конвейера одним запуском. Фундамент готов: 10-common (ORCH-101, adr-0036 — хост-параметризация/секреты/smoke) и Lite (ORCH-102, adr-0037 — док-канон docs/deployment/). Корневой docker-compose.yml заморожен анти-дрейфом ORCH-102 (ровно 3 сервиса, запрет подстрок plane/gitea) → комплект обязан жить отдельным файлом.

Сквозной характер: вводится новый top-level каталог deploy/ (дистрибутивы развёртывания), новый канонический env-example и нормативы, обязательные для будущих задач эпика ORCH-10 и любого агента, меняющего шаги тиража. Детальный пакет решений (D1…D11, исходы OQ-1…OQ-7 ТЗ) — work-item ADR: docs/work-items/ORCH-103/06-adr/ADR-001-bundled-stack-compose-and-bootstrap.md.

Решение

  1. Новый top-level каталог deploy/ — исполняемые дистрибутивы развёртывания (дополняет docs/deployment/ — инструкции). Bundled-комплект: deploy/bundled/docker-compose.yml — один самодостаточный compose всего стека с top-level name: orchestrator-bundle (project name = узнаваемый префикс томов/контейнеров; container_name не пиннится — нет коллизий с корневым compose на одном хосте). Staging-контур орка в bundle отсутствует вовсе; репо orchestrator в bundle-инсталляции не регистрируется → self-deploy-машинерия структурно спит (SELF_HOSTING_REPO-леафы не матчатся).
  2. Конфиг-слои: deploy/bundled/.env.example — канон bundle-инфры (committed, плейсхолдеры; key-set-sync тест: каждая ${VAR}-интерполяция bundle-compose имеет ключ в каноне) → live deploy/bundled/.env (авто-чтение compose из project dir — без --env-file-футгана; покрыт неякорным .env в .gitignore); runtime орка/watchdog — корневые .env/.env.watchdog ровно по канону Lite (REPLICATION §2 применим 1:1), в bundle-compose — env_file: required: false (первый up жив до сборки конфига). Bootstrap — единственный писатель всех трёх live-файлов (когерентность дублируемых ключей — механическая). Один факт = одно имя (ORCH-101 D1): существующие факты — существующие ORCH_*-имена; bundle-only — BUNDLE_*; внутренние креды Plane — upstream-имена.
  3. Состав/пиннинг: Plane CE — зеркало официального selfhost-référence (upstream-имена сервисов/env); Gitea — gitea/gitea (не rootless). Пиннинг — точный неподвижный тег литералом (не latest, не интерполяция; digest не требуется); точные теги фиксирует developer по проверенному стенду; форму держит структурный тест.
  4. Сеть: одна именованная bridge-сеть; машинный трафик — строго сервис-DNS (http://orchestrator:8500/webhook/*, http://gitea:3000, plane-proxy); network_mode: host в bundle не используется (ssh-деплой-пути неактивны: ORCH_DEPLOY_SSH_HOST пуст). Наружу — только человеческие порты (Plane proxy 8080 / Gitea 3000 / орк 8500; конфигурируемы); БД/брокер/minio не публикуются. Публичные URL — от BUNDLE_PUBLIC_HOST (split internal/public уже в конфиге орка). Мина Gitea закрывается явно: GITEA__webhook__ALLOWED_HOST_LIST=orchestrator.
  5. Bootstrap scripts/bootstrap_bundle.py: python stdlib-only, без импортов из src/**; режимы plan (дефолт, ноль мутаций) / apply / verify; step-движок check→ensure (идемпотентность, resume = повторный запуск); exit 0/2/1. Preflight fail-fast до мутаций (docker/порты/чистота томов по префиксу/RAM/диск; Claude CLI — warning). Кирпичи не дублируются: секреты — субпроцесс gen_secrets.py; статусы/лейблы/репо/вебхуки — строго onboard_project.py apply+verify (host-venv, канон ONBOARDING). Init Gitea — полностью автоматом (CLI в контейнере; branch protection НЕ настраивается — D10 ORCH-009/adr-0037 п.4); init Plane CE — честные manual-step чекпоинты (инструкция → подтверждение → API-верификация; прогрессивная автоматизация разрешена без смены контракта). Git-доступ агентов — HTTP token-remote (паттерн _push_url); ssh-контур не вводится. Секреты в логи не печатаются; delete-операций в скрипте нет вообще — teardown только документированной процедурой (BUNDLED_SETUP §13).
  6. Док-канон: docs/deployment/BUNDLED_SETUP.md — 14 нормативных разделов по форме LITE_SETUP (fenced-команда + «Проверка:» PASS/FAIL, плейсхолдеры, общие шаги ссылками на LITE_SETUP/ONBOARDING/REPLICATION — канон не форкается), включая «Требования к хосту» с цифрами по замеру тестового развёртывания. REPLICATION §1: Type B → ORCH-103. Норматив сопровождения: изменил шаги Bundled-тиража → обнови BUNDLED_SETUP.md в том же PR.
  7. Анти-дрейф — постоянная CI-гарантия: tests/test_bundle_compose.py / test_bundled_setup_doc.py / test_bootstrap_script.py (структурные, без docker/сети/LLM: состав сервисов, заморозка корневого compose, пины, key-set-sync, разделы дока, FORBIDDEN — импортом из test_no_host_hardcodes.py, секрет-эвристика, ссылки на кирпичи, отсутствие delete-операций, unit чистых функций preflight/плана, exit-контракт).

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

src/**, корневой docker-compose.yml, Dockerfile, .gitea/workflows/**, onboarding/**, промпты .openclaw/agents/**; STAGE_TRANSITIONS, состав QG_CHECKS, семантика check_*, machine-verdict ключи, схема БД — байт-в-байт. Kill-switch не вводится (активация — только явный запуск оператора на целевом хосте, паттерн ORCH-009). Прод-контейнер в рамках задачи не рестартуется; наши данные/секреты не переносятся (stateless, решение Владельца 10.06).

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

  • Расширение корневого compose (профиль bundled) — отвергнуто: заморожен анти-дрейфом ORCH-102/нормативом «compose не форкается»; смешение дистрибутива с боевым контуром.
  • Include-композиция / live-env через --env-file — отвергнуто: лишние степени свободы запуска, молчаливые дефолты при забытом флаге.
  • Орк в bundle на host-network + host-gateway — отвергнуто: хост-сеть нужна была ssh-деплой-контуру нашего хоста, который в bundle спит; bridge даёт чистые двунаправленные сервис-DNS-URL.
  • Digest-пиннинг / rootless-Gitea / ssh-доступ агентов / bash-bootstrap / reset-режим скрипта — отвергнуты (см. work-item ADR-001, «Альтернативы»).

Последствия

  • Эпик ORCH-10 закрыт по обоим типам: A (Lite, инструкция) + B (Bundled, комплект); заказчик без инфраструктуры разворачивает конвейер «под ключ».
  • Цена: пиннованные версии Plane/Gitea стареют (апгрейд — отдельные задачи); manual-step Plane CE размывают «одну команду» — неустранимо честно (нет API), митигировано контрактом чекпоинта; двойной .env-слой — под единственным писателем-bootstrap и key-sync тестом.
  • Откат: удалить deploy/, bootstrap, BUNDLED_SETUP.md, три тест-модуля, строку REPLICATION §1 — состояние 1:1 (docs+scripts+tests, без миграций).

Связи

adr-0036 (ORCH-101 — фундамент 10-common: параметризация, gen_secrets, REPLICATION/smoke), adr-0037 (ORCH-102 — док-канон docs/deployment/, compose-подмножество, запрет branch protection), adr-0035 (ORCH-009 — onboarding-CLI: 22 статуса, manual-step паттерн, _push_url, D10), adr-0027/INV-4 (merge-актор — основание норматива Gitea), adr-0001 (SELF_HOSTING_REPO-конвенция — почему self-гейты в bundle спят). Детально — docs/work-items/ORCH-103/06-adr/ADR-001-bundled-stack-compose-and-bootstrap.md, 07-infra-requirements.md, 10-tech-risks.md.