23 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 |
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-гейт, тест на отсутствие секретоподобных значений.