Files
wiki/tasks/orchestrator/DEV_TASK_APPROVED_ADVANCE.md
2026-06-03 23:30:01 +03:00

6.4 KiB
Raw Permalink Blame History

DEV TASK — БАГ 4: Approved из analysis НЕ двигает конвейер на architecture

Проект: orchestrator | Сервер: slin@82.22.50.71 | Репо: /home/slin/repos/orchestrator | Контейнер: orchestrator (8500) Ветка: fix/approved-advances-stage из свежего main (git checkout main && git pull && git checkout -b fix/approved-advances-stage). main = b01643f (PR #14).

⚠️ ГРАБЛЯ push (ORCH-7): после push git log origin/main..origin/fix/approved-advances-stage ДОЛЖЕН показать коммит ДО отчёта «PR готов». Токен Gitea: docker exec orchestrator printenv ORCH_GITEA_TOKEN.

Симптом (боевой, воспроизведён)

Слава перевёл #6 (task 29) в статус Approved из analysis. Лог: Task 29: Approved status -> advance from analysis → сразу 200 OK. Но: task 29 остался stage=analysis, нового job на architect НЕ создалось, статус в Plane не уехал в Architecture. Конвейер встал на первой стадии. Это блокер — ручной Approved не продвигает.

Корень

src/stage_engine.py, advance_stage() (~стр.191-197):

if qg_name and qg_name in QG_CHECKS:
    if qg_name == "check_analysis_approved":
        _handle_analysis_approved_flow(task_id, current_stage, repo, work_item_id, branch, agent, result)
        return result        # ← ВСЕГДА ранний return, блок Advance (стр.~228+) недостижим

_handle_analysis_approved_flow (стр.312) в начале:

if not (agent == "analyst" and work_item_id):
    return        # webhook Approved: agent=None → выходит, НИЧЕГО не делает

Два пути через один гейт, оба упираются в ранний return result:

  • Launcher (analyst закончил, finished_agent="analyst") → ставит In Review + коммент. Правильно, НЕ ломать.
  • Webhook Approved-вердикт (finished_agent=None, зовётся из _try_advance_stage в plane.py) → _handle_analysis_approved_flow делает return (agent≠analyst) → блок Advance (update_task_stage(next_stage) + enqueue_job(architect)) НИКОГДА не достигается.

finished_agent УЖЕ различает пути (launcher='analyst', webhook=None) — фикс на этом и строим.

Фикс — развести ветку check_analysis_approved по agent

src/stage_engine.py, advance_stage, ветка if qg_name == "check_analysis_approved": (~стр.193):

if qg_name == "check_analysis_approved":
    # Launcher path (analyst just finished): set In Review + ask for Approved.
    # This gate never advances on its own — a human Approved does that.
    if agent == "analyst":
        _handle_analysis_approved_flow(task_id, current_stage, repo, work_item_id, branch, agent, result)
        return result
    # Webhook Approved-verdict path (agent is None): the human approved -> the
    # analysis gate is satisfied. Skip the approval-flow and fall through to the
    # generic Advance block below (advance stage + enqueue next agent).
    # (do NOT return here)

Т.е. при agent is None (Approved-вердикт) — НЕ заходим в approved-flow и НЕ делаем ранний return, а проваливаемся в общий блок Advance (стр.~228): update_task_stage(task_id, next_stage)plane_notify_stageenqueue_job(architect).

⚠️ Проверь блок Advance: next_agent = get_agent_for_stage(current_stage) (стр.~240) — для analysis вернёт architect (по STAGES["analysis"]["agent"]? сверь: в stages.py "analysis": {"next":"architecture","agent":"architect",...}get_agent_for_stage("analysis") должно вернуть architect). Если вернёт analyst (повторный запуск!) — это вторая бага, останови и сообщи ДО фикса. По коду ORCH-4 fix комментарий «current_stage, not next» — значит agent берётся для СТАДИИ, которую покидаем; убедись что для analysis это architect, не analyst.

Ограничения

  • 🚫 НЕ ломай launcher-путь (agent="analyst" → In Review + коммент остаётся как есть).
  • 🚫 НЕ трогай: остальные QG (check_ci_green/check_tests_local/check_review_approved), rollback-ветки, Rejected-логику, Needs Input, nginx/openclaw.json/.env/deploy/HMAC/очередь(кроме enqueue)/webhook URL Plane/PLANE_STATES/M-6/uniqueness-guard/status-only PR#12/PR#13/PR#14/conftest.py/gitea_public_url.
  • Conventional Commits, один коммит: fix(stage): approved verdict advances analysis->architecture instead of re-running gate.

Тесты (контейнер)

IMG=$(docker inspect orchestrator --format '{{.Config.Image}}'); docker run --rm -v /home/slin/repos/orchestrator:/code -w /code --entrypoint python3 $IMG -m pytest tests/ -q Новый test_approved_verdict_advances_analysis_to_architecture:

  • вызов advance_stage(task_id, "analysis", repo, wid, branch, finished_agent=None) (Approved-путь) → результат: result.advanced is True, result.to_stage == "architecture", result.enqueued_agent == "architect" (мокни enqueue_job/update_task_stage/QG как в соседних тестах).
  • регресс-проверка: advance_stage(..., finished_agent="analyst") (launcher-путь) → по-прежнему In Review/коммент, НЕ advance (result.advanced НЕ True, _handle_analysis_approved_flow вызван). Baseline: 208 passed + 9 pre-existing failed — не ломать pre-existing.

Отчёт

  • НЕ деплоить, НЕ мержить (мерж + боевой прогон делает ассистент).
  • В отчёте: точные строки правки, подтверди что launcher-путь (agent=analyst) не сломан, что get_agent_for_stage("analysis")=architect (не analyst!), вывод нового+релевантных тестов. Если get_agent_for_stage вернул analyst — СТОП, сообщи. Один исполнитель, маленькая правка.