Files
orchestrator/docs/work-items/ORCH-094/02-trz.md

13 KiB
Raw Permalink Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-094 analysis analyst ready-for-review 2026-06-09 claude-opus-4-8

02 — ТЗ (TRZ): ORCH-094 — устранение флаппа deploy-статусов у терминальной (done) задачи

Work Item: ORCH-094 · Repo: orchestrator · Стадия: analysis

ТЗ описывает конкретные изменения к реализации, выведенные из BRD и фактического кода ветки. Архитектурное обоснование (ГДЕ ставить гард: setter plane_sync vs caller stage_engine vs реконсилятор) — задача архитектора (06-adr/). Здесь — ЧТО должно выполняться и ГДЕ искать.

1. Сводка изменения

Задача с БД stage=done и 0 активных job'ов в Plane стабильно держит Done: нужно (а) закрыть источник, который шлёт ей PATCH-и deploy-статусов (Awaiting Deploy/Monitoring after Deploy), (б) сделать выставление любого deploy-фазового статуса терминал-aware / идемпотентным — для задачи, чья БД-стадия терминальна (done/cancelled), любой sync/монитор/прямой вызов сходится к Done, а не к промежуточному статусу, (в) гарантировать детерминированный конец post-deploy-monitor с привязкой тиков к активному job'у (нет job → нет тиков), (г) добавить наблюдаемость «кто/почему ставит deploy-статус».

Изменение аддитивное, под обратимым флагом, never-raise, в зоне self-hosting deploy/post-deploy/sync. STAGE_TRANSITIONS / QG_CHECKS / machine-verdict ключи — не трогаются.

2. Задействованные модули / пути

Путь Действие Зачем
src/plane_sync.py изменить Сеттеры set_issue_awaiting_deploy (~954), set_issue_deploying (~964), set_issue_monitoring (~974), set_issue_done (~913) — кандидат на единый терминал-aware гард (FR-2). Терминал-детект статуса (группа/UUID, ORCH-068) уже здесь.
src/stage_engine.py изменить Три писателя deploy-статуса: advance_stage стр. 404 (set_issue_monitoring на deploy→done), _handle_self_deploy_phase_a стр. 1218, _handle_self_deploy_phase_b стр. 1316. run_post_deploy_monitor (~16981850) — детерминированный конец, привязка к job. arm_monitor-вызов (~431). Логирование caller/причины (FR-4).
src/post_deploy.py изменить (вероятно) arm_monitor (~388411), маркеры armed/series/done, enqueue_job("post-deploy-monitor", …) — гарантия отсутствия «зомби»-тиков и привязки к активному job (FR-3).
src/reconciler.py изменить (вероятно) F-2 опрашивает только [to_analyse, approved, rejected] (стр. ~387). Нет схождения «done-задача на deploy-статусе → Done». Добавить идемпотентное схождение/терминал-детект для deploy-статусов (FR-1/FR-2) ИЛИ убедиться, что гард в setter'е делает это излишним.
src/config.py изменить Kill-switch/флаг новой логики (FR-5).
src/webhooks/plane.py прочитать (диагностика) handle_issue_updated (~129180): подтверждено, что для Awaiting/Monitoring логирует «no pipeline action» и не переотправляет — echo-loop исключён; править не требуется (если локализация не покажет иное).
tests/test_* создать/изменить Анти-регресс по FR-1…FR-5 (см. 04-test-plan.yaml).
CHANGELOG.md, docs/architecture/README.md, CLAUDE.md изменить Документация = golden source; зафиксировать фикс + локализованный источник флаппа (BR-7).

Трассировка маркеров (CLAUDE.md прав. 9): перед правкой строк с маркерами ORCH-066/ORCH-068/ ORCH-086/ORCH-036/ORCH-059/ORCH-071/ORCH-088 прочитать их 06-adr/ и не сломать инвариант (особенно: deploy→done ставит Monitoring, монитор-close ставит Done; терминал-скип реконсилятора; post-deploy DEGRADED → freeze ORCH-088).

3. Функциональные требования

FR-1 — Источник флаппа локализован и устранён

Инструментально воспроизвести флапп на ORCH-061 (или эквивалентной терминальной задаче), определить фактического актора (функция/путь под бот-токеном орка ИЛИ внешняя Plane-automation) и устранить его так, чтобы терминальная задача не получала deploy-статус-PATCH-ей.

  • Зацепки (BR diagnostics): единственные code-писатели — stage_engine.py:404/1218/1316; реконсилятор F-1 done-skip есть, F-2 эти статусы не перебирает; live-overlay notifications.py — read-only.
  • Если актор — внешняя Plane-automation (вне кода орка), это фиксируется в ADR (BR-7) и закрывается буфером FR-2 (идемпотентное схождение к Done гасит маятник на стороне орка).
  • Привязка: BR-1, BR-7.

