Files
orchestrator/docs/work-items/ORCH-106/01-brd.md
claude-bot fe0dbea97e
All checks were successful
CI / test (push) Successful in 58s
analyst(ET): auto-commit from analyst run_id=652
2026-06-12 08:30:45 +03:00

12 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used, track, escalate
work_item stage author_agent status created_at model_used track escalate
ORCH-106 analysis analyst ready-for-review 2026-06-12 claude-opus-4-8 bug none

01 — Bug-report (облегчённый BRD): ORCH-106 — Fix onboard_project.py: add color field for state creation

Work Item: ORCH-106 · Repo: orchestrator · Стадия: analysis · Трек: 🐞 Bug (укороченный маршрут, ORCH-019)

Багфикс-трек: стадия architecture пропускается. Это облегчённый пакет (короткий bug-report + обязательный план регресс-теста), но все 4 файла analysis присутствуют (гейт check_analysis_complete не меняется). Эскалация в полный цикл — не требуется (см. §8).


1. Симптом

CLI онбординга scripts/onboard_project.py (режим apply) не может создать статусы Plane для нового проекта. На каждом статусе, отсутствующем в проекте (в том числе STOP), шаг plane.state:<name> падает с исходом ERROR: запрос POST .../states/ к Plane CE возвращает HTTP 400.

Практический эффект: turnkey-онбординг (ORCH-009) и Bundled-bootstrap (ORCH-103, onboard_project.py apply+verify) не доводят доску до 22 статусов автоматически — оператор вынужден создавать статусы вручную (теряется ключевое обещание «один проход»). Без статусов группы cancelled (STOP, ORCH-090) и Confirm Deploy (ORCH-059) затронутый проект остаётся без fail-closed-кнопок отмены/подтверждения деплоя.

2. Шаги воспроизведения

  1. Иметь доступный Plane CE с валидным API-токеном (env ORCH_PLANE_*).
  2. Запустить онбординг нового (либо неполностью сконфигурированного) проекта: python scripts/onboard_project.py apply --project <NAME> ... (любой путь, доходящий до секции «2. Plane: статусы», строки ~760-779 scripts/onboard_project.py).
  3. Факт: в отчёте каждый отсутствующий статус — plane.state:STOP … ERROR (и аналогично для прочих), причина — Client error '400 Bad Request' от POST …/projects/<id>/states/.
  4. Ожидание: статус создаётся, шаг — CREATED; POST …/states/ возвращает 200/201.

Детерминированный (без сети) повтор для CI — на уровне формируемого тела запроса: тело, которое create_state передаёт в _post, не содержит ключа color (см. §3). Это и есть корневой наблюдаемый дефект, проверяемый регресс-тестом (04-test-plan.yaml).

3. Локализация

Что Где
Дефектный метод scripts/onboard_project.pyPlaneClient.create_state (строки 424-428)
Дефектная строка тело POST: {"name": name, "group": group}отсутствует поле color
Точка отправки PlaneClient._post (строки 382-389): 200/201 → ок; 401/403/404/405/501ManualStep; прочее (включая 400) → resp.raise_for_status() → исключение
Точка проявления секция «2. Plane: статусы», цикл по _PLANE_NAME_TO_KEY (строки 767-779): исключение ловится except Exception → report.add(..., ERROR, str(e))
Таблица групп (контекст) STATE_GROUPS (строки 81-104) — имена→группы, в т.ч. STOP→cancelled

4. Причина (root cause)

Эндпоинт создания статуса в Plane CE (POST /workspaces/<ws>/projects/<id>/states/) требует непустое поле color (валидный hex-цвет) в теле запроса. create_state его не отправляет → серверная валидация отклоняет запрос с HTTP 400. Поскольку _post не относит 400 к «ручным» статусам (401/403/404/405/501), срабатывает raise_for_status(), исключение поднимается в цикл онбординга и фиксируется как ERROR.

Сопутствующий факт: соседний create_label (строки 430-434) и create_project (418-422) работают, т.к. их CE-эндпоинты не требуют color; проблема локальна для создания статусов.

5. Направление исправления (требование, не реализация)

