Files
orchestrator/docs/work-items/ORCH-102/01-brd.md

23 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-102 analysis analyst ready-for-review 2026-06-10 claude-opus-4-8

01 — BRD: ORCH-102 — ORCH-10a Lite-тираж: перенос орк+watchdog + полная инструкция донастройки окружения

Work Item: ORCH-102 · Repo: orchestrator (self-hosting) · Стадия: analysis Заказчик: Слава · Эпик: ORCH-10 (домен D5 «Масштаб», docs/epics/self-evolution.md) · Тип: A — Lite


1. Бизнес-контекст и проблема

1.1. Цель эпика ORCH-10

Тираж платформы — РАЗДАЧА текущей функциональности нескольким заказчикам на тест. Решения Владельца 10.06 (приняты как требования, см. §1.4): ДВА типа тиража, ОБА stateless (наши задачи/данные/секреты НЕ переносим — чистый старт):

  • Тип A (Lite) — переносим ТОЛЬКО орк+watchdog на новую инфру; окружение (Plane / Gitea / LLM / Telegram) заказчик донастраивает сам по чёткой инструкции.
  • Тип B (Bundled) — весь стек одним комплектом (отдельная задача эпика, вне ORCH-102).

1.2. Проблема, которую закрывает ORCH-102

Фундамент 10-common (ORCH-101) уже в main: все хост-значения параметризованы env (docker compose config без переменных = боевое поведение 1:1), секреты выпускаются заново (scripts/gen_secrets.py), есть smoke-процедура с PASS/FAIL (docs/operations/REPLICATION.md §4) и анти-регресс tests/test_no_host_hardcodes.py. Технически платформа разворачивается на чужом хосте без правки кода.

Операционно — нет: знания размазаны по 4+ документам, каждый из которых писался для оператора НАШЕГО хоста, а не для заказчика на чистой инфре:

Документ Что покрывает Чего не хватает для Lite
docs/operations/REPLICATION.md карта env, секреты, smoke явно НЕ описывает установку/подключение Plane/Gitea (анти-скоуп Р-5 ORCH-101)
docs/operations/ONBOARDING.md онбординг проекта (статусы/лейблы/репо/kit/реестр) предполагает уже работающий оркестратор и наш хост
docs/operations/SETUP_WEBHOOKS.md формат вебхуков Plane/Gitea примеры с боевыми URL (mva154), не generic
docs/operations/INFRA.md топология/рестарты нашего хоста не инструкция «с нуля»

Заказчик сегодня не может развернуть Lite без доп-вопросов — отсутствует единый сквозной маршрут «голый хост → работающий конвейер». Главный продукт ORCH-102 — ИНСТРУКЦИЯ docs/deployment/LITE_SETUP.md (golden source в репо), закрывающая этот разрыв.

