24 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-102 | analysis | analyst | ready-for-review | 2026-06-10 | claude-opus-4-8 |
02 — ТЗ (TRZ): ORCH-102 — ORCH-10a Lite-тираж: перенос орк+watchdog + полная инструкция донастройки окружения
Work Item: ORCH-102 · Repo: orchestrator · Стадия: analysis
ТЗ описывает что должно измениться и где (документы/контракты/тесты), выведено из BRD и фактического кода (аудит выполнен по репо на ветке задачи; ORCH-101 уже в
main). Как (точная разбивка разделов дока, форма анти-дрейф тестов, исходы вопросов §3.8) — решает архитектор в06-adr/.
1. Сводка изменения
Docs-first задача (паттерн ORCH-077/092: документы + тесты, рантайм не трогается).
Создаётся главный продукт — инструкция docs/deployment/LITE_SETUP.md (golden source Lite-тиража,
новый раздел docs/deployment/), которая собирает существующие кирпичи 10-common
(REPLICATION/ONBOARDING/SETUP_WEBHOOKS/INFRA, gen_secrets.py, onboard_project.py, smoke §4)
в один сквозной маршрут «голый хост → работающий конвейер» для заказчика. Дополнительно:
структурные анти-дрейф тесты (полнота дока, compose-подмножество, stateless/секрет-гигиена),
перекрёстные ссылки и CHANGELOG.
Ожидаемый дифф: docs/**, tests/**, CHANGELOG.md (+ опционально .env.watchdog.example —
исход А-4). src/** — ноль изменений; конвейер
(STAGE_TRANSITIONS/QG_CHECKS/check_*/machine-verdict/схема БД) — байт-в-байт.
2. Задействованные модули / пути
| Путь | Действие |
|---|---|
docs/deployment/LITE_SETUP.md |
создать — главный продукт (полная пошаговая инструкция Lite; новый каталог docs/deployment/) |
docs/operations/REPLICATION.md |
изменить: §1 таблица границ — строка «Type A — Lite» → статус ✅ ORCH-102 + ссылка на LITE_SETUP.md |
tests/test_lite_setup_doc.py |
создать — структурные анти-дрейф проверки дока + compose-подмножества (образец: tests/test_replication_smoke.py) |
.env.watchdog.example |
создать по исходу А-4 (канон конфигурации sidecar-watchdog для нового хоста; сейчас примера нет, compose читает .env.watchdog required: false) |
docs/operations/INFRA.md |
изменить при необходимости: перекрёстная ссылка на deployment-раздел (по фактическому объёму) |
README.md |
изменить: обзорный док — способность Lite-тиража (правило агентов №6: не выдавать открытое за решённое и наоборот) |
CLAUDE.md |
изменить: блок ORCH-102 в паспорте — по фактическому объёму (правило №2) |
CHANGELOG.md |
изменить: запись ORCH-102 |
src/**, docker-compose.yml, Dockerfile, scripts/** |
НЕ менять (читаются инструкцией/тестами как источник истины; любое отклонение — только через ADR архитектора) |
Кирпичи, которые инструкция переиспользует по ссылке (не форкает, BR-6/NFR-4):
docs/operations/REPLICATION.md (карта env §2, секреты §3, smoke §4),
docs/operations/ONBOARDING.md (статусы §1, слои Gitea/kit/реестр §2–5),
docs/operations/SETUP_WEBHOOKS.md (формат вебхуков, Plane CE-каверза),
scripts/gen_secrets.py, scripts/onboard_project.py (plan/apply/verify),
.env.example (канон 100% ключей), GET /health|/queue|/metrics.
3. Функциональные требования
FR-1 — Документ docs/deployment/LITE_SETUP.md: состав и форма
Привязка: BR-1, BR-2. Нормативный перечень разделов (порядок = маршрут оператора; финальную разбивку/нумерацию решает архитектор, состав — обязательный минимум):
- Рамка Lite — что разворачиваем (орк+watchdog), что заказчик ставит сам (Plane/Gitea/
Telegram/LLM), границы vs 10-common vs Bundled (ссылка на REPLICATION.md §1), платформенные
конвенции (репо
orchestrator, имена сервисов, контейнерный layout — не менять). - Предусловия хоста («зависимости, uid/gid» из бизнес-запроса): поддерживаемый контур
(Linux x86_64, Docker Engine + Compose v2, git, python3); node + дистрибутив claude-code на
хосте (
ORCH_HOST_NODE_BIN,ORCH_HOST_CLAUDE_CODE_DIR— пути под маунты); пользователь и владение каталогами:ORCH_RUN_UID/GID= uid владельцаORCH_HOST_REPOS_DIR(инвариант ORCH-040),ORCH_DOCKER_GID—getent group docker; ssh-ключи деплой-хука (ORCH_HOST_SSH_DIR); свободные порты (ORCH_DEPLOY_PROD_TARGET_PORT=8500,ORCH_STAGING_PORT=8501). Каждое предусловие — команда проверки. - Перенос кода орк+watchdog: получение чекаута репо
orchestratorна хост вORCH_DEPLOY_HOST_REPO_PATH(источник кода — параметризованный шаг, исход А-6); НИКАКИХ данных/БД/.envс боевого хоста (D-2). Watchdog отдельно не переносится — код вwatchdog/того же репо, образ собирается локально compose'ом. - Конфигурация:
.envстроится с нуля от.env.example(канон); webhook-секреты —python3 scripts/gen_secrets.py [--write]; карта переменных — ссылкой на REPLICATION.md §2; в доке явно — обязательные ключи нового хоста:ORCH_PLANE_API_URL/WEB_URL/WORKSPACE_SLUG,ORCH_PLANE_API_TOKEN,ORCH_GITEA_URL/PUBLIC_URL/OWNER,ORCH_GITEA_TOKEN, оба webhook-секрета,ORCH_TELEGRAM_BOT_TOKEN/CHAT_ID,ORCH_PROJECTS_JSON(обязателен: встроенный fallback несёт UUID исходного хоста), хост-параметрыORCH_AGENT_HOME_DIR/ORCH_HOST_*/ORCH_RUN_*/ORCH_DOCKER_GID, когерентность портов (ORCH_DEPLOY_PROD_TARGET_PORT⇄WATCHDOG_METRICS_URL⇄ORCH_POST_DEPLOY_BASE_URL). - Подключение Plane (инсталляция заказчика): создать workspace/проект; точная модель
статусов — 22 канонических имени с группами: создаёт
onboard_project.py apply, таблица — ссылкой на ONBOARDING.md §1 (без форка; fail-closedConfirm Deploy/STOPупомянуть явно); выпуск API-токена (Workspace Settings → API tokens) + команда проверки; webhook+HMAC: URL…/webhook/plane, секрет изgen_secrets.py, заголовокX-Plane-Signature; каверза Plane CE «webhook не экспонирован в /api/v1» — оба пути (UI и прямой SQL, generic-вариант команд SETUP_WEBHOOKS.md с плейсхолдерами). - Подключение Gitea (инсталляция заказчика): репо (
onboard_project.pyили вручную), токен (scoperepo,admin:repo_hook) + проверка, per-repo webhook (eventspush/pull_request/status,X-Gitea-Signature, ОДИН глобальный секрет на все репо); норматив защитыmain— по исходу А-1 (канон: branch protection НЕ включать, ORCH-009 ADR D10). - LLM-доступ (claude CLI): дистрибутив claude-code и node на хосте (пути = маунты compose),
ORCH_CLAUDE_BIN; аутентификация CLI на хосте (каталогORCH_HOST_CLAUDE_DIR+ORCH_HOST_CLAUDE_JSON— монтируются в контейнер; команда первичного логина/проверки —claude --version/ минимальный вызов); конфигурация моделей —ORCH_AGENT_MODEL_*/ORCH_AGENT_EFFORT_*(резолв ORCH-41; дефолты канона — в.env.example). - Telegram: бот трекера (BotFather
/newbot→ORCH_TELEGRAM_BOT_TOKEN), получениеchat_id(воспроизводимая команда, например черезgetUpdates), проверкаgetMe; отдельный watchdog-бот (WATCHDOG_TG_BOT_TOKEN/CHAT_ID— независимый канал, C-1 ORCH-100, токен орка переиспользовать запрещено) — размещение ключей по исходу А-4 (.env.watchdog). - Запуск compose-подмножества:
docker compose config(резолв без ошибок) →docker compose up -d --build→ поднимаются ровноorchestrator+orchestrator-watchdog(AC-2); staging-профиль — опционально/когда нужен (исход А-5); health-чек:GET /health→ 200"status":"ok",GET /queue/GET /metrics→ штатный JSON (schema_version: 1). - Регистрация проекта заказчика:
onboard_project.py plan → apply → verify(Plane-проект+статусы+лейблыautoApprove/autoDeploy/Bug, Gitea-репо+webhook, kit, mergedORCH_PROJECTS_JSON) → внести строку в.env→ управляемый рестарт → проверка/health+/queue(маршрут ONBOARDING.md, ссылкой; в Lite-доке — последовательность команд). - Smoke (AC-4): чек-лист REPLICATION.md §4 (шаги 0–5, опционально 6 до
done) — переиспользовать ссылкой + Lite-специфичные предусловия; критерий «конвейер доехал»: задача в БД → analyst-job в/queue→ артефакты01–04в ветке задачи. - Stateless-проверка (AC-3): первый старт создаёт пустую БД (
data/чист);GET /queue— нулевые счётчики, ни одной задачиORCH-*/ET-*; явная нормативная строка «данные/задачи/ секреты боевого хоста НЕ переносятся». - Траблшутинг первичной настройки: минимум — webhook 401/HMAC mismatch; «задача не
появилась» (реестр/
ORCH_PROJECTS_JSON/webhook); claude CLI не аутентифицирован/не найден;docker.sockpermission denied (ORCH_DOCKER_GID); права/repos(uid mismatch, ORCH-040/057); Telegram молчит (токен/chat-id). Каждый пункт — симптом → команда диагностики → лечение.
Форма (NFR-6, BR-1): каждый шаг — исполняемая команда (fenced code block) + явная проверка
(«Проверка:» / PASS-FAIL / ожидаемый вывод); все хост-специфичные значения в командах — только
плейсхолдеры <...> или $ENV_VAR (боевые mva154/82.22.50.71/реальные токены — запрещены);
язык — русский (канон доков платформы).
FR-2 — Compose-подмножество (AC-2)
Привязка: BR-3. Зафиксировать (в доке + тестом), что Lite-развёртывание использует
существующий docker-compose.yml БЕЗ форка:
- множество сервисов файла — ровно
{orchestrator, orchestrator-watchdog, orchestrator-staging}; orchestrator-stagingстрого заprofiles: [staging]→ дефолтныйdocker compose up -dподнимает ровно орк+watchdog;- сервисов/образов Plane/Gitea в compose НЕТ (и тест не даст появиться молча);
- форма фиксации (существующий файл vs отдельный lite-вариант) — исход А-2; ТЗ-рекомендация: существующий файл (он уже является подмножеством — факт BRD §1.3), отдельный файл не плодить.
FR-3 — Stateless-нормативы (AC-3)
Привязка: BR-4. Инструкция обязана: (а) предписывать чистый старт — пустой data/ (БД создаётся
init_db() при первом старте), .env только с нуля; (б) предписывать выпуск НОВЫХ секретов
(gen_secrets.py + чек-лист REPLICATION.md §3.2) и нести норматив «боевые секреты/данные/задачи
не копируются»; (в) содержать проверку чистоты (FR-1 п.12); (г) сама не содержать реальных
секретов (NFR-3; проверяется тестом FR-6 и security-гейтом ORCH-022).
FR-4 — Покрытие донастройки окружения без форка канона (AC-1)
Привязка: BR-2, BR-6. Per-system разделы FR-1 п.5–8 обязаны быть полными (заказчик не ходит за ответами вовне репо), при этом канонические данные даются ссылкой на golden source:
| Данные | Golden source | В LITE_SETUP.md |
|---|---|---|
| 22 статуса + группы | plane_sync._PLANE_NAME_TO_KEY / ONBOARDING.md §1 |
ссылка + критичные fail-closed имена (Confirm Deploy, STOP) |
| Карта env / хост-параметры | REPLICATION.md §2 / .env.example |
ссылка + список обязательных ключей нового хоста |
| Формат вебхуков / Plane CE-каверза | SETUP_WEBHOOKS.md | ссылка + generic-команды с плейсхолдерами |
| Онбординг проекта | ONBOARDING.md / onboard_project.py |
ссылка + последовательность команд Lite-маршрута |
| Smoke | REPLICATION.md §4 | ссылка + Lite-предусловия |
Если архитектор решит дублировать таблицу (читаемость) — дубль защищается анти-дрейф тестом
(сверка импортом из src/plane_sync.py / парсингом .env.example), не строковой копией.
FR-5 — Smoke на чистом окружении (AC-4)
Привязка: BR-5. Состав: (а) в LITE_SETUP.md — smoke-раздел (FR-1 п.11) как воспроизводимый
чек-лист с PASS/FAIL на каждый шаг; (б) приёмочный прогон процедуры на чистом контуре — минимум
staging-песочница (порт ORCH_STAGING_PORT, изолированная БД ./data/staging) + одноразовый
sandbox-проект (прецедент ORCH-101 AC-3 / ONBOARDING.md §5.2), без нового железа; (в) результат
прогона фиксируется в артефактах задачи (13-test-report.md / 15-staging-log.md); (г) прогон
на реальном новом хосте — желателен, но НЕ требование приёмки (нет железа в контуре задачи).
FR-6 — Анти-дрейф тесты (BR-8)
Привязка: BR-3, BR-6, BR-8. Новый tests/test_lite_setup_doc.py (структурный, без сети/LLM;
образец — tests/test_replication_smoke.py):
- док существует по канонному пути; несёт обязательные разделы/кирпичи FR-1 (минимум:
gen_secrets.py,onboard_project.py,docker compose,/health,/queue,/metrics,ORCH_PROJECTS_JSON, webhook-секреты,X-Plane-Signature/X-Gitea-Signature,getent group docker,Confirm Deploy/STOP, Telegram-боты обоих каналов, маркеры PASS/FAIL/«Проверка»); - каждый env-ключ
ORCH_*/WATCHDOG_*, упомянутый в доке, существует в.env.example(анти-опечатка/анти-дрейф канона); - compose-подмножество: парсинг
docker-compose.yml— ровно 3 сервиса, staging за профилем, ни одного сервиса/образаplane*/gitea*(AC-2); - stateless/секрет-гигиена: нормативная строка «не копиру…» присутствует; в доке нет
секретоподобных значений (эвристика по образцу security-паттернов) и боевых литералов
(
mva154,duckdns,82.22.50.71) в копируемых код-блоках; - перекрёстность: REPLICATION.md §1 ссылается на LITE_SETUP.md;
CHANGELOG.mdнесёт ORCH-102.
Точная нарезка по тест-модулям — за developer (план — 04-test-plan.yaml); существующие тесты
не правятся (кроме согласованных структурных дополнений).
FR-7 — Перекрёстная документация (BR-7)
Привязка: BR-7. REPLICATION.md §1 (строка Type A — Lite → ✅ + ссылка); README.md — способность Lite-тиража в обзоре (правило №6); CLAUDE.md — по фактическому объёму; CHANGELOG.md — запись. INFRA.md — ссылка на deployment-раздел при необходимости.
3.8. Вопросы архитектору (решаются в 06-adr/, не в ТЗ)
- А-1 — «pre-receive хуки» vs норматив ADR D10 (ORCH-009): бизнес-запрос упоминает
pre-receive хуки, но в платформе их нет, а branch protection на
mainнормативно запрещён (ломает PR-merge API merge-актора). Что фиксирует раздел Gitea? Рекомендация ТЗ: канон — репо+токен+webhook+явный норматив «branch protection НЕ включать»; pre-receive не вводить; отклонение — только отдельным ADR с анализом совместимости с merge-актором (ORCH-093/INV-4). - А-2 — форма compose-подмножества: существующий
docker-compose.yml(уже = подмножество)- документация/тест vs отдельный
docker-compose.lite.yml. Рекомендация: существующий, без форка (нулевой дрейф, AC-2 держит тест).
- документация/тест vs отдельный
- А-3 — размещение дока: бизнес-запрос фиксирует
docs/deployment/LITE_SETUP.md(новый разделdocs/deployment/); REPLICATION.md живёт вdocs/operations/. Подтвердить layout (deployment как витрина тиража vs operations) и перекрёстные ссылки; отступление от пути бизнес-запроса — только явным решением. - А-4 — канон watchdog-конфига нового хоста: compose читает
.env.watchdog(required: false), примера-файла нет; ключиWATCHDOG_*канонизированы в.env.example. Добавить.env.watchdog.example(симметрия с.env.staging.example) или документировать шаг «создай.env.watchdogс двумя ключами» в LITE_SETUP? Рекомендация: example-файл + упоминание в доке (меньше шансов перепутать файл-носитель). - А-5 — staging-контур в Lite-инструкции: обязателен ли запуск
orchestrator-stagingу заказчика? Рекомендация: опционален — нужен только если заказчик регистрирует проектorchestrator(self-hosting развитие платформы); для «раздачи на тест» базовый контур = prod-инстанс + watchdog; в доке — явная вилка. - А-6 — источник кода для заказчика: clone-URL (зеркало/доступ к нашему Gitea) vs архив.
В доке — параметризованный шаг
git clone <ORCHESTRATOR_GIT_URL>; конкретику источника фиксирует Владелец (вне репо).
4. Изменения API
Нет. Существующие GET /health / /queue / /metrics переиспользуются инструкцией read-only;
новые эндпоинты не вводятся.
5. Изменения схемы БД
Нет.
6. Требования к новым/изменённым QG checks
Нет. QG_CHECKS/check_*/machine-verdict ключи не меняются. Новые структурные тесты (FR-6) —
обычный pytest: попадают в существующие гейты (check_ci_green/check_tests_passed/merge-gate
re-test/coverage-гейт ORCH-027) автоматически, без регистрации нового QG.
7. Совместимость / регресс
- Нулевая регрессия (NFR-2): дифф — docs+tests (+опц.
.env.watchdog.example); рантайм не меняется; kill-switch не требуется (нечего выключать); полныйpytest tests/ -qзелёный, существующие структурные тесты (test_no_host_hardcodes,test_replication_smoke,test_infra_parametrization,test_onboarding_*) не ослабляются. - Обратимость: удаление дока/тестов возвращает состояние 1:1 (никаких миграций/состояния).
- Self-hosting (NFR-1): прод-контейнер не рестартится; выкат — штатный конвейер (deploy-staging 8501 → ручной Confirm Deploy). Для enduro-trails изменение инертно.
- Секрет-гигиена (NFR-3): в доке/тестах только плейсхолдеры; security-гейт (ORCH-022,
17-security-report.md) обязан остатьсяPASS. - Инварианты соседних маркеров (правило №9): ORCH-101 (дефолт = боевое значение; канон
.env.example; конвенции тиража REPLICATION §1), ORCH-009 (ADR D10 — без branch protection; onboarding-CLI ничего не удаляет), ORCH-100 (независимый Telegram-канал watchdog, C-1), ORCH-040 (uid/gid/HOME группа), ORCH-058 (staging ≠ прод-порт), INV-4 (мерж только через PR-merge API) — инструкция обязана им следовать, а не противоречить.