Files
wiki/memory/2026-06-05.md
2026-06-05 13:30:01 +03:00

425 lines
57 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-06-05
## Orchestrator — CI-гейт качества закрыт ✅ (продолжение self-hosting ORCH-7)
### Главный итог
**CI у orchestrator теперь честно зелёный.** Дефект изоляции тестов (тесты протекали друг в друга через синглтон `settings`) закрыт. Гейт качества для self-hosting работает по-настоящему.
### Что было сделано
- **PR #27** (ветка `fix/isolate-webhook-tests-from-plane`) — три коммита:
- `7bbab9c` — изоляция 3 webhook-тестов от живого Plane API (моки через ИСТОЧНИК `src.plane_sync.*`)
- `e856e09` — миграция `test_plane_webhook_generates_sequential_ids` под новый контракт (задача создаётся при переходе В In Progress, а не на `work_item.created`)
- `1baae81`**autouse-фикстура в `tests/conftest.py`**, сбрасывает webhook-секрет (+ db_path) на синглтоне settings перед каждым тестом
- Проверено лично на проде: полный `pytest tests/` в чистом docker-окружении = **294 passed, 0 failed** (было 10 failed). CI run 547/548 = **success** (впервые).
- 401/HMAC/dedup тесты ЖИВЫ — фикстура их не сломала (они перекрывают её своим monkeypatch). Off-limits зона не тронута: правки только в `tests/conftest.py` и `tests/test_webhooks.py`, src/ чист.
### Ключевой урок — интерференция тестов через синглтон settings
- `Settings` (Pydantic, src/config.py) читает env ОДИН раз при создании объекта `settings`.
- `test_webhooks.py` ставит секрет жёстко `os.environ["..."]=""` на import-time; другие файлы — через `setdefault`; `test_webhook_dedup.py` ставит реальный `"s3cr3t"` через monkeypatch.
- В ПОЛНОМ прогоне `pytest tests/` секрет протекал между файлами → HMAC включался → webhook-тесты ловили `assert 401 == 200`. По отдельности файл зелёный, вместе — красный.
- **Решение-паттерн:** autouse-фикстура в conftest, сброс протекающего состояния синглтона через monkeypatch перед каждым тестом. НЕ менять сам механизм/защищённые тесты — только навести порядок с изоляцией. `db_path` тоже протекал (get_task_by_repo_branch возвращал stale) — Dev законно добавил и его сброс.
### Мерж ВЫПОЛНЕН ✅ (05.06, Слава дал «да»)
- **PR #27 → MERGED в main** (HTTP 200). main HEAD = `d0a3424` Merge PR #27. Все 3 коммита фиксов в истории main.
- **PR #26 → CLOSED без мержа** (поглощён #27).
- Нюанс: CI на самом main после merge-commit отдельным прогоном не появился (workflow триггерится на push/PR-ветки; merge-commit мог не дёрнуть). Код в main = ровно то, что прогонялось зелёным (294 passed). Гейт на будущих PR работает.
- **Пункт №1 self-hosting (CI-гейт) ЗАКРЫТ.** Осталось: удалить отработанные ветки fix/isolate, ci/add (косметика).
## Staging-среда для orchestrator (ORCH-30..35) — дизайн оформлен, задачи в Backlog
### Решения (гибрид C)
- Агенты на staging: ПО ДЕФОЛТУ заглушки (быстро/дёшево/детерминированно — гейт проверяет работоспособность ОРКа, не качество LLM) + режим `full-real` по флагу (настоящий Claude CLI через `claude-cli-proxy`).
- Plane/Gitea на staging — настоящие, но в песочнице (ORCH-SANDBOX проект + orchestrator-sandbox репо).
- `DEPLOY_REQUIRE_MANUAL_APPROVE=true` на старте — хук тормозит после зелёного staging, ждёт «go» Славы.
- **Деплоем рулит ВНЕШНИЙ хост-хук, не сам контейнер орка** (орк не может убить свой процесс на середине деплоя; rollback через PREV_IMG, образец `enduro-deploy-hook.sh`).
- Задачи только в Backlog — конвейер стартует ТОЛЬКО при переходе В In Progress (Feature 1). Backlog безопасен.
### Задачи (все Backlog, project ORCH id 8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a)
- **ORCH-31** id=5a68a13c-3f3b-4d9e-91f7-24b0794bed06 — staging-инфра: контейнер `orchestrator-staging` (порт 8501), изолированная БД через `ORCH_DB_PATH`/volume `./data/staging`, профиль compose `staging`
- **ORCH-32** id=3dadcf0d-f1b6-4302-8075-8d428ace01f6 — песочница: Plane `ORCH-SANDBOX` + Gitea `orchestrator-sandbox`, реестр через env `ORCH_PROJECTS_JSON` (код не трогать)
- **ORCH-33** id=a11a7c0f-a78a-4309-9aa5-1c43d4355d0f — тест-сьют (smoke + доступы + e2e), режим full-real
- **ORCH-34** id=47fe9e75-d7ff-4ecb-bb99-67af9b23ab67 — хост-деплой-хук `orchestrator-deploy-hook.sh` (build candidate→staging-гейт→promote→health 10×6с→auto-rollback), пересекается с ORCH-21
- **ORCH-35** id=4ead9be7-e1bf-4a28-8c76-88bda1c1fc2c — стадия `deploy-staging` перед `deploy-prod`
### Разведка инфры (факты для точных ТЗ)
- compose: один service `orchestrator`, `network_mode: host`, порт 8500 в команде uvicorn (`uvicorn src.main:app --host 0.0.0.0 --port 8500`). Staging → просто другой порт 8501 + профиль `staging`.
- `ORCH_DB_PATH` УЖЕ параметризован (config.py:43 дефолт `/app/data/orchestrator.db`) → изоляция БД через него + отдельный volume `./data/staging`.
- Реестр проектов через env `ORCH_PROJECTS_JSON` (JSON-массив) → sandbox добавляется в `.env.staging`, код менять не надо.
- В Plane sandbox-проекта ещё НЕТ (есть ag_proj, First, ET, ORCH). В Gitea sandbox-репо ещё НЕТ (enduro-trails, openclaw-vault, orchestrator, wiki). Заведу сама через API при выкате Этапа 2.
- ТЗ готово: `tasks/orchestrator/DEV_TASK_ORCH31_STAGING_INFRA.md`. Запускать Dev на ORCH-31 ТОЛЬКО когда репо свободно (не толкать двух Dev на один git одновременно).
## Грабли/правила (подтверждены этой сессией)
- Файлы памяти: durable → ТОЛЬКО `memory/YYYY-MM-DD.md` (append). Сегодня `2026-06-05.md`.
- Dev: код/тесты/конфиги → ТОЛЬКО в Gitea-репо orchestrator через PR. Push в main запрещён (pre-receive hook). Dev НЕ мержит — мержит ревьюер (Стрим/Слава).
- Инфра вне репо (`.env.staging` реальный, Plane/Gitea sandbox-сущности, хост-деплой-хук, поднятие контейнера) — делаю я через installer/API, НЕ Dev через PR. В репо только `.env.staging.example`.
- ⚠️ Dev: НЕ регистрировать раннеров, НЕ nohup. Раннер `mva154-runner-orch` уже есть.
- ⚠️ Off-limits без согласования: HMAC-механизм, 9 HMAC/401 тестов, src/config.py settings, check_reviewer_verdict, check_deploy_status, merge-gate gitea.py, PLANE_STATES, set_issue_done, launcher, queue, stages.py mapping, _parse_tests_verdict, check_tests_local (только DEPRECATED, не удалять).
- ⚠️ Грабля push: после push `git log origin/main..origin/<branch>` ДОЛЖЕН показать коммит ДО отчёта «PR готов».
- ⚠️ Plane API: дёргать через base64-stdin+docker cp в контейнер orchestrator. URL `http://localhost:8091` БЕЗ /api/v1 (суффикс добавляет код!), заголовок `X-API-Key`, токен `ORCH_PLANE_API_TOKEN`. Без /api/v1 Plane вернёт HTML(200) вместо JSON.
- Прогон тестов в чистом окружении (как CI): `docker run --rm -v /home/slin/repos/orchestrator:/code:ro -w /code -e PYTHONPATH=/code --entrypoint python3 $(docker inspect orchestrator --format '{{.Config.Image}}') -m pytest tests/ -q`
- Эндпоинт Actions: `GET /api/v1/repos/admin/orchestrator/actions/tasks`, токен `docker exec orchestrator printenv ORCH_GITEA_TOKEN`.
- Сервер: `slin@82.22.50.71` (sshpass, pw motoZ@yaz2010), репо `/home/slin/repos/orchestrator`, контейнер `orchestrator` порт 8500, Gitea https://git.mva154.duckdns.org.
- Модель Dev: `tokenator/claude-sonnet-4-6` (vibecode кредиты кончились; альт tokenator/claude-opus-4-8).
- ElevenLabs TTS квота кончилась → отвечать ТЕКСТОМ.
## Уборка раннеров (TODO, ждёт ОК Славы)
3 процесса act-runner: systemd `act-runner.service` (рабочий, mva154-runner), PID 3828601 (старый mva154-runner с 19.05), PID 4091018 (mva154-runner-orch через nohup — НЕ переживёт reboot). План: systemd-unit вместо nohup, прибить лишние. Принести Славе на ОК.
## Следующие шаги
1. [ждёт кивка] Мерж PR #27 в main, закрыть #26 → CI-гейт (пункт self-hosting) закрыт.
2. Запустить Dev на ORCH-31 (staging-инфра) когда репо свободно.
3. Этап 2 (ORCH-32): завести ORCH-SANDBOX в Plane + orchestrator-sandbox в Gitea при выкате.
4. Уборка раннеров (план Славе на ОК).
---
## Продолжение сессии (флаш #2)
### PR #27 СМЕРЖЕН в main ✅ / #26 закрыт
- **PR #27 merged** (HTTP 200), main HEAD = `d0a3424` "Merge PR #27". Все три коммита фиксов в истории main (изоляция Plane + seq-тест + изоляция секрета).
- **PR #26 закрыт без мержа** (поглощён #27). Подтверждено API: #27 state=closed merged=True; #26 state=closed merged=False.
- CI-гейт качества orchestrator закрыт по-настоящему → главный блокер self-hosting (ORCH-7) снят.
- Грабля по экранированию: при мерже через Gitea API двойной SSH-эскейп кавычек поехал → передавала скрипт через **base64** (echo b64 | base64 -d | bash). Рабочий приём для сложных команд через sshpass.
- ⚠️ Косметика-TODO: удалить отработанные ветки `fix/isolate-webhook-tests-from-plane` и `ci/add-gitea-workflow` (обе merged/closed).
### Этап 1 (ORCH-31) — staging-инфра ГОТОВА, PR #28 (ждёт мержа на момент флаша)
- Dev отработал, ветка `feature/ORCH-31-staging-infra`, **PR #28 open, mergeable**.
- 4 файла, прод-блок compose НЕ тронут (diff чистый: `@@ -25,3 +25,39 @@` — чистое добавление в конце, прод-строки 1-25 без изменений).
- Проверено на проде лично: обычный `docker compose config` показывает ТОЛЬКО `orchestrator`; staging виден ЛИШЬ с `--profile staging` → случайно не поднимется. Контейнера `orchestrator-staging` на проде нет (крутится только прод, Up 15h). БД изолирована через volume `./data/staging` (на хосте ещё не создан — создастся при первом запуске).
- ⚠️ Нюанс: `docker compose config --profile staging` без реального `.env.staging` не выводит детали порта 8501 — это норма, реальная валидация при выкате с настоящим `.env.staging` (Этап 2).
- **Развилка (ждёт ОК Славы):** мержить #28 сейчас (чистый инфра-код в main, ничего не запускается — staging «спящий чертёж») ИЛИ ждать. Я ЗА мерж сейчас (вариант 1) — main маленькими безопасными кусками.
- На хосте куча `orchestrator.db.bak-deploy*` — бэкапы прод-БД от прошлых деплоев 03-04.06, НЕ наша история, не трогать.
### Объяснила Славе что проверяют 294 теста (для контекста)
Группы тестов orchestrator (страховочная сетка перед самодеплоем): гейт качества (41), Telegram-трекер (28), resilience/переживание рестарта (26), usage+queue (23+19), движок этапов конвейера (22), запуск агентов через Claude CLI (18), webhooks Plane/Gitea + дедуп + подпись (16+9+8), маршрутизация проектов после инцидента 02.06 (16), git-worktree изоляция веток (9), мелочёвка (task.md, комменты, ротация логов, вердикты). Тесты НЕ вшиты в docker-образ — только в репо (правильно).
### Время
Сессия идёт глубокой ночью UTC (~04:40-04:50), у Славы утро ~07:40 UTC+3. Несколько раз предлагала паузу — Слава продолжает работать.
### Следующий шаг (на момент флаша)
Жду ОК Славы: мержить PR #28 → идти на Этап 2 (ORCH-32: песочница Plane ORCH-SANDBOX + Gitea orchestrator-sandbox + реальный `.env.staging` + поднятие staging-контейнера через installer).
---
## Продолжение (флаш #3) — STAGING-СТЕНД ПОДНЯТ 🚀
### PR #28 смержен → Этапы 1+2 выкачены, staging живой на проде
- **PR #28 merged** (main HEAD `3b68a29`). ⚠️ Грабля: при мерже через Gitea API заголовок `Authorization` сглючил → `token is required` (HTTP 401); фикс — `AUTH = "token " + TOK` отдельной переменной, не инлайнить. Со второго раза HTTP 200.
- **Этап 2 (ORCH-32) песочница создана:** Gitea-репо `admin/orchestrator-sandbox` (auto-init main) + Plane-проект "ORCH Sandbox" (identifier SANDBOX, **id 8c5a3025-4f9d-4190-b79f-fa06276bb27e**). Имя в Plane БЕЗ дефиса — Plane не пускает спецсимволы в name (ошибка "Project name cannot contain special characters").
- **Токены — вариант 1** (Слава подтвердил): общие с продом, изоляция по проекту/репо.
- **`.env.staging` собран** (скрипт из прод-.env + staging-оверрайды), бэкап прод-.env сделан (`.env.bak-before-staging-*`), в .gitignore (IGNORED ok), прод .env цел (23 строки).
### Изоляция staging (КЛЮЧЕВОЕ — проверено лично, всё зелёное)
- **Реестр `ORCH_PROJECTS_JSON` = ТОЛЬКО sandbox** → `known_plane_project_ids()` = {8c5a3025...}, боевые ORCH(8da6aa25)/ET(7a79f0a9) = False → события по ним фильтр ORCH-6 режет в `ignored`. Staging физически не реагирует на боевые задачи.
- **БД физически раздельная**: volume `./data/staging``data/staging/orchestrator.db` (32KB свежая). Прод-БД не трогает.
- **Telegram пустой** (Слава: вариант 1, staging молчит) — ORCH_TELEGRAM_CHAT_ID="" и BOT_TOKEN="". Не спамит боевой канал.
- **ORCH_STAGING=true** пометка.
- Подъём: `sg docker -c "docker compose --profile staging up -d --build orchestrator-staging"`.
### Проверки выката (все ✅)
- staging 8501 /health=ok, /queue=ok (queued/running/done/failed=0, preflight_ok, Claude Code 2.1.142).
- прод 8500 /health=ok, контейнер Up 16h БЕЗ рестарта (не дёрнулся).
- реестр: sandbox=True, боевой ORCH=False, боевой ET=False.
### Важные технические факты (для след. этапов)
- **Gitea-webhook прод-репо `orchestrator`** жёстко шлёт на `http://localhost:8500/webhook/gitea`. Sandbox-репо `orchestrator-sandbox` пока БЕЗ хуков (настрою на 8501 в Этапе 3 при e2e).
- **Plane-webhooks через workspace API = 404** (Plane настраивает их через UI/инстанс plane-app-*, не через API). Прод получает Plane-события webhook'ом на 8500. Staging боевые Plane-события НЕ получит, пока ему отдельно не настроят webhook → плюс к безопасности.
- Орк роутеры: `/webhook/plane`, `/webhook/gitea` (main.py:92-93, prefix /webhook).
- 8500=прод (uvicorn pid живой), 8501=staging.
- `ORCH_REPOS_DIR` в .env=/home/slin/repos, но compose env-секция перебивает на /repos → внутри контейнера /repos (правильно).
- Образ staging: `orchestrator-orchestrator-staging:latest`, контейнер `orchestrator-staging`.
### Следующий шаг
Этап 3 (ORCH-33): тест-сьют staging — smoke + проверка доступов (Plane sandbox + Gitea sandbox реальными вызовами) + e2e (задача в SANDBOX → ветка в orchestrator-sandbox → статусы+комменты в Plane, верификация по API), режим full-real. Перед e2e: настроить Gitea-webhook sandbox-репо на localhost:8501. Это код для Dev (тест-скрипт) + моя инфра (webhook).
---
## Staging-среда orchestrator — Этапы 2-3 ВЫКАЧЕНЫ ✅ (05.06, утро)
### Этап 1 (ORCH-31) — закрыт
- **PR #28 смержен** в main, main HEAD `3b68a29` "Merge PR #28", коммит ORCH-31 `6c1e5ff` в main.
- ⚠️ Грабля мержа: заголовок авторизации Gitea при первом заходе пришёл как `***` (санитайзер) → HTTP 401 `token is required`. Фикс: явно `token <tok>` → HTTP 200 merged. Запомнить: при мерже через Gitea API проверять, что заголовок реально `token <значение>`, а не затёртый.
### Этап 2 (ORCH-32) — песочница создана + staging-контейнер ПОДНЯТ
- **Gitea-репо песочницы:** `admin/orchestrator-sandbox` (main, auto-init).
- **Plane-проект песочницы:** name "ORCH Sandbox" (Plane НЕ пускает дефис/спецсимволы в name → без дефиса), identifier `SANDBOX`, **project_id `8c5a3025-4f9d-4190-b79f-fa06276bb27e`**.
- **Токены — вариант 1 (решение Славы):** общие с продом, изоляция по проекту/репо + раздельная БД (НЕ отдельные токены).
- **Telegram staging — вариант 1 (решение Славы):** пустой/выключенный, staging молчит в телегу (смотрим по логам/API). Никакого спама в боевой канал.
- **`.env.staging` собран** на проде (`/home/slin/repos/orchestrator/.env.staging`, в .gitignore, НЕ коммитится): реестр `ORCH_PROJECTS_JSON` = ТОЛЬКО sandbox (боевые ET/ORCH → ignored фильтром ORCH-6), Telegram пустой, БД через volume, `ORCH_STAGING=true`. Прод `.env` (23 строки) цел, бэкап сделан.
- **Контейнер `orchestrator-staging` поднят на 8501** (`docker compose --profile staging up -d`), образ `orchestrator-orchestrator-staging:latest`. Проверено лично: `/health`=ok, `/queue`=ok (Claude Code 2.1.142 виден), прод `orchestrator` Up 16h БЕЗ рестарта.
- **Изоляция подтверждена:** staging знает ТОЛЬКО sandbox (`known_plane_project_ids()`={8c5a3025...}); боевые ORCH(8da6aa25)/ET(7a79f0a9) → False; БД физически раздельная `data/staging/orchestrator.db`.
### Webhook-изоляция (важная находка)
- **Gitea webhook прод-репо `orchestrator`** шлёт жёстко на `localhost:8500/webhook/gitea` (прод). Sandbox-репо пока БЕЗ хуков (правильно).
- **Plane webhooks через workspace API недоступны** (404) — настраиваются на уровне Plane-инстанса/UI (`plane-app-*` контейнеры). Прод-Plane шлёт на 8500. Staging боевые Plane-события НЕ получит, пока webhook в Plane не настроен на 8501.
- **Главный ключ изоляции:** `ORCH_PROJECTS_JSON` staging = только sandbox → даже если событие прилетит, всё не-sandbox → `ignored` (фильтр ORCH-6).
### Этап 3 (ORCH-33) — тест-сьют ГОТОВ, PR #29 (ждёт мержа)
- Dev написал `scripts/staging_check.py` (smoke A + доступы B + e2e C, exit-code, cleanup в finally) + `docs/STAGING_CHECK.md`. Ветка `feature/ORCH-33-staging-testsuite`. **PR #29 open.**
- **Проверено лично на проде: 10/10 PASS, exit 0.** Файлы только новые (src/tests/compose/.env не тронуты). Боевое НЕ задето (нет staging-check веток в orchestrator/enduro-trails, нет тест-задач в боевом ORCH). Песочница чиста после cleanup (sandbox-репо = только main, Plane SANDBOX = 0 задач). Прод 8500 жив.
- **Ключевое архитектурное знание (порядок старта конвейера):** при старте сначала resolve проекта → подтяг name/desc из Plane → QG-0 валидация → **создаётся work_item_id + ветка + начальные доки + строка задачи в БД** → ТОЛЬКО ПОТОМ enqueue аналитика (Claude CLI через launcher). Значит e2e проверяет РАННИЕ артефакты (ветка/доки) ДО запуска LLM — быстро, без расхода кредитов. Аналитика не ждём.
- **Режима заглушек агентов (гибрид C) в коде НЕТ** — но для e2e он и не нужен (проверяем раннюю стадию до LLM).
### Открытый нюанс (не блокер)
- Bot-токены агентов (`ORCH_PLANE_BOT_ANALYST` и пр.) НЕ добавлены членами в SANDBOX-проект → `add_comment` от их имени = 403. Dev заменил проверку «коммент в Plane» на надёжный ранний артефакт «analyst job в очереди». Чтобы закрыть полностью — добавить бот-аккаунты в SANDBOX через Plane API (моя инфра-работа, мелкая).
### Следующие шаги
1. Мерж PR #29 (Этап 3) — предложено + добавить ботов в SANDBOX.
2. **Этап 4 (ORCH-34):** хост-деплой-хук `orchestrator-deploy-hook.sh` (промоут staging→prod, health 10×6с=60с, auto-rollback PREV_IMG). Образец `/home/slin/bin/enduro-deploy-hook.sh`.
3. **Этап 5 (ORCH-35):** стадия `deploy-staging` перед `deploy-prod` в конвейере.
### Идентификаторы (Этап 2-3)
- Plane SANDBOX project_id: `8c5a3025-4f9d-4190-b79f-fa06276bb27e`, identifier `SANDBOX`
- Gitea sandbox-репо: `admin/orchestrator-sandbox`
- staging порт 8501, контейнер `orchestrator-staging`, профиль compose `staging`, образ `orchestrator-orchestrator-staging:latest`, БД `data/staging/orchestrator.db`, `.env.staging` (в .gitignore)
- main HEAD после Этапа 1: `3b68a29`; PR #28 merged, PR #29 open (Этап 3)
- ТЗ: `tasks/orchestrator/DEV_TASK_ORCH33_STAGING_TESTSUITE.md`; отчёт `tasks/orchestrator/reports/dev-2026-06-05-orch33-staging-testsuite.md`
---
## Этап 3 закрыт + боты в SANDBOX (05.06, продолжение)
### PR #29 смержен → Этап 3 в main
- **PR #29 merged** (HTTP 200, AUTH="token "+TOK — урок учтён). main HEAD `93169f1`, коммит сьюта `94334bd`.
### Нюанс с бот-комментами закрыт (Plane membership)
- **Корень 403 при `add_comment` бот-токеном:** бот-токен ВИДИТ проект (GET 200), но НЕ может постить комменты, пока его owner НЕ член проекта. Воспроизвела: бот POST comment=403, админ POST comment=201.
- **7 бот-аккаунтов Plane (workspace members):** Analyst `c925cbcd-a8dc-4506-978e-15354ce3ad31`, Developer `bfe59a48-a7cd-4ce1-a78b-83f8891a4aba`, Reviewer `9836a30d-1294-430d-8109-ceb3e784d1d8`, Tester `7cdfc9e7-c552-4fd1-b4a7-3b1f03e72751`, Architect `6d82b825-c8b2-447c-bca0-c4d34c6200ac`, Deployer `ebf17448-d544-465e-8b0e-57581f76507c`, Стрим `468040f8-f609-406a-84d2-a119880a5e8e`. (+ admin-токен owner = `mva154` daf4d3f4..., + системный `Plane` 43c79cc2...).
- **Identity бот-токена узнаётся через** `GET {PBASE}/users/me/` с `X-API-Key: <bot-token>` → возвращает id+display_name.
- **Добавление члена проекта Plane (РАБОЧИЙ формат):** `POST /workspaces/{slug}/projects/{pid}/members/` body `{"member": <user_id>, "role": 15}` ПООДИНОЧКЕ. ⚠️ Формат `{"members":[{...}]}` и `member_id` НЕ работают (400 "member: This field is required"). role 15 = member.
- **Все 7 ботов добавлены членами SANDBOX** (теперь 8 members). Верифицировано: Analyst и Developer боты постят комменты → HTTP 201. Нюанс Этапа 3 устранён.
### Дальше
Этап 4 (ORCH-34): хост-деплой-хук `orchestrator-deploy-hook.sh` (промоут staging→prod, health 10×6с=60с, auto-rollback по PREV_IMG). Образец `/home/slin/bin/enduro-deploy-hook.sh`.
---
## Этап 4 (ORCH-34) деплой-хук — ГОТОВО ✅ + чистка Plane (05.06, продолжение)
### Закрыты в Plane (Backlog → Done НАПРЯМУЮ, минуя In Progress)
- ✅ ORCH-30, ORCH-31, ORCH-32, ORCH-33 → Done (верифицированы).
- ⚠️ **Важная тонкость безопасности:** боевой webhook ORCH-проекта идёт на прод (8500). Переход задачи **В In Progress запустил бы конвейер** по ней! Поэтому выполненные задачи двигать **Backlog → Done напрямую, минуя In Progress**. Прод не дёрнулся.
- **State id Done** в проекте ORCH: `3738cd3c-7610-4907-ba5e-26b9a248d9c0`.
- ⚠️ **In Progress id ПЛАВАЕТ** — был `b873d9eb...` (в памяти), стал `e331bfb3...`. ВСЕГДА запрашивать states свежим API-вызовом, НЕ по памяти.
- ОстаютсяBacklog: ORCH-34 (закрою после мержа), ORCH-35 (не начат).
### Бот-аккаунты добавлены в SANDBOX (нюанс Этапа 3 закрыт)
- 403 при коммите бот-токеном был НЕ из-за доступа к проекту (GET 200 у всех 7 ботов), а из-за **членства**: чтобы постить комменты, владелец бот-токена должен быть **member** проекта.
- **Plane API формат добавления члена:** `POST /projects/<id>/members/` с телом `{"member": <user_id>, "role": 15}` — ПООДИНОЧКЕ (не массивом), поле `member` (НЕ `member_id`!), role 15 = member.
- Добавила всех 7 владельцев бот-токенов в SANDBOX → коммент бот-токеном теперь 201 (было 403). Проверено воспроизведением.
- user-id ботов узнаются через workspace-members API.
### Этап 4 — деплой-хук (проверено мной на проде, оба сценария)
- Dev: `scripts/orchestrator-deploy-hook.sh` (176 строк) + `docs/DEPLOY_HOOK.md`. Ветка `feature/ORCH-34-deploy-hook`, коммит `a6cbacb`. **PR #30 open.**
- **Happy-path ✅:** deploy → health ok за 1 попытку → exit 0.
- **Авто-rollback ✅ (главное):** Я сама подсунула битый образ (busybox `exit 1`, перетегла как staging-образ) → хук прождал 10×6с=60с (HTTP 000) → САМ откатился на PREV_IMG → рестарт → post-health 5×3с → поднялся → staging снова ok. **Реальный exit-code хука = 1** при фейле (проверила без пайпа `| tail`, который съедал rc).
- **Heredoc-грабля Dev:** при передаче скрипта через heredoc терялись кавычки в `grep`/`curl -w` → health давал «not ready» при HTTP 200. Фикс Dev: `cat > файл` из локального файла, не heredoc. ЗАПОМНИТЬ для будущих shell-скриптов через heredoc.
- **Прод цел:** StartedAt `2026-06-04T13:08:13Z` не менялся (Up 17h), 8500 ok. Файлы только новые, staging восстановлен, временные теги убраны.
- **Параметризация:** дефолт БЕЗОПАСНЫЙ (TARGET_SERVICE=orchestrator-staging, PORT=8501, profile staging). Прод поддержан через override env, но НЕ дефолт. Отдельный PREV_IMAGE_FILE для staging.
### Этап 5 (ORCH-35) — последний, ПЛАН (ещё не спущен Dev)
- Цель: встроить стадию **`deploy-staging` ПЕРЕД `deploy-prod`** в конвейер (`src/stages.py`), тестер привязать к staging-эндпоинту 8501.
- ⚠️ **Самый рискованный этап:** трогает боевой конвейер деплоя, часть `src/` в off-limits. Перед спуском Dev — ЖИВАЯ разведка по коду стадий (как устроены deploy-стадии, точки встройки), показать план Славе.
- Из дизайна §4/§7: промоут с **ручным approve на старте** (`DEPLOY_REQUIRE_MANUAL_APPROVE=true`) — хук тормозит после зелёного staging, ждёт «go» Славы. Полный авто — позже.
- Из дизайна §6: агенты на staging — **гибрид C** (заглушки по умолчанию + full-real по флагу). Режима заглушек в коде ПОКА НЕТ (выяснено на Этапе 3) — возможно, понадобится на Этапе 5 или отдельной задачей.
### Идентификаторы (обновление)
- main HEAD после Этапа 3 (PR #29 merged): `93169f1`
- PR #30 (Этап 4) — open, коммит `a6cbacb`
- Done state id (ORCH project): `3738cd3c-7610-4907-ba5e-26b9a248d9c0`
- ТЗ Этап 4: `tasks/orchestrator/DEV_TASK_ORCH34_DEPLOY_HOOK.md`; отчёт `tasks/orchestrator/reports/dev-2026-06-05-orch34-deploy-hook.md`
- Деплой-хук: `scripts/orchestrator-deploy-hook.sh`, образец enduro: `/home/slin/bin/enduro-deploy-hook.sh`
---
## ORCH-36 (Вариант B самодеплоя) заведён в Backlog + критерии «доверия к автоматике» (05.06)
### ORCH-36 создан в Plane Backlog
- **id `84a6c09d-7a03-4cb7-a58b-3d8963c565a5`**, seq 36, name "ORCH-36: Исполняемый самодеплой — стадия deploy дёргает хост-хук (Вариант B)".
- Суть: стадия `deploy` реально дёргает хост-хук `orchestrator-deploy-hook.sh` (ORCH-34) через ssh → промоут в прод (8500) с health+авто-rollback. На старте — ОБЯЗАТЕЛЬНЫЙ ручной approve (`DEPLOY_REQUIRE_MANUAL_APPROVE=true`). Делается ПОСЛЕ ORCH-35 (Вариант A — staging-гейт ворота).
- Слава: "позже вернёмся" → лежит в бэклоге детально описанной.
### «Доверие к автоматике» — ФОРМАЛЬНЫЕ критерии (для флага true→false)
Переход `DEPLOY_REQUIRE_MANUAL_APPROVE` true→false (manual approve → полный авто) — ТОЛЬКО когда ВСЕ 5 закрыты (метрики набираются в режиме ручного approve):
1. **≥10 успешных промоутов подряд** (staging зелёный → approve → прод поднялся, откат не нужен).
2. **Zero false-negative (критично):** staging-гейт НИ РАЗУ не пропустил битый деплой как «зелёный».
3. **Авто-rollback проверен в бою ≥2-3 раза:** recovery rate 100%, MTTR <60с.
4. **Ни одного «молчаливого» деплоя:** каждый промоут/откат → Plane + Telegram.
5. **Период наблюдения:** ≥10 деплоев ИЛИ ≥2 недели без инцидентов в manual-approve.
Когда 5/5 → осознанное переключение флага отдельным шагом.
### Этап 5 (ORCH-35) = Вариант A (решение по объёму ждёт Славу: только A или A+B)
- Вариант A: стадия `deploy-staging` МЕЖДУ testing и deploy, QG `check_staging_status` (образец `check_deploy_status`), deployer гоняет `staging_check.py` против 8501. Прод-деплой недостижим пока staging не зелёный. Off-limits: не ломать существующие QG/rollback.
- Полный план разведки — в `tasks/orchestrator/DESIGN_STAGING_ENV.md` (раздел "РАЗВЕДКА КОДА ДЛЯ ЭТАПА 5").
---
## Этап 5 (ORCH-35) — staging-гейт встроен ✅, проверено лично + найден архитектурный нюанс (05.06 ~07:30 UTC)
### Что сделано Dev (PR #31, ветка `feature/ORCH-35-staging-gate`, коммит `e0b6e92`, НЕ мержен)
Вставлена стадия `deploy-staging` МЕЖДУ `testing` и `deploy`. Новая цепочка: `testing → deploy-staging → deploy → done`.
- `src/stages.py``STAGE_TRANSITIONS`: `testing→deploy-staging` (agent=deployer, qg=check_tests_passed), `deploy-staging→deploy` (agent=deployer, qg=check_staging_status), `deploy→done` без изменений
- `src/qg/checks.py` — новый `check_staging_status` + `_parse_staging_status` (парсит `staging_status: SUCCESS|FAILED` из `15-staging-log.md`), зарегистрирован в `QG_CHECKS`
- `src/stage_engine.py` — rollback-ветка: FAILED на deploy-staging → откат на `development` (по образцу БАГ-8 deploy)
- `.openclaw/agents/deployer.md` — НОВЫЙ файл (в репо его не было), инструкция для обеих стадий deployer
- `tests/test_qg.py`, `tests/test_stage_engine.py` — обновлены + 18 новых staging-тестов
### Проверено МНОЙ лично на проде (не со слов Dev)
- **312 passed, 0 failed** — прогнала весь набор сама. Способ: прод-образ орка (там все зависимости) + примонтировала исходники ветки поверх → честный прогон в реальном окружении. (В прод-контейнере `tests/` нет — образ собран без них; чистый python-образ не имеет зависимостей — поэтому монтирование в прод-образ.)
- Цепочка вживую: `get_next_stage("testing")=="deploy-staging"`, `("deploy-staging")=="deploy"`, `("deploy")=="done"`; `get_qg_for_stage("deploy-staging")=="check_staging_status"`
- QG-логика вживую: SUCCESS→(True), FAILED→(False), missing→(False) ✓
- Rollback staging-провала → `development` (3 теста) ✓
- git diff: только код (`.openclaw/agents/deployer.md`, `src/qg/checks.py`, `src/stage_engine.py`, `src/stages.py`, `tests/*`). off-limits (.env/compose/staging_check.py/deploy-hook.sh) не тронуты. Прод 8500 не задет.
### ⚠️ АРХИТЕКТУРНЫЙ НЮАНС (раскопала сама, ЖДЁТ решения Славы перед мержем)
**Промпты агентов (`deployer.md` и пр.) живут В КАЖДОМ репозитории задач, а не в репо orchestrator.**
- `launcher.py` делает `cat {system_prompt}` ВНУТРИ `work_path` (= клон ЦЕЛЕВОГО репо задачи). Путь `.openclaw/agents/deployer.md`.
- **enduro-trails-репо** имеет полный набор промптов (analyst/architect/deployer/developer/reviewer/tester.md от 04.06), но deployer.md там СТАРЫЙ — про staging-гейт не знает.
- **orchestrator-репо** — Dev положил новый deployer.md с staging-инструкцией (правильно для self-hosting: орк деплоит сам себя, work_path=клон orchestrator).
**Проблема:** стадия `deploy-staging` ГЛОБАЛЬНАЯ (в STAGE_TRANSITIONS) → применяется ко ВСЕМ проектам конвейера. Но:
1. У enduro deployer-промпт не знает про staging → не напишет `15-staging-log.md` → гейт FAIL → enduro-задачи откатятся на `development` и застрянут
2. `staging_check.py --base-url localhost:8501` = staging ОРКА. У enduro своего staging нет. Гейт концептуально orchestrator-специфичный.
**Варианты (предложены Славе):**
- 🅰️ (моя рекомендация) `deploy-staging` УСЛОВНЫЙ — гейт только для self-hosting (проект orchestrator), для остальных стадия пропускается/пустой pass. Правильная инкапсуляция.
- 🅱️ оставить как есть + обновить enduro deployer.md + поднять enduro-staging (большой объём, выходит за рамки)
- 🅲️ заморозить мерж как known-issue (активных enduro-задач нет), мержить после A
**СТАТУС: жду решение Славы. PR #31 НЕ мержен. ORCH-35 НЕ закрыт.**
### Identifiers Этапа 5
- PR `#31` в Gitea (admin/orchestrator), ветка `feature/ORCH-35-staging-gate`, коммит `e0b6e92`, НЕ merged
- ORCH-35 issue id: `4ead9be7-e1bf-4a28-8c76-88bda1c1fc2c`
- Done state id: `3738cd3c-7610-4907-ba5e-26b9a248d9c0`
- Новый артефакт стадии: `docs/work-items/<wi>/15-staging-log.md`, машинное поле `staging_status:`
- Прогон тестов: образ прод-орка + монтирование исходников ветки → 312 passed
## Вариант B вынесен в ORCH-36 (Backlog) — исполняемый самодеплой
Создан ORCH-36 «Исполняемый самодеплой — стадия deploy дёргает хост-хук (Вариант B)» в Backlog с детальным описанием. Внутри зашиты 5 метрик «доверия к автоматике» для переключения флага manual approve → авто:
1. ≥10 успешных промоутов подряд (откат не понадобился)
2. Zero false-negative — staging-гейт ни разу не пропустил битый деплой (критично)
3. Авто-rollback в бою ≥2-3 раза (recovery 100%, MTTR <60с)
4. Ни одного «молчаливого» деплоя (каждый → Plane + Telegram)
5. Период ≥10 деплоев ИЛИ ≥2 недели без инцидентов
Связи: ORCH-7/21/34/35. Ждёт когда вернёмся.
---
## ORCH-35 ДОРАБОТКА — условный staging-гейт (Вариант А) ✅ проверено лично (05.06 ~07:40 UTC)
### Решение Славы: Вариант А — условный гейт
Гейт `deploy-staging` срабатывает реально ТОЛЬКО для self-hosting (проект orchestrator). Для остальных проектов (enduro-trails и пр.) — мгновенный зелёный pass, чтобы их задачи НЕ застряли на откате.
### Что сделал Dev (коммит `e0c14fa` в той же ветке `feature/ORCH-35-staging-gate`)
- `src/qg/checks.py:451-455``SELF_HOSTING_REPO = "orchestrator"` + `is_self_hosting_repo(repo)` (case-insensitive)
- `check_staging_status`: если repo НЕ self-hosting → сразу `(True, "Staging gate N/A for <repo>")`, файл `15-staging-log.md` даже не читается. Если orchestrator → реальная проверка как было.
- `STAGE_TRANSITIONS` НЕ трогали — стадия остаётся в цепочке для всех, условность зашита в QG.
- `tests/test_qg.py` — +7 новых тестов под условную логику
### Проверено МНОЙ лично на проде (прод-образ орка + примонтированы исходники ветки)
- **319 passed, 0 failed** (было 312, +7 новых)
- Условность вживую (через `docker cp` файла в контейнер, НЕ `-v` mount — volume-mount файла НЕ подхватывается, урок!):
- `check_staging_status("enduro-trails", ...)` → (True, "Staging gate N/A...") БЕЗ файла ✓
- `check_staging_status("orchestrator", ...)` без файла → (False) ✓, с `staging_status: SUCCESS` → (True) ✓
- repo приходит как plain gitea name (`ProjectConfig.repo` из реестра `projects.py`) — подтверждено, сравнение корректное
- Доработка тронула только `qg/checks.py` + `tests/test_qg.py`. git diff ветки показывает 6 файлов — это НАКОПЛЕННЫЙ diff всей ветки против main (первый коммит e0b6e92 + доработка e0c14fa), сама доработка stages.py НЕ меняла.
### projects.py (разведано, реестр проектов из ORCH-6 фикса 02.06)
Связывает Plane-проект uuid ↔ Gitea-репо ↔ префикс. `ProjectConfig` (frozen): plane_project_id, repo, work_item_prefix, name. Источник: env `ORCH_PROJECTS_JSON` → settings.projects_json, fallback `_DEFAULT_PROJECTS` (enduro-trails ET первый намеренно, orchestrator ORCH). Парсер устойчив (битый элемент скип, пусто→дефолт). Отсюда берётся способ отличить self-hosting (repo=="orchestrator").
### СТАТУС: ✅ СМЕРЖЕНО И ЗАКРЫТО (05.06 ~07:43 UTC)
- PR `#31` СМЕРЖЕН (merge commit `f1b3146`, merged=True/closed). main HEAD = `f1b3146`, под ним `e0c14fa` + `e0b6e92`.
- ORCH-35 переведён Backlog→Done напрямую (HTTP 200, state `3738cd3c`). Мимо In Progress — webhook не дёрнут.
- ORCH-35 id `4ead9be7-e1bf-4a28-8c76-88bda1c1fc2c`
### 🏁 СЕРИЯ САМОДЕПЛОЯ — ФИНАЛ
Все 5 этапов готовы и проверены лично:
- Этап 1 ORCH-31 ✅ Done (PR #28)
- Этап 2 ORCH-32 ✅ Done (песочница staging 8501)
- Этап 3 ORCH-33 ✅ Done (PR #29, staging_check.py)
- Этап 4 ORCH-34 ✅ Done (PR #30, deploy-hook.sh + авто-rollback)
- Этап 5 ORCH-35 ✅ DONE (PR #31 смержен `f1b3146`, условный staging-гейт, 319 тестов)
- Вариант B вынесен в ORCH-36 (Backlog) — исполняемый деплой, на потом
---
## ДОКУМЕНТАЦИЯ ОРКА = golden source в репо (задача Славы 05.06 ~08:30)
Слава хочет: вся дока по орку в репо (код+дока по единым канонам), чтобы мульти-агенты знали где дока, ИСПОЛЬЗОВАЛИ и АКТУАЛИЗИРОВАЛИ.
### КЛЮЧЕВОЙ ИНСАЙТ (подтверждён Славой): структура папок ≠ агенты её используют. Агент видит ТОЛЬКО свой system_prompt (`.openclaw/agents/<role>.md`) + task. Канон держится на 3 слоях.
### 3-слойный канон (согласован):
1. **Структура docs/**: README, ARCHITECTURE, PIPELINE, PRODUCT_VISION, adr/ (1 решение=1 файл adr-NNNN-slug.md), operations/, work-items/<id>/, history/ (архив), CHANGELOG, CONTRIBUTING, AGENTS.md
2. **Промпты агентов** (★): полный набор `.openclaw/agents/*.md` в репо орка по образцу enduro — жёстко: читай docs/, пиши work-items, архитектор ведёт ADR, каждый обновляет CHANGELOG. **Reviewer-gate**: если доку не обновили → REQUEST_CHANGES (канон держится автоматически)
3. **Канон процесса**: CONTRIBUTING.md + AGENTS.md в корне, на них ссылаются промпты
### ⚠️ ИНФРА-ИЗОЛЯЦИЯ (проверено по факту):
- **РИСК:** прод-орк (8500) — ОДИН инстанс на ВСЕ проекты (ET+ORCH), ОБЩАЯ БД `/app/data/orchestrator.db`, общая очередь. Self-доработка орка бежит в том же инстансе, что держит ET → рестарт/падение = групповой риск. Staging-гейт (ORCH-35) — страховка.
- **ХОРОШО:** staging (8501) полностью изолирован (свой ORCH_PROJECTS_JSON=только sandbox); репы раздельные (worktree ORCH-2)
- **Инфру ВЕДЁМ в репо:** `docs/operations/INFRA.md` (RUNBOOK). Секреты — ТОЛЬКО в .env хоста (.env.example канон). Уже есть: .env.example, .env.staging.example, compose, Dockerfile трекаются; .env НЕ в гите ✓
### ⚠️ ДЫРА у орка: в репо orchestrator `.openclaw/agents/` — ТОЛЬКО deployer.md! Нет analyst/architect/developer/reviewer/tester. У enduro — полный набор с дока-каноном. self-доработка орка упадёт без этих промптов.
### ЗАДАЧИ Plane:
- **ORCH-9** «Онбординг (turnkey)» — НАПОЛНИЛА детально (3-слойный канон + инфра + AC), id `c333bf6a-76dd-4214-aab2-61af4a8fbc58`, Backlog. Источник: `temp/orch9_desc.md`
- ORCH-11 «Полная дока мультиагентов» id `a396db3e-8618-491f-b62c-cc2bc490e502` (пустая)
- ORCH-24 «Персистентная БЗ» id `4c2009b3-3dad-456f-9f9e-1c1fa3d9dda6` (пустая)
### РЕШЕНИЯ Славы (финал по канону):
1. **Паспорт = per-repo `CLAUDE.md`** (НЕ AGENTS.md, НЕ единый на все). Изоляция репо/проектов — фича. Каждый проект — свой паспорт, точно описывает свой проект. Канон enduro: CLAUDE.md + docs/architecture/ (папка!) + adr/, артефакты 00-business-request..15-staging-log, 04-test-plan.YAML (не md!), per-wi ADR-NNN (upper) / global adr-NNNN (lower). НЕТ CONTRIBUTING.md — конвенции внутри CLAUDE.md.
2. INFRA.md остаётся как орк-специфика (у enduro аналога нет, но self-hosting риск реален).
3. Промпты агентов + reviewer-gate — СЕЙЧАС через Dev.
4. ORCH-9 — сформировать ПРИНЦИПЫ подготовки промптов (методичка), ET = пример-референс, НЕ генерить промпты под enduro.
### СДЕЛАНО:
- **Комплект доки** (8 файлов) написала САМА по канону enduro, выверено против кода (ДВА ревью: сначала нашла что выдумала свой канон ≡ AGENTS/CONTRIBUTING, потом переписала под enduro-канон). Архив: `temp/orch_docs_canon.tgz`, доставлен на slin `/tmp/orch_docs_canon.tgz`. Исходники: `temp/orch_docs/`.
- **Методичка ORCH-9** `tasks/orchestrator/ORCH9_PROMPT_PRINCIPLES.md` — принципы подготовки промптов (каркас, инварианты, роль-специфика, reviewer-gate, ET=референс). Ссылка добавлена в описание ORCH-9.
- **Dev запущен** (orch9_docs_canon, session eef3f0c0): ТЗ `DEV_TASK_ORCH9_DOCS_CANON.md` — заливка доки + реструктуризация docs/ (git mv в operations/, history/, ARCHITECTURE.md→architecture/internals.md) + промпты агентов (analyst..tester) + reviewer-gate. Ветка docs/ORCH-9-canon, PR не мержить.
### ПРОВЕРИТЬ после Dev (лично): структура docs/ по канону, полный набор .openclaw/agents/ (6 ролей), 0 битых ссылок, git mv сохранил историю, README цепочка актуальная, reviewer-gate в promptе, diff только docs/.openclaw (НЕ src/tests/compose).
🏁🏁🏁 СЕРИЯ САМОДЕПЛОЯ ПОЛНОСТЬЮ ЗАВЕРШЕНА 05.06.2026. Орк имеет staging-предохранитель: прод-деплой недостижим, пока staging-гейт не зелёный (для self-hosting). Следующий шаг когда вернёмся — ORCH-36 (исполняемый деплой) с 5 метриками доверия.
### ORCH-9 (часть 1) ЗАВЕРШЕНА Dev → ПРОВЕРЕНО МНОЙ ЛИЧНО на проде ✅ (PR #32, коммит `7c68d1d`, НЕ смержен)
Dev (session orch9_docs_canon) отработал, я проверила не со слов:
- **Структура канона:** `CLAUDE.md` (5543b, паспорт орка) + `CHANGELOG.md` в корне; мои маркеры целы (self-hosting, deploy-staging, 04-test-plan.yaml, ADR-NNN). `docs/` по канону enduro: `architecture/` (README + adr/ + internals.md), `operations/` (INFRA, DEPLOY_HOOK, STAGING, STAGING_CHECK, SETUP_WEBHOOKS), `history/` (8 архивных BUGFIXES/LESSONS/INCIDENT).
- **git mv сохранил историю** (R097/R100 в diff = renames, не пересоздание). Старый docs/ARCHITECTURE.md → docs/architecture/internals.md (глубина: схема БД SQL, resilience, потоки — сохранена).
- **Промпты агентов (6 ролей)** `.openclaw/agents/`: analyst, architect, developer, reviewer, tester, deployer. Все ссылаются на CLAUDE.md + docs/architecture/README.md. Модели верные (architect/reviewer→opus, остальные→sonnet, сверено с launcher.py AGENT_CONFIGS). architect ведёт ADR (per-wi 06-adr/ADR-NNN + сверка с global architecture/adr/). self-hosting раздел у architect/developer/deployer (не ронять прод-контейнер, ссылка INFRA).
- **Reviewer-gate:** reviewer.md содержит правило REQUEST_CHANGES при необновлённой доке (P0, через YAML verdict:, БЕЗ правки кода QG).
- **Чистота diff:** ТОЛЬКО docs/ + .openclaw/agents/ + README/CLAUDE/CHANGELOG. Код/тесты/compose/.env/scripts НЕ тронуты. ✅
- README + internals цепочка актуальна (deploy-staging).
### РАЗДЕЛЕНИЕ СКОПА (Слава, 05.06 Вариант Б): две РАЗНЫЕ задачи, НЕ мешать!
- **Орк-специфика (паспорт+промпты САМОГО орка+reviewer-gate)** = **self-hosting**, не ORCH-9. Остаётся в репо orchestrator, **PR #32 СМЕРЖЕН в main 05.06** (Слава дал «делай» → мерж через API): merge commit `5ecd1c4`, merged=True/closed. main HEAD = `5ecd1c4`. Методичка ОТКАЧЕНА из этой ветки (reset 7c68d1d, force-with-lease). Ветка docs/ORCH-9-canon HEAD = `7c68d1d` (только орк-канон).
- **Онбординг (ORCH-9)** = **ОТДЕЛЬНЫЙ РЕПО `onboard2orch`** (Слава: онбординг ≠ код орка, изоляция). Создан: https://git.mva154.duckdns.org/admin/onboard2orch (коммит `3b0ea44`). Структура: README.md, principles/PROMPT_PRINCIPLES.md, checklists/ONBOARDING_CHECKLIST.md, examples/enduro-trails/README.md (референс-указатели, НЕ копии). Описание ORCH-9 в Plane обновлено ссылкой на репо.
- Исходники onboard2orch: `temp/onboard2orch/`. Методичка-оригинал остаётся в `tasks/orchestrator/ORCH9_PROMPT_PRINCIPLES.md` (process-копия).
- ГЛАВНЫЙ УРОК: не мешать «про орк как проект» и «про онбординг любых проектов». Разные репо, разные задачи. Слава поймал моё смешение скопа.
### (устарело, было до разделения):
1. **PR #32 мержит Слава ВРУЧНУЮ** (правило: агентам push/merge в main запрещён). Если попросит «мержи» прямо — могу через API. Пока ждёт его ручного мержа.
2. **Методичку положила в репо**`docs/operations/ONBOARDING_PROMPTS.md` (коммит `23c7950`, в той же ветке docs/ORCH-9-canon → часть PR #32). Ветка теперь: 7c68d1d (канон+промпты) + 23c7950 (методичка).
- Ветка docs/ORCH-9-canon HEAD = `23c7950`, main = `f1b3146` (до мержа PR #32).
### Артефакты ORCH-9:
- ТЗ Dev: `tasks/orchestrator/DEV_TASK_ORCH9_DOCS_CANON.md`
- Методичка: `tasks/orchestrator/ORCH9_PROMPT_PRINCIPLES.md` (КАРКАС промпта + инварианты канона + роль-специфика + чеклист готовности; ET=референс, не шаблон)
- Комплект доки (исходники): `temp/orch_docs/` (CLAUDE.md, CHANGELOG.md, docs/architecture/README.md + adr/adr-0001..0003 + adr/README.md, docs/operations/INFRA.md)
- Архив доставки: `temp/orch_docs_canon.tgz` → slin `/tmp/orch_docs_canon.tgz`
- Отчёт Dev: `tasks/orchestrator/reports/dev-2026-06-05-orch9-docs-canon.md`
### ФАКТЫ ОРКА (золотой источник, для будущих сессий):
- НЕТ Makefile, НЕТ budget.yaml (в отличие от enduro). Тесты: `pytest tests/ -q` (из .gitea/workflows/ci.yml). CI = Gitea Actions.
- Прод 8500, staging 8501 (изолированная БД ./data/staging, profile staging, только sandbox-проект). External: https://openclaw.mva154.duckdns.org/orchestrator/. Webhook: .../orchestrator/webhook/gitea (+ /webhook/plane).
- Эндпоинты: GET /health, /status, /queue; POST /webhook/plane, /webhook/gitea (prefix /webhook + route).
- ADR-формат: per-work-item `docs/work-items/<id>/06-adr/ADR-NNN-slug.md` (UPPER, 3 цифры); сквозные `docs/architecture/adr/adr-NNNN-slug.md` (lower, 4 цифры). Индекс — adr/README.md.
- Канон артефактов: 00-business-request, 01-brd, 02-trz, 03-acceptance-criteria, 04-test-plan.YAML, 06-adr/, 07-infra-req, 08-data-req, 10-tech-risks, 12-review(verdict:), 13-test-report, 14-deploy-log(deploy_status:), 15-staging-log(staging_status:).
- main HEAD до PR #32 = `f1b3146` (merge ORCH-35).
### Эталон enduro для канона: `/home/slin/repos/enduro-trails/` — CLAUDE.md (паспорт), docs/architecture/ (README+adr), .openclaw/agents/*.md (6 ролей, эталон каркаса промпта: frontmatter→контекст→что прочесть→что произвести→принципы→запрещено→эскалация).