FR-2 — Терминал-aware идемпотентность выставления deploy-статуса

Любая попытка выставить deploy-фазовый статус (Awaiting Deploy/Deploying/Monitoring after Deploy) для задачи, чья БД-стадия терминальна (stage IN ('done','cancelled')), должна вместо этого привести Plane к Done (для done) либо к корректному терминалу (для cancelled) — идемпотентно. Повторные вызовы не качают маятник: уже-Done → no-op.

  • Гард — терминал-aware (по БД-стадии задачи, не по живому Plane-статусу), чтобы НЕ подавлять легитимный Monitoring у реально деплоящейся (нетерминальной) задачи (BR-5/AC-4).
  • Реализация-кандидат (решает архитектор): единая точка в setter'ах plane_sync (требует доступа к БД-стадии по work_item_id) ИЛИ в caller'ах stage_engine/reconciler. ТЗ требует результат: done-задача сходится к Done из любого пути.
  • never-raise: невозможность определить стадию/сетевая ошибка → безопасная деградация (не флаппить).
  • Привязка: BR-1, BR-2.

FR-3 — Детерминированный конец post-deploy-monitor + привязка тиков к активному job

  • Монитор завершается детерминированно: HEALTHY+исчерпание post_deploy_budget тиков → set_issue_done
    • маркер done; DEGRADED → штатный путь (Blocked/freeze ORCH-088); после завершения — ни одного последующего статус-PATCH (маркер done — идемпотентный страж, ~стр. 1729).
  • Тик монитора обязан проверять, что задача не терминальна и для неё есть основание тикать (нет активного основания/job → тик no-op, новый тик не ставится в очередь). «Зомби»-тик (тик без соответствующего активного job'а/при БД=done) → немедленный no-op без статус-PATCH.
  • Гарантировать, что arm_monitor не может быть вызван/перезапущен для задачи, уже находящейся в done, способом, который заново ставит Monitoring (повторный deploy→done re-drive).
  • restart-safe: после рестарта контейнера нет воскрешения тиков для завершённого окна.
  • Привязка: BR-3, BR-4, NFR-4.

FR-4 — Наблюдаемость выставления deploy-статуса

Каждый вызов, выставляющий deploy-фазовый статус, логирует структурно: work_item, caller (функция/путь), целевой статус, причина/триггер, БД-стадия задачи на момент вызова. Достаточно, чтобы по логу однозначно определить «кто и почему» при будущем флаппе. Терминал-aware-подавление (FR-2) тоже логируется (что подавили и почему).

  • Привязка: BR-6, G4.

FR-5 — Обратимость и совместимость

  • Новая логика — под kill-switch/флагом в config.py (env-override); False → прежнее поведение 1:1 (нулевая регрессия).
  • Условность self-hosting, как ORCH-035/036/043/088: для не-self репозиториев — no-op / прежнее поведение.
  • Привязка: NFR-3, BR-5.

4. Изменения API

Нет новых внешних эндпоинтов конвейера. Допустимо (на усмотрение архитектора) аддитивное read-only поле наблюдаемости в GET /queue (напр. блок post_deploy/deploy_status_guard со счётчиками подавлений), по образцу существующих блоков serial_gate/reconcile/reaper. Не обязательно.

5. Изменения схемы БД

Ожидается без миграции схемы: терминал-aware гард читает существующую tasks.stage; привязка тиков к job — существующая таблица jobs; состояние монитора — существующие sentinel-файлы (post_deploy.py). Если архитектор сочтёт необходимым durable-счётчик/маркер — строго аддитивно (_ensure_column, по образцу ORCH-088/090), без изменения существующих колонок.

6. Требования к новым/изменённым QG checks

Нет. QG_CHECKS и check_* (включая check_deploy_status/check_staging_status) — не трогаются; machine-verdict ключи (deploy_status:/staging_status:/…) — байт-в-байт. ORCH-094 — фикс индикации/идемпотентности sync, не гейт.

7. Совместимость / регресс

  • Kill-switch (FR-5): выключение → прежнее поведение 1:1.
  • Регресс деплоя (AC-4): рабочий цикл 063-подобной задачи Awaiting→Deploying→Monitoring→Done сохраняется — гард срабатывает строго на терминальной БД-стадии, нетерминальная задача проходит как раньше.
  • Не-self репозитории: условность self-hosting → нулевая регрессия (enduro-trails).
  • STAGE_TRANSITIONS/QG_CHECKS/machine-verdict/схема БД — без изменений (или строго аддитивно).
  • never-raise / self-hosting безопасность: не трогать main/force-push/прод-контейнер/детач-деплой.
  • Артефакты pipeline: обновляются CHANGELOG.md, обзорные доки (README.md/docs/architecture/ README.md), CLAUDE.md; 06-adr/ADR-NNN-… с локализованным источником флаппа (BR-7).