G1: remove the dead `model:` line from all 6 .openclaw/agents/*.md prompts — launcher never read it; config (agent_model_*) is the single source of truth. G2: add is_valid_model helper (format check ^claude-…$) applied inside resolve_agent_model's resolution cascade and at the inline --fallback-model read in _spawn. An invalid name is logged and skipped to the next valid level (in the limit: no --model flag), never passed to the CLI, never raises. Format check chosen over an allowlist for forward-compatibility (ADR-001). G3 (routing) and G4 (fallback) intentionally NOT enabled — all agents stay on claude-opus-4-8; agent_fallback_model stays "". Docs (golden source) updated in the same change: README model/effort table + validation, CLAUDE.md, .env.example (ORCH_AGENT_MODEL_*/EFFORT_*/FALLBACK_MODEL), CHANGELOG. Tests: test_agent_frontmatter_no_model.py (G1), extended test_resolve_agent_model.py (G2 never-break). Refs: ORCH-074 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
93 lines
9.9 KiB
Markdown
93 lines
9.9 KiB
Markdown
# CLAUDE.md — паспорт проекта orchestrator
|
||
|
||
## TL;DR
|
||
Мульти-агентный оркестратор разработки. FastAPI-сервис: принимает webhooks от Plane и Gitea, ведёт задачи по конвейеру стадий через Quality Gates, запускает Claude CLI агентов (analyst → architect → developer → reviewer → tester → deployer) на каждой стадии. **Оркестратор дорабатывает в том числе сам себя (self-hosting).**
|
||
|
||
## Стек
|
||
- Backend: FastAPI + uvicorn (Python 3.12)
|
||
- БД: SQLite (`src/db.py`)
|
||
- Агенты: Claude CLI (`ORCH_CLAUDE_BIN`), по одному промпту на роль в `.openclaw/agents/`. **ORCH-74:** модель/эффорт агента берутся ТОЛЬКО из config (`resolve_agent_model`/`resolve_agent_effort`, ORCH-41) — frontmatter `model:` удалён как мёртвый, frontmatter описательный; имя модели валидируется форматом `^claude-…$` перед `--model` (never-break).
|
||
- Очередь задач: собственная (SQLite `jobs`, `src/queue_worker.py`, ORCH-1). **ORCH-026:** `claim_next_job` гейтит задачи с незавершёнными зависимостями (`job_deps`, `NOT EXISTS`) без занятия слота `max_concurrency`; декларации/детект циклов — leaf `src/task_deps.py` (kill-switch `ORCH_TASK_DEPS_ENABLED`). Сериализация мержа одного репо — безусловный pre-merge rebase под merge-lease (`ORCH_PREMERGE_REBASE_ALWAYS`).
|
||
- Контейнеризация: Docker + Compose
|
||
- CI/CD: Gitea Actions (`.gitea/workflows/`)
|
||
- Деплой: docker compose на mva154
|
||
|
||
## Команды
|
||
- `uvicorn src.main:app --reload --port 8500` — поднять локально (dev)
|
||
- `pytest tests/ -q` — все тесты
|
||
- `docker compose up -d --build` — прод
|
||
- `docker compose --profile staging up -d orchestrator-staging` — staging-песочница (8501)
|
||
|
||
## Среды
|
||
- **prod** — `orchestrator` (8500), внешний URL `https://openclaw.mva154.duckdns.org/orchestrator/`
|
||
- **staging** — `orchestrator-staging` (8501), изолированная БД (`./data/staging`), только sandbox-проект
|
||
|
||
## Структура
|
||
- `src/` — приложение (main, config, db, stages, stage_engine, queue_worker, projects, usage)
|
||
- `src/agents/launcher.py` — запуск Claude CLI агентов
|
||
- `src/qg/checks.py` — Quality Gate проверки
|
||
- `src/webhooks/` — приём вебхуков Plane/Gitea
|
||
- `tests/` — pytest
|
||
- `docs/` — документация, ADR, work-items, operations
|
||
- `scripts/` — утилиты (staging_check.py, orchestrator-deploy-hook.sh)
|
||
|
||
## Конвейер (кратко; детали — docs/architecture/README.md)
|
||
```
|
||
created → analysis → architecture → development → review → testing → deploy-staging → deploy → done
|
||
↑ │
|
||
└──── REQUEST_CHANGES ──────┘ (откат на development, max 3)
|
||
```
|
||
|
||
## Статусная модель Plane (ORCH-066) — индикация ≠ управление
|
||
Статусы Plane — это **слой B (индикация)**, отдельный от **слоя A (машина стадий)** `src/stages.py::STAGE_TRANSITIONS`. Plane показывает наблюдателю осмысленную картину (`Backlog → Todo → Analysis → Architecture → Development → Code-Review → Testing → Awaiting Deploy → Deploying → Monitoring after Deploy → Done` + человеческие гейты `In Review/Approved`, `Confirm Deploy`), но НИКОГДА не управляет конвейером. Маппинг и сеттеры — `src/plane_sync.py` (6 новых ключей: `to_analyse/analysis/code_review/awaiting_deploy/deploying/monitoring`), с project-relative alias-fallback: на частично сконфигурированном проекте новый ключ деградирует на базовый UUID ТОГО ЖЕ проекта (нулевая регрессия для enduro-trails). Детали — `docs/architecture/README.md`.
|
||
|
||
## Нотификации / Telegram live-tracker (ORCH-042/066/067)
|
||
Каждая задача = **одна карточка** в Telegram (`src/notifications.py`). Поведение карточки:
|
||
- **Дефолт `tracker_mode` — `bump`** (ORCH-067; `edit` доступен через `ORCH_TRACKER_MODE=edit`).
|
||
`bump` на каждом обновлении удаляет старую карточку и шлёт свежую вниз чата (тихо), `edit`
|
||
редактирует на месте. Инвариант «одна карточка на задачу» — в обоих режимах.
|
||
- **Статус-строка карточки** (`📍 <status_label>`) показывает текущий Plane-статус по модели
|
||
ORCH-066 (`plane_status_label`). Оффлайн-ядро (`stage → статус`, In Review из brd-clock)
|
||
работает всегда без сети; best-effort live-overlay (kill-switch `tracker_live_status`,
|
||
TTL-кэш, короткий таймаут) лишь дорисовывает ветки, неотличимые offline (Needs Input /
|
||
Blocked / Rejected / Cancelled / Deploying / Monitoring) и **никогда не блокирует конвейер**.
|
||
- **Кликабельный номер задачи** (`plane_issue_link`) — `ORCH-NNN` в карточке И во всех
|
||
уведомлениях (`notify_*`, alert'ы стадий) рендерится как `<a href=…>` на issue в Plane;
|
||
fail-safe → просто `html.escape(номер)`, если ссылку построить нельзя. Никогда не падает.
|
||
- Транспорт (`send_telegram`/`edit_telegram`/`delete_telegram`), `disable_notification`
|
||
(карточка тихая, пингуют только alert-хелперы), схема БД — не трогаются.
|
||
|
||
## Конвенции
|
||
- Conventional Commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
|
||
- Ветки: `feature/ORCH-NNN-slug`, `fix/ORCH-NNN-slug`
|
||
- ADR per work-item: `docs/work-items/<plane-id>/06-adr/ADR-NNN-slug.md`
|
||
- Global ADR (сквозные решения): `docs/architecture/adr/adr-NNNN-slug.md`
|
||
- Work items: `docs/work-items/<plane-id>/`
|
||
- Машинные вердикты Quality Gate — строго YAML-frontmatter (`verdict:`, `deploy_status:`, `staging_status:`, `security_status:`), никогда проза
|
||
|
||
## Артефакты задачи (`docs/work-items/<plane-id>/`)
|
||
`00-business-request.md`, `01-brd.md`, `02-trz.md`, `03-acceptance-criteria.md`, `04-test-plan.yaml`, `06-adr/ADR-NNN-slug.md`, `07-infra-requirements.md`, `08-data-requirements.md`, `10-tech-risks.md`, `12-review.md`, `13-test-report.md`, `14-deploy-log.md`, `15-staging-log.md`, `16-post-deploy-log.md` (post-deploy наблюдение, ORCH-021), `17-security-report.md` (security-гейт: `security_status:`/secrets/deps, ORCH-022).
|
||
|
||
## Правила для агентов
|
||
1. Перед любым действием прочесть этот файл и `docs/architecture/README.md`.
|
||
2. **Документация = golden source наравне с кодом.** Изменил функционал → обнови доку В ТОМ ЖЕ PR. Архитектурное решение → заведи ADR. Обнови `CHANGELOG.md`.
|
||
3. Никогда не править артефакты других этапов.
|
||
4. Никогда не комментировать ТЗ задним числом — если ТЗ не годится, возвращай в Анализ.
|
||
5. Никогда не закрывать задачу самостоятельно — это делает CI / финальная стадия.
|
||
6. **Reviewer проверяет: обновлена ли документация. Нет → REQUEST_CHANGES.**
|
||
7. Не использовать `--no-verify` без явного одобрения Owner.
|
||
8. Секреты — только в `.env`/`.env.staging` на хосте, в гит НЕ коммитятся (канон — `.env.example`).
|
||
|
||
## ⚠️ Self-hosting — оркестратор правит САМ СЕБЯ
|
||
Задачи проекта ORCH меняют инструмент, который СЕЙЧАС работает в продакшене и обслуживает ДРУГИЕ проекты (enduro-trails) из ОДНОГО инстанса с ОБЩЕЙ БД и общей очередью.
|
||
- **НЕ перезапускать / не ронять прод-контейнер** `orchestrator` в рамках задачи — встанет конвейер всех проектов.
|
||
- Любой деплой/рестарт self = групповой риск. Детали и топология — `docs/operations/INFRA.md`.
|
||
- Стадия `deploy-staging` (порт 8501) — обязательная страховка перед прод-деплоем орка.
|
||
- Прод-деплой орка запускается ТОЛЬКО переводом задачи на стадии `deploy` в выделенный
|
||
Plane-статус **«Confirm Deploy»** (ORCH-059). Статус `Approved` — человеческий гейт
|
||
конвейера и прод-деплой НЕ запускает (на `deploy` — no-op). Это разделяет «одобрить
|
||
артефакт» и «выкатить в прод», чтобы привычный approve не ронял прод случайным кликом.
|
||
|
||
---
|
||
*Паспорт проекта orchestrator. Поддерживается агентами при каждой доработке. Изолирован: описывает только этот проект (канон per-repo, см. ORCH-9).*
|