Files
orchestrator/docs/work-items/ORCH-048/01-brd.md
claude-bot 8b5b1f0056
All checks were successful
CI / test (push) Successful in 13s
CI / test (pull_request) Successful in 13s
analyst(ET): auto-commit from analyst run_id=145
2026-06-06 05:06:33 +00:00

7.6 KiB
Raw Blame History

01 — Business Requirements Document (BRD)

Work Item: ORCH-048 Title: staging B6 check reads registry from host worktree, not staging container Stage: analysis Author: analyst Date: 2026-06-06


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

scripts/staging_check.py — suite живых проверок staging-стенда orchestrator (порт 8501, ADR-0003). Деплоер запускает его на стадии deploy-staging и пишет staging_status: в 15-staging-log.md. FAIL любого чека = откат на development.

Блок B содержит проверку B6 «Registry: sandbox present, prod ET/ORCH absent» — она должна подтверждать, что в staging-реестре проектов есть только sandbox-проект и НЕТ боевых проектов (enduro-trails / orchestrator). Это страховка изоляции: staging не должен обслуживать прод-проекты.

B6 даёт ложный FAIL (prod-ET=YES(BAD!), prod-ORCH=YES(BAD!)), хотя сама изоляция реестра в staging РАБОТАЕТ корректно.

Root cause (подтверждён прямым запуском, Стрим, 06.06)

  • Внутри контейнера orchestrator-staging known_plane_project_ids() корректно отдаёт count=1, sandbox=True, ET=False, ORCH=False. .env.staging верно задаёт ORCH_PROJECTS_JSON = только sandbox. Изоляция реестра исправна.
  • Все остальные чеки (A1A3, B4, B5, блок C E2E) обращаются к работающему staging-инстансу по HTTP и зелёные.
  • B6 — единственный чек, который не ходит по HTTP, а импортирует Python-код локально. В блоке B6 (строки ~263284) выполняется:
    sys.path.insert(0, "/repos/orchestrator")        # ХОСТ-worktree
    importlib.reload(sys.modules["src.projects"])    # подхватывает env ТЕКУЩЕГО процесса
    from src.projects import known_plane_project_ids
    
  • Деплоер по факту запускает скрипт с хоста (.openclaw/agents/deployer.md: python3 scripts/staging_check.py --base-url http://localhost:8501). В env хост-процесса ORCH_PROJECTS_JSON НЕ задан → src.projects грузит встроенный _DEFAULT_PROJECTS (ET + ORCH) → known_plane_project_ids() возвращает боевые id → ложный FAIL.
  • Иными словами, B6 проверяет реестр НЕ того окружения, реестр которого реально использует staging-инстанс. Гипотеза деплоера про misconfig staging-контейнера — опровергнута.

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

B6 должен достоверно отражать реестр проектов именно работающего staging-инстанса (изолированное окружение), а не реестр, восстановленный из локального импорта в произвольном process-env. При этом B6 обязан по-прежнему ловить реальное нарушение изоляции.

3. Заинтересованные стороны

Роль Интерес
Deployer-агент Достоверный сигнал staging-гейта; нет ложных откатов на development
Owner / прод Изоляция staging от прод-проектов реально проверяется (не ложно-зелёная и не ложно-красная)
Self-hosting pipeline deploy-staging — обязательная страховка перед прод-деплоем орка; ложный FAIL блокирует доставку всех ORCH-задач

4. Объём (Scope)

В объёме

  • Исправление блока B6 в scripts/staging_check.py, чтобы он читал реестр в окружении staging-инстанса.
  • Тест на корректность B6: оба исхода (PASS при чистой изоляции; FAIL при попадании прод-проекта в staging-реестр).
  • Обновление документации B6 (docs/operations/STAGING_CHECK.md, при необходимости docs/architecture/README.md/CHANGELOG) в том же PR.

Вне объёма (НЕ ТРОГАТЬ)

  • src/projects.py — реестр работает корректно.
  • .env / .env.staging — конфигурация верна.
  • Прод-логика оркестратора.
  • Остальные staging-чеки B1B5 и блок C E2E — зелёные.

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

ID Требование
BR-1 B6 на staging даёт PASS (sandbox=YES, prod-ET=NO, prod-ORCH=NO), читая реестр из окружения staging-инстанса, а не из локального импорта хост-worktree.
BR-2 B6 по-прежнему детектирует реальное нарушение изоляции: если бы прод-проект реально попал в staging-реестр, B6 обязан выдать FAIL.
BR-3 Остальные staging-чеки не сломаны; src/projects.py и .env* не изменяются.
BR-4 Существующие unit-тесты остаются зелёными (pytest tests/ -q).
BR-5 Документация B6 обновлена в том же PR (golden source).

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

  • Решение должно быть минимально инвазивным и не затрагивать прод-логику.
  • Скрипт scripts/staging_check.py использует только stdlib (нет requests/httpx) — это конвенция файла, её нужно сохранить.
  • Способ запуска suite может варьироваться (с хоста / docker exec внутри контейнера) — выбранное решение должно быть корректным для канонического способа запуска деплоером и задокументировано.

7. Критерий успеха (бизнес)

  • staging-прогон scripts/staging_check.pyB6 PASS при работающей изоляции.
  • При искусственно нарушенной изоляции → B6 FAIL (проверяется тестом, без реального изменения staging).
  • python -m pytest tests/ -q — зелёный.

8. Открытые вопросы (для архитектора)

Бизнес-запрос предлагает три варианта реализации (выбор за архитектором, см. 02-trz §4):

  • (а) B6 читает реестр через HTTP-эндпоинт staging-инстанса;
  • (б) B6 выполняет проверку через subprocess в окружении staging-контейнера (docker exec);
  • (в) staging_check запускается ВНУТРИ staging-контейнера и читает собственный process-env (убрать host-path хак).

Предпочтение бизнес-запроса: минимально инвазивный вариант, не трогающий прод-логику.