1.3. Установленные факты (проверено по репо, не изобретать)

  • ORCH-101 смержен (git log: merge #122) — ветка задачи уже содержит фундамент: env-карта §2 REPLICATION.md, gen_secrets.py, .env.example = канон 100% ключей старта (включая блок WATCHDOG_*), smoke §4, тесты test_no_host_hardcodes/test_infra_parametrization/test_secrets_gen/test_replication_smoke.
  • docker-compose.yml УЖЕ является compose-подмножеством Lite: ровно три сервиса — orchestrator, orchestrator-watchdog, orchestrator-staging (последний строго за profiles: [staging]); сервисов Plane/Gitea в compose НЕТ. Дефолтный docker compose up -d поднимает ровно орк+watchdog. AC-2 достижим без форка compose — нужны фиксация в доке и анти-дрейф тест.
  • Plane CE не отдаёт webhook через публичный API — на нашем хосте webhook создан напрямую в PostgreSQL / через UI (SETUP_WEBHOOKS.md). Инструкция Lite обязана дать заказчику оба пути (UI и DB) для ЕГО инсталляции Plane.
  • Точная модель статусов: 22 канонических имени с группами (источник — plane_sync._PLANE_NAME_TO_KEY; таблица — ONBOARDING.md §1; создаёт scripts/onboard_project.py apply). Код-критичные fail-closed: Confirm Deploy, STOP (группа cancelled); в терминальных группах — только Done/Cancelled/STOP.
  • Branch protection на main нормативно ЗАПРЕЩЁН (ORCH-009 ADR D10: required-approvals / status-checks ломают PR-merge API merge-актора → ложные HOLD). Pre-receive хуков в платформе НЕТ — защита держится конвенцией + скоупом токенов. Формулировка бизнес-запроса «pre-receive хуки» конфликтует с этим нормативом → вопрос архитектору (ТЗ §3.8 А-1); рекомендация: раздел Gitea фиксирует канон (репо+токен+webhook+«protection НЕ включать»).
  • Гэп watchdog-конфига: compose читает .env.watchdog (required: false), но .env.watchdog.example в репо НЕТ (есть только .env.example/.env.staging.example); ключи WATCHDOG_* задокументированы внутри .env.example. Инструкции нужен однозначный рецепт настройки watchdog-бота (форма — вопрос архитектору А-4).
  • Платформенные конвенции тиража (REPLICATION.md §1, нормативно): репо платформы обязан называться orchestrator (SELF_HOSTING_REPO); имена сервисов/профиля — константы; контейнерный layout (/app/data, /repos, /opt/claude-code) не параметризуется.
  • Прецедент приёмки smoke: ORCH-101 AC-3 — воспроизводимость подтверждается прогоном на текущей инфре (staging-песочница ORCH_STAGING_PORT=8501 + sandbox-проект), без нового железа.

1.4. Решения Владельца (10.06) — приняты как требования

# Решение
D-1 Тиражей ДВА типа: A (Lite) и B (Bundled); ORCH-102 реализует ТОЛЬКО A.
D-2 Оба типа stateless: наши задачи/данные/секреты не переносятся; на целевой инфре чистый старт.
D-3 Lite = перенос ТОЛЬКО орк+watchdog; окружение (Plane/Gitea/LLM/Telegram) заказчик донастраивает по инструкции.
D-4 Главный продукт задачи = инструкция docs/deployment/LITE_SETUP.md — golden source в репо.
D-5 Зависимость: ORCH-102 ← 10-common (ORCH-101) — выполнена (смержен), блокеров нет.

2. Объём (scope)

2.1. В объёме

  • Инструкция docs/deployment/LITE_SETUP.md — полная пошаговая (каждый шаг = команда + проверка), покрывающая сквозной маршрут: предусловия хоста (зависимости, uid/gid) → перенос кода орк+watchdog → конфиг (.env с нуля + секреты) → подключение Plane (workspace/проект, точная модель статусов, API-токен, webhook+HMAC) → подключение Gitea (репо, токен, webhook, норматив защиты main) → LLM-доступ (claude CLI / ключи моделей) → Telegram (бот трекера + watchdog-бот + chat-id) → запуск compose-подмножества → регистрация проекта (ORCH_PROJECTS_JSON, src/projects.py) → health-чек → smoke (из 10-common) → траблшутинг.
  • Фиксация compose-подмножества (AC-2): документировано и защищено структурным тестом, что дефолтный запуск = ровно орк+watchdog, без Plane/Gitea-контейнеров.
  • Stateless-нормативы в инструкции (AC-3): чистая БД, новые секреты, явный запрет переноса наших задач/данных/секретов.
  • Smoke на чистом окружении (AC-4): воспроизводимая процедура/чек-лист (переиспользование REPLICATION.md §4) + зафиксированный приёмочный прогон.
  • Анти-дрейф тесты структуры/полноты инструкции и compose-подмножества; полный pytest зелёный; CHANGELOG.md; перекрёстные ссылки (REPLICATION.md §1 границы, README — по объёму).

2.2. Вне объёма (явно, не делать)

  • Тип B (Bundled) — весь стек одним комплектом: отдельная задача эпика.
  • Установка самих Plane / Gitea / Telegram / LLM-аккаунтов — заказчик ставит по официальной документации вендоров; ORCH-102 покрывает только ПОДКЛЮЧЕНИЕ к оркестратору (анти-скоуп-крип, зеркало Р-5 ORCH-101).
  • Изменения рантайма/конвейера: ожидаемый объём — docs+tests; src/** не трогается; STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict ключи / схема БД — байт-в-байт.
  • Перенос данных: ни БД, ни задач, ни worktree, ни секретов (D-2).
  • Новая автоматизация поверх существующих CLI (gen_secrets.py, onboard_project.py): новые скрипты не вводятся без решения архитектора.
  • Коммерческая механика раздачи (доступ заказчика к коду, лицензии, поддержка) — операторский/владельческий уровень; в инструкции — параметризованный источник кода.
  • Введение pre-receive хуков / branch protection — запрещено действующим нормативом ORCH-009 ADR D10 (см. §1.3); пересмотр только явным ADR архитектора.

3. Заинтересованные стороны

  • Владелец (Слава) — раздаёт платформу заказчикам на тест; принимает инструкцию как продукт.
  • Заказчик-тестер (новый оператор) — целевой читатель LITE_SETUP.md: разворачивает Lite на своей инфре без доп-вопросов; технически грамотен (linux/docker), платформу видит впервые.
  • Оператор текущего прода — прогоняет приёмочный smoke на staging-песочнице; его прод (общий для enduro-trails) не должен быть затронут.
  • Будущая задача 10b (Bundled) — переиспользует разделы Lite-инструкции; границы фиксируются в REPLICATION.md §1.

4. Бизнес-требования (BR)

ID Требование Связь
BR-1 Существует docs/deployment/LITE_SETUP.mdполная пошаговая инструкция Lite-тиража: по ней человек, не видевший платформу, разворачивает орк+watchdog и донастраивает окружение без доп-вопросов; каждый шаг несёт команду и проверку (ожидаемый результат / PASS-FAIL). AC-1, FR-1, D-4
BR-2 Инструкция покрывает ВСЕ системы донастройки: Plane (workspace/проект, точная модель статусов — 22 имени с группами, API-токен, webhook+HMAC с учётом ограничения Plane CE), Gitea (репо, токен с нужными scope, per-repo webhook, норматив «branch protection main НЕ включать»), LLM (claude CLI: дистрибутив/node/аутентификация/ORCH_CLAUDE_BIN/модели), Telegram (бот трекера + ОТДЕЛЬНЫЙ watchdog-бот + получение chat-id), регистрацию проекта (ORCH_PROJECTS_JSON через onboard_project.py), health-чек, smoke. AC-1, FR-4
BR-3 Разворачивается compose-подмножество только орк+watchdog: дефолтный docker compose up -d поднимает ровно orchestrator+orchestrator-watchdog; Plane/Gitea-контейнеров в compose нет; staging-сервис — строго за профилем. Свойство зафиксировано в доке и защищено структурным тестом. AC-2, FR-2
BR-4 Stateless: инструкция предписывает чистую БД (создаётся пустой при первом старте), выпуск НОВОГО комплекта секретов (gen_secrets.py + чек-лист внешних токенов), и нигде не предписывает перенос наших задач/данных/секретов; в самой доке — только плейсхолдеры, ни одного реального секрета/боевого токена. AC-3, FR-3
BR-5 Smoke на чистом окружении существует как воспроизводимая процедура/чек-лист с PASS/FAIL (переиспользование REPLICATION.md §4, без форка); приёмочный прогон выполнен на чистом контуре (минимум — staging-песочница + sandbox-проект, прецедент ORCH-101 AC-3) и зафиксирован в артефактах задачи. AC-4, FR-5
BR-6 Канон не форкается: канонические таблицы (модель статусов, карта env, формат вебхуков) инструкция даёт ссылкой на golden source (ONBOARDING.md/REPLICATION.md/SETUP_WEBHOOKS.md) либо с анти-дрейф тестом при неизбежном дублировании; копируемые команды инструкции — generic (плейсхолдеры вместо боевых URL/путей). AC-1/AC-6, FR-4, NFR-4
BR-7 Полный pytest tests/ -q зелёный; запись в CHANGELOG.md; перекрёстные доки обновлены (REPLICATION.md §1 «границы» — строка Type A → ссылка/статус; README/CLAUDE.md — по фактическому объёму, правило агентов №2/№6). AC-5, FR-6/FR-7
BR-8 Полнота/структура инструкции защищена структурным pytest (анти-дрейф, по образцу tests/test_replication_smoke.py): исчезновение обязательного раздела/кирпича/env-ключа из дока или дрейф compose-подмножества ломает CI. AC-6, FR-6

5. Нефункциональные требования (NFR)

ID Требование
NFR-1 Self-hosting безопасность: задача docs+tests; прод-контейнер orchestrator не перезапускается; прод-выкат — только штатным конвейером (staging 8501 → ручной Confirm Deploy).
NFR-2 Нулевая регрессия: поведение рантайма не меняется (ожидаемо ноль изменений src/**); STAGE_TRANSITIONS/QG_CHECKS/check_*/machine-verdict/схема БД — байт-в-байт; существующие тесты (включая test_no_host_hardcodes, test_replication_smoke) остаются зелёными.
NFR-3 Секрет-гигиена: ни в инструкции, ни в тестах — ни одного реального секрета/токена/боевого webhook-секрета; только плейсхолдеры и ссылки на gen_secrets.py; security-гейт (ORCH-022) зелёный.
NFR-4 Единый источник истины: инструкция — маршрутизатор поверх канонов, не их копия; неизбежные дубли защищены анти-дрейф тестом (сверка с кодом/каноном импортом, не строкой).
NFR-5 Поддерживаемость golden source: LITE_SETUP.md версионируется в репо и поддерживается агентами при каждой доработке, меняющей шаги тиража (правило агентов №2 — дока в том же PR).
NFR-6 Копируемость команд: каждый код-блок инструкции выполняется на чистом хосте дословно после подстановки явно перечисленных плейсхолдеров (<...>); никаких неявных «подразумевается, что…».

6. Допущения и ограничения

  • Поддерживаемый контур (фиксируется в предусловиях инструкции): Linux x86_64, Docker Engine + Compose v2, git, python3; пользователь с правами docker; диск/память по минимальным требованиям (значения уточнит архитектор/инструкция). Иные ОС/архитектуры — вне гарантии Lite.
  • Заказчик сам ставит Plane CE, Gitea, заводит Telegram-ботов и LLM-доступ (Claude CLI-аутентификация / ключи) — по официальным докам вендоров; наша инструкция начинается с «системы установлены и доступны по сети».
  • Имя репо платформы — orchestrator (норматив REPLICATION.md §1 / SELF_HOSTING_REPO); инструкция не предлагает его менять.
  • Источник кода для заказчика (clone-URL/архив) — решение Владельца; в инструкции — параметризованный шаг (А-6 в ТЗ).
  • «Без доп-вопросов» (AC-1) операционализируется проверяемо: (а) каждый шаг несёт команду+проверку, (б) приёмочный smoke-прогон по инструкции на чистом контуре зафиксирован, (в) траблшутинг покрывает типовые отказы первичной настройки.
  • Терминология бизнес-запроса «pre-receive хуки» трактуется по факту платформы (§1.3): канонический механизм защиты — конвенция + скоуп токенов + запрет branch protection; окончательная формулировка раздела Gitea — за архитектором (А-1).

7. Критерии успеха (резюме; детали — 03-acceptance-criteria.md)

  • AC-1: docs/deployment/LITE_SETUP.md — полная пошаговая, человек разворачивает без доп-вопросов (каждый шаг — команда/проверка).
  • AC-2: compose-подмножество только орк+watchdog (без Plane/Gitea-контейнеров).
  • AC-3: stateless — чистая БД, ни одной нашей задачи/секрета.
  • AC-4: smoke на чистом окружении проходит (минимум — воспроизводимая процедура/чек-лист).
  • AC-5: pytest зелёный; CHANGELOG.
  • AC-6 (детализация): анти-дрейф тесты структуры дока/compose; канон не форкается.
  • AC-7 (детализация): self-hosting безопасность, инварианты конвейера не тронуты.

8. Риски (детали — 10-tech-risks.md, заполняет архитектор)

  • R-1 — Дрейф инструкции: платформа развивается, шаги устаревают → структурные тесты (BR-8)
    • правило golden source (NFR-5).
  • R-2 — Форк канона: скопированная таблица статусов/env разъедется с кодом → ссылки/анти-дрейф (BR-6, NFR-4).
  • R-3 — Непроверяемость «без доп-вопросов» → операционализация через §6 (команда+проверка, smoke-прогон, траблшутинг).
  • R-4 — Гетерогенность хостов заказчиков (rootless docker, иной uid, нет node) → явный поддерживаемый контур + предусловия с проверками (getent group docker, владение ORCH_HOST_REPOS_DIR).
  • R-5 — Конфликт «pre-receive» с нормативом ADR D10 → вопрос А-1 архитектору; до решения — канон платформы.
  • R-6 — Утечка секрета через примеры дока → NFR-3, security-гейт, тест на отсутствие секретоподобных значений.