Тело запроса, формируемое create_state, должно содержать валидное непустое поле color (hex-строка, принимаемая Plane CE), чтобы POST …/states/ возвращал 200/201 и статус создавался. Конкретный способ (единый дефолт-цвет на все статусы либо палитра по группам/именам) и значение цвета — решает developer (для багфикс-трека architecture пропущена; это точечная правда тела запроса, не архитектурное решение).

⚠️ Зона аналитика — требование и его проверяемость, не выбор реализации. Минимально достаточно: любой валидный hex-цвет, единый или пер-статусный.

6. Объём (scope)

В объёме

  • Добавить валидное поле color в тело POST, формируемое PlaneClient.create_state (scripts/onboard_project.py).
  • Обязательный регресс-тест: тело create_state несёт непустой валидный color (red до фикса, green после) — см. 04-test-plan.yaml.

Вне объёма

  • Изменение публичной сигнатуры create_state(project_id, name, group) (color добавляется внутри тела, не как новый обязательный аргумент) — чтобы не ломать call-site (строка 773) и существующие тесты/моки.
  • Любые правки рантайма src/**, STAGE_TRANSITIONS, QG_CHECKS, check_*, схемы БД, compose, Dockerfile.
  • Цвета/палитра статусов как «дизайн» — не задача; нужен лишь валидный для CE цвет.
  • Поведение create_label/create_project — не трогается.

7. Заинтересованные стороны / влияние

  • Заказчик: оператор платформы, разворачивающий новый проект (ORCH-009 turnkey, ORCH-103 Bundled). Боль — ручное досоздание 22 статусов, обещание «один проход» нарушено.
  • Затронуто: scripts/onboard_project.py (CLI вне рантайма), runbook'и онбординга/тиража (ссылаются на apply+verify). Действующий прод-конвейер и проект enduro-trails не затронуты (скрипт — операторский, активируется только явным запуском).
  • Принимает результат: reviewer/tester по критериям 03 и плану 04.

8. Решение по треку (bug-track, ORCH-019)

Баг простой и точечный: правка тела запроса одного метода (create_state), без ADR, без макетов, без затрагивания рантайма/гейтов. → Остаётся на облегчённом багфикс-треке, стадия architecture пропускается. escalate: none — эскалация в полный цикл (POST /bug-fast-track/escalate) не требуется.

9. Бизнес-требования (BR)

  • BR-1onboard_project.py apply создаёт статусы Plane без ошибки 400: тело POST …/states/ содержит валидное непустое поле color.
  • BR-2 — Сценарий из описания задачи воспроизводится зелёным: создание статуса с именем STOP и цветом возвращает 200/201 (на живом Plane CE) / тело несёт color (детерминированно в CI).
  • BR-3Все статусы онбординга (весь _PLANE_NAME_TO_KEY, включая STOP) создаются единообразно с непустым color.

10. Нефункциональные требования (NFR)

  • NFR-1 (совместимость) — публичная сигнатура create_state(project_id, name, group) и call-site (строка 773) не меняются; существующие онбординг-тесты (tests/test_onboarding_script.py и пр.) остаются зелёными.
  • NFR-2 (изоляция рантайма) — правка только в операторском CLI scripts/onboard_project.py (+ тест); src/**/STAGE_TRANSITIONS/QG_CHECKS/схема БД/compose — байт-в-байт. Self-hosting безопасно: скрипт не деплоит/не рестартит прод/не трогает main.
  • NFR-3 (валидность цвета) — отправляемый color — валидная hex-строка, принимаемая Plane CE (не пустая, не null).
  • NFR-4 (полный регресс зелёный)pytest tests/ -q остаётся зелёным.

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

  • Plane CE требует именно color (hex); поле обязательно и непустое — установленный факт из описания задачи и наблюдаемого 400.
  • Живая проверка 200 против реального Plane CE — ручной шаг приёмки (CI работает на уровне тела запроса, без сети — детерминированность).
  • Точное значение/палитра цвета — на усмотрение developer; аналитик фиксирует лишь «валидный непустой hex».

12. Критерии успеха

Резюме: после фикса онбординг создаёт все статусы (включая STOP) без 400; регресс-тест на наличие валидного color в теле create_state зелёный; существующий набор тестов не сломан. Детальные PASS/FAIL — 03-acceptance-criteria.md.