Files
enduro-trails/docs/work-items/ET-015/01-brd.md
claude-bot 68076fca1a
Some checks failed
CI / lint (push) Failing after 4s
CI / test (push) Failing after 5s
CI / build (push) Has been skipped
analyst(ET): auto-commit from analyst run_id=56
2026-06-02 19:03:41 +00:00

12 KiB
Raw Blame History

BRD — ET-015 / ORCH-6: Multi-repo support для оркестратора

Work Item ID: ET-015 Plane title: [ORCH-6] Multi-repo: оркестратор работает по нескольким проектам Целевой репозиторий изменений: orchestrator (а не enduro-trails) Где трекается work item: enduro-trails/docs/work-items/ET-015/ (организационная задача)

1. Контекст и проблема

Multi-Agent Orchestrator (FastAPI-сервис на порту 8500) сегодня жёстко завязан на один проект — enduro-trails. Это видно по нескольким местам:

  1. ORCH_DEFAULT_REPO=enduro-trails — единственный fallback, который используется почти везде в webhooks/plane.py, webhooks/gitea.py, agents/launcher.py.
  2. Префикс work item ID жёстко ET- (get_next_work_item_id в db.py, строка ~9399): любой новый таск, откуда бы он ни пришёл, получает ID вида ET-NNN.
  3. Plane-настройки одиночные: ORCH_PLANE_WORKSPACE_SLUG, ORCH_PLANE_PROJECT_ID, словарь PLANE_STATES со state-id'ами конкретного проекта enduro-trails. Webhooks от другого Plane-проекта будут обработаны, но patch'и состояний и комментарии полетят в чужой проект.
  4. Документация (docs/phases/PH-1..PH-9, фазы roadmap), agent-prompts (.openclaw/agents/*.md) и Quality Gates конвенции живут в enduro-trails и неявно считаются «универсальными».

В результате невозможно подключить к оркестратору ни сам orchestrator (мета-разработка), ни любой будущий проект (например enduro-tiles-data, enduro-mobile).

2. Бизнес-цель

Дать оркестратору возможность обслуживать N проектов одновременно, не теряя текущей функциональности по enduro-trails и без миграции исторических данных.

Это нужно, чтобы:

  • запускать пайплайн на самом репо orchestrator (dogfooding — улучшения оркестратора проходят через тот же пайплайн);
  • начать вести новые проекты той же командой и тем же инструментарием (тайлы, мобильное приложение, бэкенды для соседних идей);
  • иметь единую точку наблюдения за разработкой нескольких репо (один /status, один Telegram-канал, одни логи).

3. Целевые пользователи и сценарии

Роль Сценарий Ожидание
Owner (homenet542@gmail.com) Подключить к оркестратору новый проект foo За один шаг (правка конфига + перезапуск) проект становится известен оркестратору. Никаких code-change'ей в src/.
Stakeholder в Plane Создаёт work item в проекте Foo (Plane workspace) Получает branch feature/FOO-NNN-slug в Gitea-репо foo, артефакты в docs/work-items/FOO-NNN/, анализ запускается автоматически.
Developer (claude-bot) Анализирует work item, который пришёл из проекта Foo Видит корректный work item ID (FOO-007), корректный repo (foo), корректную ветку (feature/FOO-007-...). Worktree создаётся под нужным репо.
Owner Смотрит /status оркестратора Видит все активные задачи across all repos, с указанием repo для каждой.
Owner Хочет временно поставить проект на паузу Может выключить конкретный проект в конфиге, не трогая остальные.

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

BR-1. Реестр проектов

Оркестратор должен знать список обслуживаемых проектов. Источник истины конфигурируется (env / file / иной способ — на усмотрение архитектора). Для каждого проекта задаются как минимум:

  • имя Gitea-репо (repo),
  • префикс work item ID (ET, ORCH, FOO, ...),
  • идентификаторы Plane (workspace_slug, project_id),
  • маппинг состояний Plane (backlog, todo, in_progress, needs_input, in_review, blocked, done, cancelled) — каждый Plane-проект имеет собственные UUID состояний.

BR-2. Маршрутизация Plane-вебхуков по проектам

При получении вебхука от Plane оркестратор обязан определить, какому проекту из реестра принадлежит событие (по project_id в payload), и работать с настройками этого проекта (Plane state IDs, workspace, gitea-репо).

BR-3. Маршрутизация Gitea-вебхуков по репозиториям

При получении push / PR / status оркестратор должен использовать repository.name из payload как ключ для поиска проекта в реестре вместо settings.default_repo.

BR-4. Префикс work item ID — per-project

Генерация следующего ID должна продолжать существующую нумерацию в пределах своего префикса: для enduro-trailsET-016 после ET-015; для orchestratorORCH-001 для первого таска, ORCH-002 далее; ID одного проекта не пересекают и не сдвигают ID другого.

BR-5. Изоляция worktree per (repo, branch)

Текущая схема /repos/_wt/<repo>/<safe-branch> уже репо-aware, но оркестратор должен предполагать наличие main-clone'а для каждого репо в /repos/<repo>. Если main-clone отсутствует — внятная ошибка в логах + Telegram (а не падение).

BR-6. Agent prompts и фазы — per-repo

Agent-промпты (.openclaw/agents/<agent>.md), CLAUDE.md, docs/phases/ у каждого проекта могут отличаться. Оркестратор не должен «протаскивать» артефакты enduro-trails в другие репозитории.

BR-7. Обратная совместимость

Существующий проект enduro-trails после миграции продолжает работать без потери истории:

  • активные задачи в tasks таблице не ломаются;
  • ID ET-015, ET-016, … продолжают выдаваться;
  • комментарии и состояния в Plane продолжают летать в текущий workspace/project.

BR-8. Наблюдаемость

/status (и любые админ-эндпоинты) выводит repo для каждой активной задачи. Telegram-уведомления и логи также включают repo, чтобы их можно было разделить per-project.

BR-9. Минимально необходимый рантайм-конфиг

Подключение нового проекта не требует изменения кода src/. Только конфиг + наличие main-clone'а репозитория на хосте + перезапуск контейнера. Webhook secret-ы (Plane / Gitea) — также per-project.

BR-10. Безопасность

Каждый Plane-проект может иметь собственный webhook secret; оркестратор должен проверять HMAC с правильным секретом для конкретного проекта, иначе вебхук отбрасывается с 401.

5. Out of scope для этой задачи

  • Параллельная обработка нескольких задач (S-4 уже сделал worktree per branch, но in-process очередь задач — отдельный F-2b).
  • Веб-UI для управления проектами.
  • Автоматическое подтягивание main-clone'а нового репо (git clone выполняется руками или другим инструментом).
  • Изменение pipeline-stage машины (stages.py).
  • Изменение модели данных Plane (state-id'ы определяются в Plane, оркестратор только подхватывает).

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

  • Все обслуживаемые репозитории живут в одном Gitea-инстансе (один ORCH_GITEA_URL, один ORCH_GITEA_TOKEN, один owner=admin). Multi-Gitea — не в скоупе.
  • Все Plane-проекты — в одном Plane-инстансе (ORCH_PLANE_API_URL), но могут быть в разных workspace.
  • Claude CLI бинарник один и тот же (/opt/claude-code/bin/claude.exe).
  • Hooks деплоя per-repo не обязаны существовать на этом этапе: если у репо нет деплой-стадии — deploy помечается done без смоук-теста (либо проект явно объявляет, что у него нет deploy).

7. Метрики успеха

  1. Создание work item'а в Plane-проекте Orchestrator приводит к появлению ветки feature/ORCH-NNN-… в Gitea-репо orchestrator и запуску analyst-агента в worktree /repos/_wt/orchestrator/<branch>.
  2. ID нового таска в orchestrator имеет префикс ORCH-, а не ET-.
  3. Создание work item в enduro-trails продолжает работать: ID ET-016, ветка feature/ET-016-..., всё как раньше.
  4. /status возвращает поле repo для каждой задачи.
  5. Telegram-уведомление содержит repo в префиксе сообщения.
  6. Регрессии не наблюдаются на 2 последовательных ET-NNN задачах после раскатки.

8. Зависимости и риски (на уровне бизнеса)

  • Plane state IDs другого проекта надо получить вручную (через Plane UI или API) — этим занимается Owner перед подключением.
  • Webhook secret per-project потребует пересоздать webhook'и в каждом Plane-проекте и каждом Gitea-репо.
  • Schema tasks уже хранит repo — миграции данных не требуется.

9. Связанные документы

  • 02-trz.md — функциональные/нефункциональные требования (этот пакет).
  • 03-acceptance-criteria.md — критерии приёмки.
  • 04-test-plan.yaml — план тестов.
  • Architecture phase: создаст ADR по способу хранения реестра проектов и стратегии маппинга Plane state IDs.