12 KiB
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. Шаги воспроизведения
- Иметь доступный Plane CE с валидным API-токеном (env
ORCH_PLANE_*). - Запустить онбординг нового (либо неполностью сконфигурированного) проекта:
python scripts/onboard_project.py apply --project <NAME> ...(любой путь, доходящий до секции «2. Plane: статусы», строки ~760-779scripts/onboard_project.py). - Факт: в отчёте каждый отсутствующий статус —
plane.state:STOP … ERROR(и аналогично для прочих), причина —Client error '400 Bad Request'отPOST …/projects/<id>/states/. - Ожидание: статус создаётся, шаг —
CREATED;POST …/states/возвращает200/201.
Детерминированный (без сети) повтор для CI — на уровне формируемого тела запроса: тело, которое
create_stateпередаёт в_post, не содержит ключаcolor(см. §3). Это и есть корневой наблюдаемый дефект, проверяемый регресс-тестом (04-test-plan.yaml).
3. Локализация
| Что | Где |
|---|---|
| Дефектный метод | scripts/onboard_project.py → PlaneClient.create_state (строки 424-428) |
| Дефектная строка | тело POST: {"name": name, "group": group} — отсутствует поле color |
| Точка отправки | PlaneClient._post (строки 382-389): 200/201 → ок; 401/403/404/405/501 → ManualStep; прочее (включая 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-1 —
onboard_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.