auto-sync: 2026-06-05 08:50:01

This commit is contained in:
Stream
2026-06-05 08:50:01 +03:00
parent c8317e9c1d
commit af8dbcab18

View File

@@ -0,0 +1,65 @@
# DEV TASK — ORCH-33: тест-сьют для staging-стенда (smoke + доступы + e2e)
**Проект:** orchestrator | **Сервер:** slin@82.22.50.71 (pw motoZ@yaz2010) | **Репо:** /home/slin/repos/orchestrator | **Контейнеры:** orchestrator (прод 8500), orchestrator-staging (8501)
**Ветка:** создать `feature/ORCH-33-staging-testsuite` из свежего origin/main. `git fetch origin && git checkout main && git pull --ff-only && git checkout -b feature/ORCH-33-staging-testsuite`.
**Этап:** 3 из 5 (после Этапов 1-2: staging-контейнер ПОДНЯТ и живой на 8501, песочница готова).
## ЦЕЛЬ
Написать **самостоятельный скрипт-сьют** `scripts/staging_check.py` (+ docs), который проверяет, что живой staging-стенд реально работоспособен. НЕ unit-тесты (они уже есть в tests/), а **проверка живого стенда** через HTTP/API. Запускается вручную/из деплой-хука против работающего staging на 8501.
## ОКРУЖЕНИЕ (факты, проверены на проде 05.06)
- **staging:** http://localhost:8501 — `/health` -> `{"status":"ok","service":"orchestrator"}`, `/queue` -> JSON со счётчиками. Контейнер `orchestrator-staging`, образ `orchestrator-orchestrator-staging:latest`.
- **Песочница Plane:** проект "ORCH Sandbox", identifier `SANDBOX`, **project_id `8c5a3025-4f9d-4190-b79f-fa06276bb27e`**.
- **Песочница Gitea:** репо `admin/orchestrator-sandbox` (main, auto-init).
- **Реестр staging:** `ORCH_PROJECTS_JSON` содержит ТОЛЬКО sandbox → `known_plane_project_ids()` = {8c5a3025...}. Боевые ET/ORCH staging НЕ видит (фильтр ORCH-6 режет в ignored).
- **Токены (внутри контейнера orchestrator-staging, через env):** `ORCH_PLANE_API_TOKEN`, `ORCH_PLANE_WORKSPACE_SLUG` (=ag_proj), `ORCH_PLANE_API_URL` (=http://localhost:8091, код добавляет /api/v1), `ORCH_GITEA_TOKEN`, `ORCH_GITEA_URL` (=http://localhost:3000). Plane-заголовок `X-API-Key`, Gitea-заголовок `Authorization: token <tok>`.
- ⚠️ Plane API URL БЕЗ /api/v1 в env — суффикс добавляет КОД. Если дёргаешь Plane напрямую — добавь /api/v1 сам, иначе Plane вернёт HTML(200) вместо JSON.
## ЧТО ДОЛЖЕН ДЕЛАТЬ `scripts/staging_check.py`
Скрипт принимает базовый URL staging (дефолт http://localhost:8501) и режим. Запускается ВНУТРИ контейнера orchestrator-staging (там есть токены и сетевой доступ к localhost:8091/3000) ИЛИ умеет читать токены из env. Структура — три блока, каждый печатает PASS/FAIL и в конце общий итог + exit code (0 = всё PASS, !=0 = есть FAIL):
### Блок A — SMOKE (быстрый, без побочных эффектов)
1. `GET /health` -> 200 и `status==ok`.
2. `GET /queue` -> 200, есть ключи counts/max_concurrency/resilience.
3. Проверка, что это ИМЕННО staging: `ORCH_STAGING==true` в env контейнера (или эндпоинт, если есть). Если падает прод-URL по ошибке — НЕ продолжать деструктив.
### Блок B — ДОСТУПЫ (реальные вызовы в песочницу, read-only)
4. Plane: `GET {PLANE}/api/v1/workspaces/{slug}/projects/` своим токеном -> 200, среди проектов есть id `8c5a3025-...` (sandbox доступен).
5. Gitea: `GET {GITEA}/api/v1/repos/admin/orchestrator-sandbox` своим токеном -> 200 (sandbox-репо доступен на запись — проверить `permissions.push==true`).
6. Реестр: внутри контейнера `from src.projects import known_plane_project_ids` -> содержит sandbox и НЕ содержит боевые ET(7a79f0a9)/ORCH(8da6aa25). (Гарантия изоляции.)
### Блок C — E2E (реальный прогон в песочнице, побочные эффекты ТОЛЬКО в sandbox)
⚠️ **ВАЖНО — разведано на проде 05.06, РЕЖИМА ЗАГЛУШЕК АГЕНТОВ В КОДЕ НЕТ** (гибрид C из дизайна ещё не реализован). НО он и НЕ НУЖЕН для e2e. Порядок `start_pipeline` (разведан по коду): resolve проекта → подтяг name/desc из Plane API → **QG-0** валидация (жёсткий гейт!) → **создание work_item_id + ветки + начальных доков + строки задачи** → ПОТОМ enqueue аналитика (вот тут Claude CLI).
**Ключ e2e:** ветка+доки+коммент QG-0 создаются ДО запуска LLM. Проверяем ИМЕННО эти ранние артефакты, АНАЛИТИКА НЕ ЖДЁМ и НЕ ВЫЗЫВАЕМ (он встанет в очередь — это ок, не проблема). Так e2e быстрый и детерминированный, без расхода LLM-кредитов.
Шаги:
7. Создать тестовую задачу в Plane-проекте SANDBOX через API. ⚠️ QG-0 жёсткий: name ≥ 3 символов И description ≥ 20 символов — иначе конвейер упрётся в QG-0 fail и ветку НЕ создаст. Дай задаче НОРМАЛЬНЫЙ заголовок (`[staging-check] e2e <ts>`) И description ≥ 20 символов.
8. Триггер конвейера = переход В In Progress. Webhook Plane→staging НЕ настроен → самый детерминированный путь: **прямой POST на staging `http://localhost:8501/webhook/plane`** с корректным payload (issue updated, new state = In Progress, project=8c5a3025...) + подпись HMAC (см. ниже). Структуру payload и имя state-поля сверь с `src/webhooks/plane.py` (handle_status_start, PLANE_STATES) и с эталонным тестом `tests/test_webhooks.py::test_plane_webhook_creates_task`.
9. Поллить с таймаутом (~30-60с) и проверить по факту через API:
- в Gitea `orchestrator-sandbox` появилась ветка под задачу (GET .../branches);
- в Plane-задаче появился коммент от орка (GET issue comments) — напр. QG-0 или «ветка создана»;
- (опц.) строка задачи появилась в staging-БД (можно через `/queue` или SQL в data/staging/orchestrator.db).
10. **CLEANUP (try/finally, ВСЕГДА):** удалить созданную ветку в sandbox-репо + закрыть/удалить тест-задачу в SANDBOX, чтобы песочница не засорялась. Отработать даже если e2e упал.
**режимы:** поддержи `--mode stub|full-real` ради будущего, НО понимай: сейчас стуб-режима агентов НЕТ, поэтому stub-прогон просто НЕ ЖДЁТ аналитика (проверяет ранние артефакты: ветка/доки/коммент). full-real — дополнительно дожидается реального Claude CLI (длинный, расход кредитов), НЕ дефолт. Если stub-режим требует реального изменения src (чтобы не дёргался LLM) — СТОП, отчёт (src править нельзя, это отдельная задача).
## HMAC-секрет для блока C (если webhook на staging требует подпись)
- staging `.env.staging` копирует `ORCH_PLANE_WEBHOOK_SECRET` из прода. Если он непустой — твой запрос на `/webhook/plane` должен нести валидную подпись. Прочитай реальный секрет из env контейнера staging и сформируй подпись тем же алгоритмом, что использует код (`src/webhooks/plane.py` — посмотри как проверяет). НЕ хардкодь секрет в скрипт — читай из env в рантайме.
- Если проще и надёжнее — создавай задачу и меняй статус ЧЕРЕЗ Plane API (тогда настоящий Plane сам пошлёт webhook... но только если webhook в Plane настроен на 8501 — а он пока НЕ настроен). Поэтому самый детерминированный путь для блока C: **прямой POST на staging `/webhook/plane`** с корректным payload + подпись. Документируй выбранный путь.
## ⛔ OFF-LIMITS / ПРАВИЛА
- НЕ трогать src/ (логику орка), tests/ (unit), docker-compose.yml, .env, .env.staging. Только НОВЫЕ файлы: `scripts/staging_check.py` + `docs/STAGING_CHECK.md` (как запускать). Если для работы нужен крошечный helper — клади в scripts/.
- E2E пишет ТОЛЬКО в песочницу (SANDBOX-проект + orchestrator-sandbox-репо). НИКОГДА в боевые ET/ORCH/enduro-trails/orchestrator. Если код может задеть боевое — СТОП, отчёт.
- НЕ дёргать прод (8500). Все вызовы — на 8501 и в sandbox-сущности.
- НЕ регистрировать раннеров, НЕ nohup. Раннер mva154-runner-orch уже есть.
- PR push в main ЗАПРЕЩЁН. НЕ мержить — только коммит в ветку + PR.
- Если факт разошёлся с ТЗ (эндпоинт другой, нет нужного API, конвейер в stub не доходит до ветки) — СТОП, отчёт с вопросом, НЕ угадывать и не продавливать.
## ПРОВЕРКА (обязательный пруф в отчёт)
1. Запустить сьют против ЖИВОГО staging: `docker exec orchestrator-staging python3 /repos/orchestrator/scripts/staging_check.py --mode stub` (или как удобнее запускать — задокументируй). Приложи ВЕСЬ вывод: блок A/B/C, PASS/FAIL по каждому пункту, итог, exit code.
2. Доказать, что после прогона песочница почищена (ветка удалена) и БОЕВЫЕ проекты/репо НЕ затронуты (нет новых веток в orchestrator/enduro-trails, нет задач в боевом ORCH).
3. Прод 8500 `/health` = ok (не пострадал).
4. `git log --oneline origin/main..origin/feature/ORCH-33-staging-testsuite` — коммит ВИДЕН (после push, до отчёта «PR готов»).
## РЕЗУЛЬТАТ
Новые файлы: `scripts/staging_check.py` (smoke+доступы+e2e, exit-code, cleanup в finally, --mode stub|full-real) + `docs/STAGING_CHECK.md`. Прогон против живого staging зелёный (или честный отчёт где затык). PR в Gitea. Отчёт → `tasks/orchestrator/reports/dev-2026-06-05-orch33-staging-testsuite.md`. Коммит: `feat(staging): add live staging check suite (smoke + access + e2e)`.