From 11551572e9ff7c595a568c59445d18518012f6ae Mon Sep 17 00:00:00 2001 From: claude-bot Date: Wed, 10 Jun 2026 14:47:54 +0300 Subject: [PATCH] analyst(ET): auto-commit from analyst run_id=584 --- docs/work-items/ORCH-009/01-brd.md | 176 ++++++++++++++ docs/work-items/ORCH-009/02-trz.md | 227 ++++++++++++++++++ .../ORCH-009/03-acceptance-criteria.md | 146 +++++++++++ docs/work-items/ORCH-009/04-test-plan.yaml | 164 +++++++++++++ 4 files changed, 713 insertions(+) create mode 100644 docs/work-items/ORCH-009/01-brd.md create mode 100644 docs/work-items/ORCH-009/02-trz.md create mode 100644 docs/work-items/ORCH-009/03-acceptance-criteria.md create mode 100644 docs/work-items/ORCH-009/04-test-plan.yaml diff --git a/docs/work-items/ORCH-009/01-brd.md b/docs/work-items/ORCH-009/01-brd.md new file mode 100644 index 0000000..34faa38 --- /dev/null +++ b/docs/work-items/ORCH-009/01-brd.md @@ -0,0 +1,176 @@ +--- +work_item: ORCH-009 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-10 +model_used: claude-opus-4-8 +--- + +# 01 — BRD: ORCH-009 — Онбординг проектов в оркестратор (turnkey: Plane + репо + агенты + инфра) + +Work Item: **ORCH-009** · Repo: **orchestrator** (self-hosting) · Стадия: analysis +Заказчик: Слава · Домен эпика: 📈 **D5 Масштаб (D5.2)** — `docs/epics/self-evolution.md` + +> ⚠️ **Актуализация Владельца 10.06 принята как приоритетная над исходной постановкой 05.06.** +> Эталон онбординга = **сам репозиторий orchestrator** (каноны ORCH-52b/c/d/e уже кодифицированы), +> НЕ enduro-trails (устаревший пример). «Дыра: у orchestrator только deployer.md» — уже закрыта +> (в `.openclaw/agents/` полный набор 6 промптов). Скоуп — **способность** разворачивать новый +> проект по образцу орка одним проходом; онбординг конкретного нового заказчика — исполнение этой +> способности, вне данной задачи. + +--- + +## 1. Бизнес-контекст и проблема + +### 1.1. Цель +При подключении **нового** проекта к оркестратору одним проходом разворачивается всё, что нужно +мульти-агентам для автономной работы: Plane-проект (статусы/лейблы под машинные контракты), +Gitea-репо (+webhook), полный набор промптов агентов, структура документации по единым канонам, +инфра-описание (INFRA.md), регистрация в реестре проектов. Агенты нового проекта **обязаны** знать, +где лежит документация, использовать её и актуализировать. + +### 1.2. Проблема сегодня +Онбординг проекта — ручная археология: шаги размазаны по докам (`SETUP_WEBHOOKS.md`, +`INFRA.md`), памяти Стрима/Славы и инцидентам (прецедент 2026-06-02: webhook всего workspace + +захардкоженный `default_repo` → задачи чужого проекта падали в enduro-trails; закрыто реестром +ORCH-6). Любой пропущенный шаг даёт **тихую деградацию**: без промптов в репо конвейер проекта не +работает вовсе; без точных имён статусов Plane ветки `Confirm Deploy`/`STOP` молча не активируются +(fail-closed); без лейблов авто-режимы и багфикс-трек молча выключены (fail-safe). Турникей-проход +обязан закрывать все слои сразу и проверяемо. + +### 1.3. Установленные факты (проверено по коду, не изобретать) + +| # | Факт | Где проверено | +|---|------|---------------| +| Ф-1 | Промпты агентов — **per-repo**: launcher резолвит `system_prompt: .openclaw/agents/.md` относительно worktree репо задачи. Нет промптов в новом репо → конвейер для него не работает. | `src/agents/launcher.py` (реестр AGENTS, 6 ролей) | +| Ф-2 | Агент видит **только** worktree своего репо → каноны (шаблоны/стандарты) обязаны быть **скопированы** в новый репо; «ссылка на репо орка» агенту недоступна. | модель worktree `src/git_worktree.py`, launcher | +| Ф-3 | Реестр проектов строится **при импорте** из `ORCH_PROJECTS_JSON` (или built-in default): ключи `plane_project_id`/`repo`/`work_item_prefix`/`name` + опц. `agent_models`/`agent_efforts`. Регистрация нового проекта = правка `.env` на хосте + **управляемый рестарт** (операторский шаг). | `src/projects.py` (`_parse_projects_json`, `_load_projects`) | +| Ф-4 | Статусы Plane резолвятся по **точным именам** (22 ключа `_PLANE_NAME_TO_KEY`); `Confirm Deploy` (ORCH-059) и `STOP` (группа `cancelled`, ORCH-090) — **fail-closed** (нет статуса на доске → ветка не активируется); TTL-self-heal 300с (ORCH-068) — статус, добавленный позже, подхватывается без рестарта. | `src/plane_sync.py` (`_PLANE_NAME_TO_KEY`, `get_project_states`) | +| Ф-5 | Лейблы `autoApprove`/`autoDeploy` (ORCH-089) и `Bug` (ORCH-019) — **fail-safe** (нет лейбла → ручной режим / полный цикл); сопоставление по нормализованному имени через Plane API. | `src/labels.py`, `src/bug_fast_track.py`, CLAUDE.md (инфра-предусловия) | +| Ф-6 | Plane-webhook — **workspace-level** (один на все проекты, уже существует; в Plane CE создаётся SQL-ом, внешнего API нет). Gitea-webhook — **per-repo** (создаётся через API; events `push`/`pull_request`/`status`; HMAC-secret). | `docs/operations/SETUP_WEBHOOKS.md`, docstring `src/projects.py` | +| Ф-7 | Каноны (golden source) в репо орка: `docs/_templates/` — 16 скелетов (`00…18`, ORCH-52b); `docs/_standards/` — `HANDOFF_PROTOCOL.md`/`PIPELINE_DOCS.md`/`TRACEABILITY.md` (ORCH-52c/e); `.openclaw/agents/*.md` — 6 промптов канона Anthropic (ORCH-52d/92; `deployer.md` — английский **нормативно**, ADR-001 D2 ORCH-092); ADR-конвенция — `PIPELINE_DOCS.md` §4. | листинг репо, `docs/_standards/PIPELINE_DOCS.md` | +| Ф-8 | Per-repo паспорт `CLAUDE.md` — канон самого ORCH-9 (подпись в паспорте орка: «канон per-repo, см. ORCH-9»); все 6 промптов орка начинаются с «прочти CLAUDE.md». | `CLAUDE.md`, `.openclaw/agents/*.md` | + +### 1.4. Принятая трактовка постановки (расхождения 05.06 ↔ 10.06) +- **Реализация в репо orchestrator** (данный конвейер пишет в этот репо; каноны живут здесь). + Упоминание отдельного репо `onboard2orch` (05.06) — историческое: его пример enduro-trails + объявлен устаревшим; судьба репо — операторское решение вне кода (рекомендация: архивировать/ + оставить указатель, чтобы не плодить второй источник канона). Эскалации не требует: актуализация + 10.06 прямо говорит «каноны кодифицированы в репо орка — их и брать за образец». +- **Раскладка docs/**: слой-1 постановки (05.06) указывал `docs/adr/`; канон орка — + `docs/architecture/adr/` (сквозные) + `docs/work-items//06-adr/` (per-task). Применяется + канон орка (эталон = орк). + +--- + +## 2. Объём (scope) + +### 2.1. В объёме +- **Onboarding-kit**: параметризуемый каркас нового репо — 6 промптов агентов, паспорт + `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, `README.md`, `CHANGELOG.md`, скелет `docs/` + (включая `operations/INFRA.md`), копии `docs/_templates/` + `docs/_standards/`. +- **Onboarding-скрипт** (операторский CLI, вне конвейера): Gitea-репо + per-repo webhook, + Plane-проект + статусы + лейблы (в мере, доступной API), материализация kit (подстановка + параметров) + initial push в свежесозданный репо, генерация валидной записи реестра, режимы + dry-run / apply / verify, идемпотентность. +- **Runbook** `docs/operations/ONBOARDING.md`: полный чеклист, явная маркировка ручных шагов + (env + управляемый рестарт; UI-only действия Plane), верификация, откат. +- **Верификация способности**: автоматические структурные тесты kit (pytest) + документированный + smoke-прогон на песочнице («агент по своему промпту находит доку, использует и актуализирует»). +- **Актуализация обзорных доков** в том же PR (CLAUDE.md, `docs/architecture/README.md`, + CHANGELOG, обобщение `SETUP_WEBHOOKS.md`). + +### 2.2. Вне объёма (явно, не делать) +- Исполнение онбординга конкретного нового заказчика/проекта (включая правку прод-`.env` и + рестарт прода) — операторская эксплуатация способности. +- ORCH-10 — тиражирование платформы на новый хост (IaC-bundle); мультитенантность (D5.6); + параллелизм D5.1. +- Стеки-плагины D4.1 (профили web/mobile/data/ML): kit параметризуется плейсхолдерами, без + механизма профилей. +- Любые изменения `src/**`: машина стадий, QG, launcher, реестр `projects.py` (его контракт уже + достаточен — регистрация через `ORCH_PROJECTS_JSON`), схема БД. +- Создание/миграция Plane workspace-webhook (уже существует, общий на workspace). +- Слой-3 продуктовый мониторинг онбордируемого приложения (фундамент эпика, отдельные задачи). + +--- + +## 3. Заинтересованные стороны +- **Владелец/оператор (Слава, Стрим):** запускает онбординг, выполняет операторские шаги + (env, рестарт, UI-шаги Plane), принимает результат smoke-прогона. +- **Будущие заказчики/проекты:** получают рабочий автономный конвейер «за минуты» (D5.2). +- **Действующие проекты (enduro-trails, orchestrator):** не должны почувствовать онбординг + соседа — общий прод-инстанс, общая БД, общая очередь (self-hosting, ORCH-1). +- **Агенты конвейера:** потребители kit — промпты обязаны вести их к доке проекта. + +--- + +## 4. Бизнес-требования (BR) + +| ID | Требование | Связь | +|----|------------|-------| +| BR-1 | **Turnkey-проход:** один документированный проход (скрипт + runbook) разворачивает все слои: Plane-проект (статусы+лейблы) → Gitea-репо (+webhook) → kit в репо (initial push) → запись реестра → верификация. Список шагов закрыт и воспроизводим. | AC-1, AC-11 | +| BR-2 | **Единый эталон без форка:** kit производится от **живых** канонов репо орка — `docs/_templates/`/`docs/_standards/` копируются в новый репо в момент онбординга «как есть»; параметризация — только в kit-собственных шаблонах (промпты, паспорт, INFRA и пр.). Вторая редактируемая копия канона внутри орка не создаётся. enduro-trails эталоном не является. | AC-5, Ф-2/Ф-7 | +| BR-3 | **Полный набор промптов:** 6 ролей (analyst/architect/developer/reviewer/tester/deployer), параметризуемых под проект/стек, по канону Anthropic 52d: 5 XML-секций в нормативном порядке, запреты «❌ X → ✅ Y», `` у developer/reviewer/tester (ORCH-092), добровольная эмиссия 6-польной frontmatter-схемы 52c, machine-verdict ключи байт-в-байт (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`). Каждый промпт жёстко направляет: читай паспорт/`AGENTS.md`/доку ПЕРЕД работой, пиши артефакты в `docs/work-items//` по канону, обновляй CHANGELOG/доку. | AC-2, AC-4 | +| BR-4 | **Reviewer-gate на доку:** шаблон reviewer-промпта содержит проверку «документация обновлена; нет → REQUEST_CHANGES» (канон держится автоматически, не на честном слове). | AC-3 | +| BR-5 | **Каркас репо полон:** `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `AGENTS.md` (точка входа агентов: карта доков + правила), паспорт `CLAUDE.md`, `docs/` (архитектура, конвейер, продукт-видение, `operations/`, ADR-реестр, `work-items/`, `history/`), копии `_templates/`+`_standards/`. Ссылочная целостность: промпты ссылаются только на реально существующие в каркасе пути. | AC-1, AC-5 | +| BR-6 | **INFRA.md обязателен:** топология (контейнеры/порты прод+staging/сеть/тома/БД), карта env-переменных (дескрипторы в репо, секреты только в `.env` на хосте, `.env.example` — канон), границы доступа, риски общего хоста. Для самого орка существующие self-hosting-предупреждения (общая БД/очередь/groupwide-риск рестарта) сохраняются нетронутыми. | AC-10 | +| BR-7 | **Plane-проект под машинные контракты:** статусы с **точными** каноническими именами (все 22 имени `_PLANE_NAME_TO_KEY`, включая `Confirm Deploy` и `STOP` с группой `cancelled`) + лейблы `autoApprove`/`autoDeploy`/`Bug`. Что недоступно через Plane API — явный ручной пункт runbook с командой проверки. | AC-7, Ф-4/Ф-5 | +| BR-8 | **Регистрация в реестре:** скрипт генерирует запись `ORCH_PROJECTS_JSON`, валидную через фактический парсер `projects._parse_projects_json` (round-trip). Применение env + рестарт — **операторский** шаг, явно описанный в runbook; скрипт прод-контейнер НЕ рестартит. | AC-6, AC-9, Ф-3 | +| BR-9 | **Безопасность исполнения:** dry-run по умолчанию / явный apply; идемпотентный повторный прогон (доделывает недостающее, не дублирует, ничего не удаляет); аддитивность — существующие проекты/репо не модифицируются; push — только initial в свежесозданный пустой репо (никогда в `main` существующих). | AC-8, AC-9 | +| BR-10 | **Верификация способности:** (а) автоматические структурные тесты kit/скрипта (pytest, без сети); (б) verify-режим: registry-валидность, резолв статусов, наличие webhook, полнота kit; (в) документированный smoke на песочнице: новый агент по своему промпту находит доку, использует и актуализирует её. | AC-12, AC-13 | +| BR-11 | **Прозрачность:** каждый шаг скрипта логируется; итоговый отчёт «создано / уже было (пропущено) / требует ручного шага». | AC-8 | + +--- + +## 5. Нефункциональные требования (NFR) + +| ID | Требование | +|----|------------| +| NFR-1 | **`src/**` не меняется.** Изменение — docs/templates/scripts/tests-only. `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, `check_*`, machine-verdict ключи, схема БД, контракт `projects.py` — байт-в-байт. | +| NFR-2 | **Self-hosting безопасность:** скрипт никогда не рестартит/не останавливает прод-контейнер, не пишет в общую БД, не пушит в `main` существующих репо, не трогает чужие Plane-проекты/Gitea-репо. Онбординг соседа не влияет на enduro/orchestrator. | +| NFR-3 | **Секреты:** токены Plane/Gitea — только из env на хосте; сгенерированные секреты (webhook HMAC) выводятся оператору для `.env` и в гит не попадают; `.env.example` — канон. | +| NFR-4 | **Anti-drift:** структурные тесты канона для kit-промптов (аналог `tests/test_agent_prompts_canon.py`) — расхождение kit с каноном 52d ловится CI, а не глазами. | +| NFR-5 | **Оффлайн-тестируемость:** все тесты детерминированы, без реальных вызовов Plane/Gitea (моки); сетевые шаги изолированы за тонким слоем. | +| NFR-6 | **Документация = golden source:** CLAUDE.md / `docs/architecture/README.md` / CHANGELOG обновлены в том же PR; reviewer-gate применим к самому PR. | + +--- + +## 6. Допущения и ограничения +- Plane API v1 позволяет создавать проект/статусы/лейблы (issue-API уже используется кодом); + если на практике какой-то вызов недоступен в CE — шаг деградирует в ручной пункт runbook + (fail-safe постановки, не блокер задачи). +- Скрипт — операторский инструмент: запускается человеком на хосте с токенами из `.env`, + **вне** конвейера задач; конвейер его не вызывает. +- Регистрация проекта вступает в силу после операторского рестарта (Ф-3) — это сознательное + ограничение (никакой автоматики рестартов, NFR-2); TTL-self-heal статусов (Ф-4) рестарта + не требует. +- Песочница для smoke — staging-контур (8501, изолированная БД, sandbox-проект) либо одноразовый + sandbox-проект в Plane/Gitea; выбор фиксирует архитектор/оператор в runbook. +- Языковая политика kit-промптов: по канону орка (5 ru + deployer en, ADR-001 D2 ORCH-092); + окончательное слово за архитектором, отступление — только с обоснованием в ADR. + +--- + +## 7. Критерии успеха (резюме; детали — 03-acceptance-criteria.md) +- Kit полон и канон-чист (структурные тесты зелёные): 6 промптов 52d + reviewer-gate + каркас + репо + INFRA.md + копии канонов. +- Скрипт: dry-run печатает полный план без мутаций; apply идемпотентен; registry-запись проходит + round-trip через фактический парсер; план Plane содержит точные имена статусов и лейблы. +- Runbook закрывает 100% шагов (ручные — помечены) и верификацию. +- `src/**` не тронут; пайплайн-инварианты байт-в-байт. +- Smoke на песочнице: агент по промпту находит и актуализирует доку (документированный прогон). + +--- + +## 8. Риски (кратко; детали — 10-tech-risks.md, заполняет архитектор) +- **R-1 Drift канона:** копия канонов в kit/новых репо разъезжается с живым каноном орка → + митигируется BR-2 (live-copy в момент онбординга) + NFR-4 (структурные тесты). +- **R-2 Тихая деградация Plane-контрактов:** опечатка в имени статуса/лейбла → fail-closed/ + fail-safe ветки молча не работают → митигируется BR-7 (точные имена из кода) + verify-режимом. +- **R-3 Скрипт с боевыми токенами:** ошибка = разрушительное действие → dry-run по умолчанию, + никаких delete-операций, аддитивность (BR-9). +- **R-4 «Скрипт сделал — оператор не знает про env+restart»:** проект создан, но невидим для + оркестратора → runbook явно фиксирует операторские шаги + verify-режим показывает разрыв (BR-8/10). +- **R-5 Утечка орк-специфики в kit:** новый проект получает чужие литералы (ORCH-, порты 8500/8501, + self-hosting-правила) → структурный тест на остаточные плейсхолдеры/литералы (AC-5). diff --git a/docs/work-items/ORCH-009/02-trz.md b/docs/work-items/ORCH-009/02-trz.md new file mode 100644 index 0000000..081338d --- /dev/null +++ b/docs/work-items/ORCH-009/02-trz.md @@ -0,0 +1,227 @@ +--- +work_item: ORCH-009 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-10 +model_used: claude-opus-4-8 +--- + +# 02 — ТЗ (TRZ): ORCH-009 — Онбординг проектов в оркестратор (turnkey) + +Work Item: **ORCH-009** · Repo: **orchestrator** · Стадия: analysis + +> ТЗ описывает **что** должно измениться и **где** (модули/контракты/артефакты). **Как** (точная +> раскладка kit, механизм подстановки, формат CLI) — решает архитектор в `06-adr/`. Имена путей +> ниже — рабочее предложение; архитектор вправе скорректировать, сохранив требования и AC. + +> ⚠️ Скоуп по актуализации 10.06: эталон = репо orchestrator; deliverables — в этом репо. +> `src/**` НЕ меняется (NFR-1) — задача docs/templates/scripts/tests-only. + +--- + +## 1. Сводка изменения +Создать **способность turnkey-онбординга** нового проекта: (1) параметризуемый **onboarding-kit** +(каркас нового репо: 6 промптов агентов по канону 52d/92, паспорт, AGENTS/CONTRIBUTING, скелет +`docs/` с INFRA.md, копии живых канонов `_templates/`+`_standards/`); (2) операторский +**onboarding-скрипт** (Gitea-репо + per-repo webhook; Plane-проект + статусы + лейблы; +материализация kit + initial push; генерация записи реестра; dry-run/apply/verify; идемпотентно); +(3) **runbook** `docs/operations/ONBOARDING.md` (полный чеклист, ручные шаги, верификация); +(4) **структурные тесты** анти-дрейфа. Конвейер/движок не трогаются. + +--- + +## 2. Задействованные модули / пути + +| Путь | Действие | Роль | +|------|----------|------| +| `onboarding/repo-skeleton/**` | создать | параметризуемый kit нового репо (дерево зеркалит целевой репо: `.openclaw/agents/*.md`, `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, `README.md`, `CHANGELOG.md`, `docs/**`) | +| `onboarding/README.md` | создать | устройство kit: словарь плейсхолдеров, правило «канон не форкается» (что копируется live, что шаблонизируется) | +| `scripts/onboard_project.py` | создать | операторский turnkey-CLI: `plan` (dry-run, дефолт) / `apply` / `verify`; идемпотентность; отчёт | +| `docs/operations/ONBOARDING.md` | создать | runbook: последовательность, ручные шаги (env+рестарт, UI-only Plane), верификация, откат | +| `docs/operations/SETUP_WEBHOOKS.md` | обновить | обобщить per-repo Gitea-webhook секцию (сейчас примеры захардкожены на enduro-trails); сослаться на ONBOARDING.md | +| `tests/test_onboarding_kit.py` | создать | структура kit, канон промптов, reviewer-gate, INFRA/AGENTS/CONTRIBUTING | +| `tests/test_onboarding_script.py` | создать | рендер/плейсхолдеры, registry round-trip, dry-run/идемпотентность, план Plane/Gitea (моки) | +| `tests/test_onboarding_invariants.py` | создать | `src/**` не тронут логикой онбординга; снапшот `STAGE_TRANSITIONS`/`QG_CHECKS` | +| `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md` | обновить | golden source: раздел «Онбординг проектов (ORCH-009)», запись changelog | +| `src/**` | **не менять** | NFR-1; скрипту разрешён **read-only import** `src.projects._parse_projects_json` / констант `src.plane_sync._PLANE_NAME_TO_KEY` для round-trip и точных имён (не дублировать литералы) — допустимость импорта vs снапшот-фикстура решает архитектор | + +Справочные источники kit (read-only): `.openclaw/agents/*.md`, `docs/_templates/` (16 скелетов), +`docs/_standards/` (3 стандарта), `docs/operations/INFRA.md` (образец структуры RUNBOOK). + +--- + +## 3. Функциональные требования + +### FR-1 — Onboarding-kit: состав каркаса нового репо (BR-3/BR-5/BR-6) +`onboarding/repo-skeleton/` содержит (минимум): + +``` +.openclaw/agents/{analyst,architect,developer,reviewer,tester,deployer}.md ← шаблоны промптов +CLAUDE.md ← паспорт проекта (per-repo канон, Ф-8) +AGENTS.md ← точка входа агентов: карта доков + правила ведения +CONTRIBUTING.md ← канон процесса: где что лежит, как вести +README.md ← entrypoint: что это, quickstart, ссылки +CHANGELOG.md ← пустой каркас +docs/ARCHITECTURE.md ← код-карта/потоки/БД (заполняется по мере жизни) +docs/PIPELINE.md ← стадии, QG, агенты (ссылается на _standards) +docs/PRODUCT_VISION.md ← зачем проект (BRD-свод) +docs/operations/INFRA.md ← обязательный RUNBOOK (см. FR-3) +docs/architecture/adr/ ← реестр сквозных ADR (канон орка, §1.4 BRD) +docs/work-items/.gitkeep +docs/history/.gitkeep +docs/_templates/ ← live-копия канона орка в момент онбординга (BR-2) +docs/_standards/ ← live-копия канона орка в момент онбординга (BR-2) +.env.example ← заготовка карты env (без секретов) +``` + +- **Параметризация** — единый словарь плейсхолдеров (минимум): `{{PROJECT_NAME}}`, `{{REPO}}`, + `{{WORK_ITEM_PREFIX}}`, `{{PLANE_PROJECT_ID}}`, `{{STACK}}`, `{{TEST_CMD}}`, + `{{PROD_PORT}}`/`{{STAGING_PORT}}` (расширяемо; единый синтаксис, фиксирует архитектор). +- **Ссылочная целостность:** каждый путь, на который ссылаются kit-промпты/AGENTS.md, существует + в каркасе (проверяемо тестом). +- **Правило «канон не форкается» (BR-2):** `docs/_templates/` и `docs/_standards/` НЕ хранятся + второй редактируемой копией в kit — копируются скриптом из живого канона репо орка в момент + материализации. В kit хранятся только параметризуемые дельты (промпты, паспорт, AGENTS, + CONTRIBUTING, README, INFRA и пр.). + +### FR-2 — Шаблоны промптов 6 ролей по канону 52d/92 (BR-3/BR-4) +Каждый из 6 шаблонов промптов: +- 5 обязательных XML-секций в нормативном порядке `` → `` → `` → + `` → ``; ``; `` у + developer/reviewer/tester (после ``); `` у решающих ролей — + как в эталоне `.openclaw/agents/` (ORCH-077/092). +- Запреты в формате «❌ X → ✅ Y». +- Директивы доки (жёстко): читай `CLAUDE.md`(паспорт)/`AGENTS.md`/`docs/ARCHITECTURE.md`/ADR + ПЕРЕД работой; пиши артефакты в `docs/work-items//` по `docs/_standards/PIPELINE_DOCS.md` + (скелеты из `docs/_templates/`); архитектор фиксирует решения в `06-adr/` + сквозные в + `docs/architecture/adr/adr-NNNN-slug.md`; каждый обновляет `CHANGELOG.md`/релевантную доку. +- **Reviewer:** содержит gate «документация обновлена? нет → `verdict: REQUEST_CHANGES`». +- Эмиссия 6-польной frontmatter-схемы 52c (`work_item`/`stage`/`author_agent`/`status`/ + `created_at`/`model_used`) — аддитивно; machine-verdict ключи и значения байт-в-байт + (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`); копируемые + примеры — с плейсхолдерами ``/`` (анти-паттерн ORCH-092 учтён). +- Стек-специфика (язык/тесты/команды) — только через плейсхолдеры; никаких унаследованных + орк-литералов (порты 8500/8501, «ORCH-», self-hosting-правила орка) в материализованном виде. +- Языковая политика: по канону орка (5 ru + deployer en, нормативно ADR-001 D2 ORCH-092); + отступление — только решением архитектора в ADR. + +### FR-3 — INFRA.md шаблон: обязательные секции (BR-6) +Шаблон `docs/operations/INFRA.md` нового проекта содержит секции: топология (контейнеры, порты +прод/staging, сеть, тома, БД); карта env-переменных (дескрипторы в репо; секреты ТОЛЬКО в `.env` +на хосте; `.env.example` — канон; `docker-compose.yml`/`Dockerfile` трекаются в гите); границы +доступа; эксплуатационные предупреждения, включая **риски общего хоста** (соседние контейнеры, +общие ресурсы; факт: хост впритык — см. `docs/epics/self-evolution.md` С-3). Существующий +`docs/operations/INFRA.md` орка с self-hosting-предупреждениями (общая БД/очередь/групповой риск +рестарта) — не модифицируется этой задачей (read-only образец). + +### FR-4 — Onboarding-скрипт: провижининг (BR-1/BR-7/BR-9/BR-11) +`scripts/onboard_project.py` (вход: имя проекта, repo, префикс work-item, параметры стека): +- **Gitea:** создать репо (API), создать per-repo webhook (`push`/`pull_request`/`status`, + HMAC-secret из/для `.env` — формат `SETUP_WEBHOOKS.md`); материализовать kit → **initial push + в свежесозданный пустой репо** (единственный разрешённый push; в существующие репо — никогда). +- **Plane:** создать проект (или принять существующий `--plane-project-id`); создать статусы со + **точными** именами из `_PLANE_NAME_TO_KEY` (22 имени; `STOP` — группа `cancelled`, + `Confirm Deploy` — отдельный статус; группы фиксирует архитектор по `plane_sync`) и лейблы + `autoApprove`/`autoDeploy`/`Bug`. Недоступное через API CE → пункт отчёта «ручной шаг» со + ссылкой на runbook (fail-safe, не падение). +- **Реестр:** сгенерировать запись `ORCH_PROJECTS_JSON` (полный новый массив или диф — + фиксирует архитектор), **валидную через фактический `projects._parse_projects_json`**; + вывести оператору инструкцию «добавь в `.env` + управляемый рестарт». Скрипт сам `.env` прода + не правит и контейнер не рестартит (NFR-2). +- **Режимы:** `plan` (дефолт; полный план без единой мутации), `apply` (исполнение), + `verify` (см. FR-5). Идемпотентность: повторный `apply` обнаруживает существующее + (репо/webhook/статусы/лейблы/файлы) и пропускает с пометкой; ничего не удаляет и не + перезаписывает существующий контент без явного флага. +- **Прозрачность:** лог каждого шага + итоговый отчёт: `created / skipped(exists) / manual-step`. +- **Webhook Plane:** не создаётся (workspace-level уже существует, Ф-6) — только проверка в verify. + +### FR-5 — Верификация (BR-10) +- `verify`-режим скрипта: запись реестра парсится (`_parse_projects_json` round-trip → поля + совпадают); статусы проекта резолвятся (все логические ключи, включая `confirm_deploy`/`stop`); + лейблы присутствуют; Gitea-webhook существует и активен; kit-файлы в репо (включая 6 промптов, + AGENTS.md, INFRA.md, `_templates`/`_standards`); нет неразрешённых плейсхолдеров. +- **Smoke на песочнице** (runbook, операторский): онбордить sandbox-проект → создать тестовую + задачу → стадия analysis в песочнице → убедиться: агент прочитал доку проекта (следы в + выводе/артефактах) и записал артефакты в `docs/work-items//` по канону. Контур песочницы + (staging 8501 / одноразовый sandbox) фиксирует архитектор в ADR + runbook. + +### FR-6 — Runbook ONBOARDING.md (BR-1/BR-8) +Полный чеклист онбординга: предусловия (токены, доступы) → шаги скрипта → **операторские шаги** +(env+рестарт — с предупреждением self-hosting: рестарт прода = групповое окно, выполнять +осознанно; UI-only шаги Plane, напр. drag-and-drop порядок статусов) → верификация (verify + +smoke) → откат (удаление созданного — вручную, скрипт не удаляет). Каждый ручной шаг — с командой +проверки результата. + +--- + +## 4. Изменения API +**Нет.** Новые/изменённые HTTP-эндпоинты оркестратора не вводятся; вебхук-контракты не меняются. +(Onboarding-CLI — операторский инструмент вне FastAPI-приложения.) + +## 5. Изменения схемы БД +**Нет.** Общая БД не читается и не пишется скриптом (NFR-2). + +## 6. Требования к новым/изменённым QG checks +**Нет.** Реестр `QG_CHECKS`/`check_*`/`STAGE_TRANSITIONS` — байт-в-байт (контроль — снапшот-тест, +TC-18). Онбординг — операторская способность, не гейт конвейера. + +--- + +## 7. Совместимость / регресс +- **Нулевая регрессия кода:** `src/**` не меняется → поведение конвейера для enduro/orchestrator + идентично; полный регресс `tests/` остаётся зелёным. +- **Kill-switch не требуется:** способность активируется только явным запуском операторского CLI; + в горячих путях конвейера нового кода нет. +- **Обратимость:** удаление `onboarding/`/`scripts/onboard_project.py`/runbook возвращает репо в + исходное состояние; созданные онбордингом внешние сущности сносятся вручную по разделу + «Откат» runbook. +- **Совместимость канонов:** kit-промпты проходят те же структурные требования, что эталонные + (анти-дрейф NFR-4); обновление канона орка автоматически подхватывается live-copy частью kit + (BR-2), шаблонные дельты — через обычные PR с reviewer-gate. + +--- + +## 8. Артефакты pipeline (создать/обновить в ТОМ ЖЕ PR) +- `docs/work-items/ORCH-009/06-adr/ADR-001-…` — решения архитектора (раскладка kit, синтаксис + плейсхолдеров, copy-vs-template split по файлам, импорт `src` из скрипта vs снапшот, контур + песочницы, языковая политика kit-deployer). +- `docs/architecture/README.md` — раздел «Онбординг проектов (ORCH-009)». +- `CLAUDE.md` — краткий абзац о способности онбординга. +- `CHANGELOG.md` — запись `feat:`. +- `docs/operations/ONBOARDING.md` (новый), `docs/operations/SETUP_WEBHOOKS.md` (обобщение). +- `07-infra-requirements.md` — предусловия онбординга (токены/доступы), заполняет архитектор. + +--- + +## 9. Инварианты (не нарушать) +- `src/**` без изменений; `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict ключи/схема + БД — байт-в-байт (NFR-1). +- Скрипт: не рестартит/не останавливает прод-контейнер; не пушит в `main` существующих репо + (INV-4 — мерж только через PR-merge API — не затрагивается: initial push идёт в свежесозданный + пустой репо, не являющийся участником конвейера до регистрации); не удаляет внешние сущности; + секреты в гит не попадают (NFR-2/NFR-3). +- Никаких сетевых вызовов в тестах (NFR-5); никаких новых обязательных pip-зависимостей без + обоснования в ADR. +- Эталонные промпты орка `.openclaw/agents/*.md` этой задачей не модифицируются (они — read-only + образец; их правка = отдельные задачи канона). + +--- + +## 10. Открытые вопросы для архитектора (не блокируют анализ) +- OQ-1: Раскладка kit — `onboarding/repo-skeleton/` (предложение) vs `docs/_onboarding/` vs + `scripts/onboarding/`; где словарь плейсхолдеров. +- OQ-2: Механизм подстановки — stdlib (`str.replace`/`string.Template`) без новых зависимостей + (рекомендация) vs шаблонизатор (новая зависимость — потребует обоснования). +- OQ-3: Copy-vs-template split: какие файлы kit — live-copy канона, какие — параметризуемые + шаблоны (минимум по BR-2: `_templates`/`_standards` — live-copy). +- OQ-4: Скрипту импортировать `src.projects`/`src.plane_sync` (точные имена/парсер, нет + дублирования) vs автономный снапшот констант с тестом синхронизации. +- OQ-5: Plane API CE: фактическая доступность создания проекта/статусов/лейблов — что уходит в + ручные шаги runbook. +- OQ-6: Контур песочницы для smoke (staging 8501 vs одноразовый sandbox-проект) и судьба + sandbox-артефактов после прогона. +- OQ-7: Языковая политика kit-промптов для не-self-hosting проектов (рекомендация: канон орка, + deployer — en). +- OQ-8: Защита `main` нового репо в Gitea (branch protection): не должна ломать PR-merge API + конвейера — включать ли вообще (рекомендация: не включать, зафиксировать в runbook). diff --git a/docs/work-items/ORCH-009/03-acceptance-criteria.md b/docs/work-items/ORCH-009/03-acceptance-criteria.md new file mode 100644 index 0000000..575425f --- /dev/null +++ b/docs/work-items/ORCH-009/03-acceptance-criteria.md @@ -0,0 +1,146 @@ +--- +work_item: ORCH-009 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-10 +model_used: claude-opus-4-8 +--- + +# 03 — Критерии приёмки (Acceptance Criteria): ORCH-009 — Turnkey-онбординг проектов + +Work Item: **ORCH-009** · Repo: **orchestrator** · Стадия: analysis + +Формат: каждый критерий — чёткое условие **PASS/FAIL**, проверяемое буквально по файлам +репозитория и детерминированным тестам (без сети). AC-13 — единственный операторский +(документированный smoke), его автоматизируемая часть вынесена в AC-2/AC-12. + +--- + +## AC-1 — Kit полон (состав каркаса) +**Условие:** инспекция `onboarding/repo-skeleton/` (или каталога, выбранного архитектором в ADR). +- **PASS:** присутствуют все элементы FR-1: 6 шаблонов промптов (`analyst/architect/developer/ + reviewer/tester/deployer`), `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, `README.md`, + `CHANGELOG.md`, `docs/ARCHITECTURE.md`, `docs/PIPELINE.md`, `docs/PRODUCT_VISION.md`, + `docs/operations/INFRA.md`, `docs/architecture/adr/`, `docs/work-items/`, `docs/history/`, + `.env.example`; материализация добавляет live-копии `docs/_templates/` + `docs/_standards/`. +- **FAIL:** отсутствует любой элемент состава, либо промптов меньше 6. + +## AC-2 — Промпты kit соответствуют канону 52d/92 +**Условие:** структурные тесты по каждому из 6 шаблонов промптов. +- **PASS:** в каждом — 5 обязательных XML-секций в нормативном порядке `→ + `; запреты в формате «❌ → ✅»; `` у + developer/reviewer/tester; директивы «читай паспорт/AGENTS.md/доку ПЕРЕД работой» и «пиши + артефакты в `docs/work-items//`»; эмиссия 6-польной frontmatter-схемы 52c с + плейсхолдерными примерами дат/моделей; machine-verdict ключи у ролей-вердиктов байт-в-байт + (`verdict:` / `result:` / `staging_status:` / `deploy_status:` / `security_status:`). +- **FAIL:** нарушен порядок/состав секций, отсутствует любой verdict-ключ или директива доки, + пример frontmatter содержит захардкоженные дату/модель. + +## AC-3 — Reviewer-gate на обновление доки +**Условие:** шаблон `reviewer.md` в kit. +- **PASS:** содержит явное правило: документация (CHANGELOG/релевантные доки/ADR) обновлена в том + же PR; нет → `verdict: REQUEST_CHANGES`. +- **FAIL:** правило отсутствует или сформулировано как необязательное. + +## AC-4 — Языковая политика kit +**Условие:** проверка языка шаблонов промптов против решения ADR (дефолт — канон орка). +- **PASS:** языковая раскладка соответствует зафиксированной в ADR (по умолчанию: 5 ru + + deployer en, как ADR-001 D2 ORCH-092); отступление — только с обоснованием в ADR. +- **FAIL:** язык промптов противоречит ADR, либо политика нигде не зафиксирована. + +## AC-5 — Материализация: плейсхолдеры и отсутствие утечек +**Условие:** рендер kit с тестовыми параметрами (`PROJECT_NAME`, `REPO`, `WORK_ITEM_PREFIX` и т.д.). +- **PASS:** все плейсхолдеры подставлены; в результате нет ни одного неразрешённого плейсхолдера + (grep по синтаксису из ADR); нет утечек орк-специфики, где должен быть параметр (литералы + `ORCH-` как префикс work-item чужого проекта, порты 8500/8501, self-hosting-правила орка); + пути, на которые ссылаются отрендеренные промпты/AGENTS.md, существуют в каркасе. +- **FAIL:** найден неразрешённый плейсхолдер, орк-литерал вместо параметра или битая ссылка + на несуществующий путь. + +## AC-6 — Registry round-trip через фактический парсер +**Условие:** скрипт генерирует запись реестра для тестового проекта. +- **PASS:** сгенерированный JSON парсится `projects._parse_projects_json` без ошибок; полученный + `ProjectConfig` несёт исходные `plane_project_id`/`repo`/`work_item_prefix`/`name`; существующие + записи реестра не модифицируются и не теряются. +- **FAIL:** парсер отвергает запись, поля искажены, либо генерация ломает/теряет существующие записи. + +## AC-7 — План Plane: точные статусы и лейблы +**Условие:** `plan`-режим для нового проекта (моки сети). +- **PASS:** план провижининга содержит ВСЕ канонические имена статусов из `_PLANE_NAME_TO_KEY` + (включая `Confirm Deploy` и `STOP` с группой `cancelled`) и лейблы `autoApprove`/`autoDeploy`/ + `Bug`; имена байт-в-байт совпадают с константами `src/plane_sync.py` (или их синхронизированным + снапшотом по OQ-4); недоступные через API шаги помечены `manual-step` со ссылкой на runbook. +- **FAIL:** пропущен/искажён любой статус или лейбл; недоступный шаг молча отброшен. + +## AC-8 — План Gitea: репо + per-repo webhook; dry-run без мутаций +**Условие:** `plan`-режим (моки сети). +- **PASS:** план содержит создание репо, создание webhook с events `push`/`pull_request`/`status` + и HMAC-secret (секрет — для `.env` оператора, не в гит), материализацию kit + initial push в + свежесозданный репо; в режиме `plan` не выполняется НИ ОДНОЙ мутации (ни одного + POST/PUT/DELETE-вызова в моках, ни одной записи на диск вне отчёта). +- **FAIL:** план неполон, или dry-run произвёл мутацию. + +## AC-9 — Идемпотентность и безопасность apply +**Условие:** повторный `apply` на частично/полностью созданном проекте (моки: сущности существуют). +- **PASS:** существующие сущности (репо/webhook/статусы/лейблы/файлы) распознаны и пропущены с + пометкой `skipped(exists)`; ничего не удалено и не перезаписано без явного флага; скрипт не + выполняет рестарт/останов контейнеров, не правит `.env` прода, не пушит в существующие репо + (в коде отсутствуют такие операции — проверяемо тестом/ревью); итоговый отчёт перечисляет + created/skipped/manual-step. +- **FAIL:** дублирование сущностей, любое удаление/перезапись без флага, любая операция + рестарта/push в существующий репо, отсутствие отчёта. + +## AC-10 — INFRA.md шаблон: обязательные секции +**Условие:** инспекция шаблона `docs/operations/INFRA.md` в kit. +- **PASS:** присутствуют секции: топология (контейнеры/порты прод+staging/сеть/тома/БД); + карта env-переменных + правило секретов (только `.env` на хосте, `.env.example` — канон); + границы доступа; предупреждения о рисках общего хоста. Существующий `docs/operations/INFRA.md` + орка (self-hosting-предупреждения) этой задачей не изменён. +- **FAIL:** отсутствует любая обязательная секция, либо изменён INFRA.md самого орка. + +## AC-11 — Runbook ONBOARDING.md полон +**Условие:** инспекция `docs/operations/ONBOARDING.md`. +- **PASS:** покрывает все слои BR-1 в последовательности: предусловия (токены/доступы) → Plane + (проект/статусы/лейблы) → Gitea (репо/webhook) → kit (материализация/push) → регистрация + (env-строка + операторский управляемый рестарт с self-hosting-предупреждением) → верификация + (`verify` + smoke на песочнице) → откат; каждый ручной шаг помечен и снабжён командой проверки; + Plane workspace-webhook описан как существующий (проверка, не создание). +- **FAIL:** пропущен слой, ручной шаг не помечен/без проверки, или runbook требует + автоматического рестарта прода. + +## AC-12 — Инварианты: src/** не тронут +**Условие:** diff PR + снапшот-тест. +- **PASS:** `git diff` PR не содержит изменений `src/**`; снапшот `STAGE_TRANSITIONS` и реестра + `QG_CHECKS` совпадает с эталоном; эталонные промпты `.openclaw/agents/*.md` орка не изменены; + полный регресс `tests/` зелёный. +- **FAIL:** любой diff в `src/**` или `.openclaw/agents/`, расхождение снапшота, красный регресс. + +## AC-13 — Smoke: агент находит, использует и актуализирует доку (операторский) +**Условие:** документированный прогон по runbook на песочнице (контур — по ADR): онбординг +sandbox-проекта → тестовая задача → стадия analysis. +- **PASS:** агент песочницы по своему промпту прочитал доку проекта (следы чтения паспорта/ + AGENTS.md в выводе или артефактах) и записал артефакты в `docs/work-items//` по канону + (структура соответствует `PIPELINE_DOCS.md`); результат прогона зафиксирован в runbook/отчёте + задачи. Для приёмки данной задачи прогон выполняется один раз и протоколируется. +- **FAIL:** агент не нашёл доку (артефакты вне канона/не созданы), либо прогон не запротоколирован. + +--- + +## Сводная матрица AC ↔ BR/FR + +| AC | BR | FR | Тип проверки | +|----|----|----|--------------| +| AC-1 | BR-5 | FR-1 | unit (структура kit) | +| AC-2 | BR-3 | FR-2 | unit (структурный канон) | +| AC-3 | BR-4 | FR-2 | unit | +| AC-4 | BR-3 | FR-2 | unit + ADR | +| AC-5 | BR-2/BR-5 | FR-1/FR-2 | unit (рендер) | +| AC-6 | BR-8 | FR-4 | integration (реальный парсер) | +| AC-7 | BR-7 | FR-4 | unit (план, моки) | +| AC-8 | BR-1/BR-9 | FR-4 | unit (план, моки) | +| AC-9 | BR-9/BR-11 | FR-4 | unit/integration (моки) | +| AC-10 | BR-6 | FR-3 | unit (структура) | +| AC-11 | BR-1/BR-8 | FR-6 | unit (структура дока) | +| AC-12 | NFR-1 | — | unit (снапшот) + ревью diff | +| AC-13 | BR-10 | FR-5 | ручной smoke (протоколируемый) | diff --git a/docs/work-items/ORCH-009/04-test-plan.yaml b/docs/work-items/ORCH-009/04-test-plan.yaml new file mode 100644 index 0000000..09678f0 --- /dev/null +++ b/docs/work-items/ORCH-009/04-test-plan.yaml @@ -0,0 +1,164 @@ +work_item: ORCH-009 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-10 +model_used: claude-opus-4-8 +title: "Turnkey-онбординг проектов: kit + скрипт + runbook (ORCH-009)" +framework: pytest +scope: > + Структурная полнота onboarding-kit, канон 52d/92 шаблонов промптов, материализация + (плейсхолдеры/утечки), registry round-trip через фактический парсер projects.py, + планы Plane/Gitea (dry-run, моки), идемпотентность apply, runbook, инварианты src/**. + Вне покрытия pytest: реальные вызовы Plane/Gitea API и операторский smoke на песочнице + (AC-13) — выполняется вручную по docs/operations/ONBOARDING.md и протоколируется. +notes: > + Все тесты детерминированы, без сети (Plane/Gitea мокируются; NFR-5). Точные имена файлов + тест-модулей могут уточняться архитектором при сохранении покрытия TC↔AC. Полный регресс + tests/ должен оставаться зелёным (src/** не меняется — NFR-1). Если ADR изменит раскладку + kit (OQ-1) — пути в тестах следуют ADR, маппинг TC↔AC неизменен. + +tests: + # ---------- AC-1: состав kit ---------- + - id: TC-01 + type: unit + description: "Kit содержит все элементы FR-1: 6 шаблонов промптов, CLAUDE.md, AGENTS.md, CONTRIBUTING.md, README.md, CHANGELOG.md, docs/ARCHITECTURE.md, docs/PIPELINE.md, docs/PRODUCT_VISION.md, docs/operations/INFRA.md, docs/architecture/adr/, docs/work-items/, docs/history/, .env.example" + module: tests/test_onboarding_kit.py + expected: PASS + + - id: TC-02 + type: unit + description: "Материализация добавляет live-копии docs/_templates/ (16 канонических скелетов) и docs/_standards/ (3 стандарта) из живого канона репо орка; вторая редактируемая копия канона в kit отсутствует (BR-2)" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-2: канон промптов 52d/92 ---------- + - id: TC-03 + type: unit + description: "Каждый из 6 шаблонов промптов содержит 5 обязательных XML-секций в нормативном порядке context→task→deliverables→constraints→output_format" + module: tests/test_onboarding_kit.py + expected: PASS + + - id: TC-04 + type: unit + description: "Шаблоны developer/reviewer/tester содержат секцию ; запреты оформлены в формате '❌ → ✅'" + module: tests/test_onboarding_kit.py + expected: PASS + + - id: TC-05 + type: unit + description: "Каждый шаблон промпта направляет агента к доке: читай паспорт(CLAUDE.md)/AGENTS.md/ARCHITECTURE/ADR перед работой; пиши артефакты в docs/work-items// по PIPELINE_DOCS; обновляй CHANGELOG/доку" + module: tests/test_onboarding_kit.py + expected: PASS + + - id: TC-06 + type: unit + description: "Шаблоны эмитят 6-польную frontmatter-схему 52c (work_item/stage/author_agent/status/created_at/model_used); machine-verdict ключи ролей байт-в-байт (verdict:/result:/staging_status:/deploy_status:/security_status:); примеры дат/моделей — плейсхолдеры, не литералы (анти-паттерн ORCH-092)" + module: tests/test_onboarding_kit.py + expected: PASS + + # ---------- AC-3: reviewer-gate ---------- + - id: TC-07 + type: unit + description: "Шаблон reviewer.md содержит обязательный gate: документация не обновлена в PR → verdict: REQUEST_CHANGES" + module: tests/test_onboarding_kit.py + expected: PASS + + # ---------- AC-4: языковая политика ---------- + - id: TC-08 + type: unit + description: "Языковая раскладка шаблонов соответствует политике ADR (дефолт: 5 ru + deployer en, канон ADR-001 D2 ORCH-092)" + module: tests/test_onboarding_kit.py + expected: PASS + + # ---------- AC-5: материализация ---------- + - id: TC-09 + type: unit + description: "Рендер kit с тестовыми параметрами подставляет все плейсхолдеры: в выходе нет ни одного неразрешённого плейсхолдера (grep по синтаксису из ADR)" + module: tests/test_onboarding_script.py + expected: PASS + + - id: TC-10 + type: unit + description: "В отрендеренном kit нет утечек орк-специфики, где должен быть параметр: префикс ORCH- вместо префикса проекта, порты 8500/8501, self-hosting-правила орка" + module: tests/test_onboarding_script.py + expected: PASS + + - id: TC-11 + type: unit + description: "Ссылочная целостность: каждый путь, на который ссылаются отрендеренные промпты и AGENTS.md, существует в материализованном каркасе" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-6: registry round-trip ---------- + - id: TC-12 + type: integration + description: "Сгенерированная скриптом запись реестра парсится фактическим projects._parse_projects_json; ProjectConfig несёт исходные plane_project_id/repo/work_item_prefix/name; существующие записи реестра сохранены без искажений" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-7: план Plane ---------- + - id: TC-13 + type: unit + description: "plan-режим: план Plane содержит все канонические имена статусов _PLANE_NAME_TO_KEY (включая 'Confirm Deploy' и 'STOP' с группой cancelled) байт-в-байт и лейблы autoApprove/autoDeploy/Bug" + module: tests/test_onboarding_script.py + expected: PASS + + - id: TC-14 + type: unit + description: "Шаг Plane, недоступный через API (мок отвечает отказом/не реализовано), помечается в плане/отчёте как manual-step со ссылкой на runbook — не отбрасывается молча и не валит скрипт" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-8: план Gitea + dry-run ---------- + - id: TC-15 + type: unit + description: "plan-режим: план Gitea содержит создание репо, webhook (events push/pull_request/status + HMAC-secret вне гита) и initial push kit в свежесозданный репо" + module: tests/test_onboarding_script.py + expected: PASS + + - id: TC-16 + type: unit + description: "dry-run (plan) не выполняет ни одной мутации: ноль POST/PUT/DELETE в замоканных клиентах Plane/Gitea, ноль git push, ноль записей на диск вне отчёта" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-9: идемпотентность / безопасность apply ---------- + - id: TC-17 + type: integration + description: "Повторный apply на уже созданном проекте (моки: репо/webhook/статусы/лейблы существуют): сущности распознаны и помечены skipped(exists); нет дублей, удалений и перезаписи без явного флага; итоговый отчёт перечисляет created/skipped/manual-step" + module: tests/test_onboarding_script.py + expected: PASS + + - id: TC-18 + type: unit + description: "Скрипт не содержит операций рестарта/останова контейнеров, правки прод-.env и push в существующие репо: на моках полного прогона apply такие вызовы отсутствуют (NFR-2)" + module: tests/test_onboarding_script.py + expected: PASS + + # ---------- AC-10: INFRA.md шаблон ---------- + - id: TC-19 + type: unit + description: "Шаблон INFRA.md kit содержит обязательные секции: топология (контейнеры/порты прод+staging/сеть/тома/БД), карта env + правило секретов (.env на хосте, .env.example — канон), границы доступа, риски общего хоста" + module: tests/test_onboarding_kit.py + expected: PASS + + # ---------- AC-11: runbook ---------- + - id: TC-20 + type: unit + description: "ONBOARDING.md покрывает все слои в последовательности: предусловия → Plane → Gitea → kit → регистрация (env + операторский управляемый рестарт с self-hosting-предупреждением) → верификация (verify + smoke) → откат; ручные шаги помечены и снабжены командами проверки" + module: tests/test_onboarding_kit.py + expected: PASS + + # ---------- AC-12: инварианты ---------- + - id: TC-21 + type: unit + description: "Снапшот STAGE_TRANSITIONS и реестра QG_CHECKS совпадает с эталоном (src/** не затронут логикой онбординга); эталонные промпты .openclaw/agents/ орка не изменены задачей" + module: tests/test_onboarding_invariants.py + expected: PASS + + - id: TC-22 + type: integration + description: "Полный регресс существующего tests/ остаётся зелёным после добавления onboarding-артефактов (никакой новый импорт/код не ломает конвейер)" + module: tests/ + expected: PASS