fix(deploy): terminal-window-aware guard so done tasks hold Done in Plane (ORCH-094) #105

Merged
admin merged 8 commits from feature/ORCH-094-bug-done-deploy-plane-awaiting into main 2026-06-09 23:45:50 +03:00
Owner

ORCH-094 — done-задача держит Done, не флаппит deploy-статусы

Задача с БД stage=done и 0 активных job'ов стабильно флаппила в Plane Awaiting Deploy ⟷ Monitoring after Deploy (верифицировано на ORCH-061, task 47) вместо Done. Корень: три deploy-фазовых сеттера терминал-слепы — любой стейл/двойной/неизвестный вызов под бот-токеном перезаписывал терминал промежуточным статусом, и обратно, бесконечно.

Решение (по ADR-001)

  • Единый гард на низком чокпоинте (D1/D2): новый leaf src/deploy_status_guard.py (never-raise, config-gated) — decide() -> ALLOW | CONVERGE_DONE | SUPPRESS на входе set_issue_awaiting_deploy/set_issue_deploying/set_issue_monitoring. Легитимность: deploy-статус ОК ⇔ задача нетерминальна ИЛИ (done И активно пост-деплой-окно). Для done иначе → идемпотентное схождение к Done; cancelled → suppress.
  • Перенос арм-блока перед terminal-sync (D3): post_deploy.arm_monitor поднят выше set_issue_monitoring в advance_stage, чтобы window_active==True пропустил легитимный первый Monitoring (БД уже done к этому моменту).
  • Харднинг монитора (D4): тик при БД cancelled мид-окно → закрыть окно без статус-PATCH и без перепостановки (zombie-tick guard).
  • Наблюдаемость (D5): BC-kwarg reason + одна структурная лог-запись на вердикт; новый db.get_task_by_work_item_id, post_deploy.window_active.
  • Флаги (D6): deploy_status_guard_enabled (kill-switch → 1:1) / deploy_status_guard_repos (CSV; пусто → self-hosting only).

Инварианты

STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict ключи / схема БД — не тронуты (читается существующая tasks.stage, без миграции). main/force-push/прод-контейнер/detached-деплой — не тронуты. Рабочий self-deploy-цикл 1:1; не-self репо инертны.

Тесты

TC-01..TC-12 в 5 новых модулях + флаги конфига; обновлены reason-ассерты в test_deploy_terminal_sync/test_deploy_approve. Полный регресс pytest tests/ -q зелёный (1413).

ADR: docs/work-items/ORCH-094/06-adr/ADR-001-terminal-window-aware-deploy-status-guard.md, сквозной docs/architecture/adr/adr-0028-…md.

Refs: ORCH-094

🤖 Generated with Claude Code

## ORCH-094 — done-задача держит `Done`, не флаппит deploy-статусы Задача с БД `stage=done` и 0 активных job'ов стабильно флаппила в Plane `Awaiting Deploy ⟷ Monitoring after Deploy` (верифицировано на ORCH-061, task 47) вместо `Done`. Корень: три deploy-фазовых сеттера терминал-слепы — любой стейл/двойной/неизвестный вызов под бот-токеном перезаписывал терминал промежуточным статусом, и обратно, бесконечно. ### Решение (по ADR-001) - **Единый гард на низком чокпоинте (D1/D2):** новый leaf `src/deploy_status_guard.py` (never-raise, config-gated) — `decide() -> ALLOW | CONVERGE_DONE | SUPPRESS` на входе `set_issue_awaiting_deploy`/`set_issue_deploying`/`set_issue_monitoring`. Легитимность: deploy-статус ОК ⇔ задача нетерминальна ИЛИ (`done` И активно пост-деплой-окно). Для `done` иначе → идемпотентное схождение к Done; `cancelled` → suppress. - **Перенос арм-блока перед terminal-sync (D3):** `post_deploy.arm_monitor` поднят выше `set_issue_monitoring` в `advance_stage`, чтобы `window_active==True` пропустил легитимный первый Monitoring (БД уже `done` к этому моменту). - **Харднинг монитора (D4):** тик при БД `cancelled` мид-окно → закрыть окно без статус-PATCH и без перепостановки (zombie-tick guard). - **Наблюдаемость (D5):** BC-kwarg `reason` + одна структурная лог-запись на вердикт; новый `db.get_task_by_work_item_id`, `post_deploy.window_active`. - **Флаги (D6):** `deploy_status_guard_enabled` (kill-switch → 1:1) / `deploy_status_guard_repos` (CSV; пусто → self-hosting only). ### Инварианты `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / machine-verdict ключи / схема БД — **не тронуты** (читается существующая `tasks.stage`, без миграции). `main`/force-push/прод-контейнер/detached-деплой — не тронуты. Рабочий self-deploy-цикл 1:1; не-self репо инертны. ### Тесты TC-01..TC-12 в 5 новых модулях + флаги конфига; обновлены `reason`-ассерты в `test_deploy_terminal_sync`/`test_deploy_approve`. Полный регресс `pytest tests/ -q` зелёный (1413). ADR: `docs/work-items/ORCH-094/06-adr/ADR-001-terminal-window-aware-deploy-status-guard.md`, сквозной `docs/architecture/adr/adr-0028-…md`. Refs: ORCH-094 🤖 Generated with [Claude Code](https://claude.com/claude-code)
admin added 7 commits 2026-06-09 23:41:26 +03:00
A DB stage=done task with 0 active jobs flapped in Plane between `Awaiting
Deploy` and `Monitoring after Deploy` instead of holding `Done` (verified live
on ORCH-061, task 47): the three deploy-phase setters were terminal-blind, so
any stale/duplicate/unknown caller under the bot token re-stamped an
intermediate status over the terminal Done, forever.

- New leaf src/deploy_status_guard.py (pure, never-raise, config-gated): decide()
  -> ALLOW | CONVERGE_DONE | SUPPRESS on the entry of set_issue_awaiting_deploy /
  set_issue_deploying / set_issue_monitoring. A deploy-phase status is legitimate
  iff the task is non-terminal OR (done AND post-deploy window active); otherwise
  done converges to Done idempotently, cancelled is suppressed (FR-2, D1/D2).
- D3: move post_deploy.arm_monitor ABOVE the terminal-sync block in advance_stage
  so window_active is True when the legitimate first Monitoring is set (the task
  is already DB-done by then); a re-drive after the window closes converges to Done.
- D4: run_post_deploy_monitor no-ops without a status PATCH / re-queue when the
  task became cancelled mid-window (zombie-tick guard, FR-3).
- D5: additive `reason` kwarg on the three setters + one structured log line per
  verdict (work_item/caller/target/db_stage/window_active/verdict); new read-only
  db.get_task_by_work_item_id; post_deploy.window_active helper.
- Flags deploy_status_guard_enabled (kill-switch -> 1:1) / deploy_status_guard_repos
  (CSV; empty = self-hosting only). STAGE_TRANSITIONS / QG_CHECKS / check_* /
  machine-verdict keys / DB schema untouched (reads existing tasks.stage).

Tests: TC-01..TC-12 across 5 new test modules + config flags; updated the
reason-kwarg assertions in test_deploy_terminal_sync / test_deploy_approve.
Full regress green (1413). Docs: CHANGELOG, CLAUDE.md, docs/architecture/README.md
(status -> реализовано), .env.example.

Refs: ORCH-094

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tester(ET): auto-commit from tester run_id=523
All checks were successful
CI / test (push) Successful in 42s
CI / test (pull_request) Successful in 40s
fe35b2224a
admin force-pushed feature/ORCH-094-bug-done-deploy-plane-awaiting from b35b082331 to fe35b2224a 2026-06-09 23:41:26 +03:00 Compare
admin added 1 commit 2026-06-09 23:45:47 +03:00
deploy(ORCH-036): finalize SUCCESS for ORCH-094
All checks were successful
CI / test (push) Successful in 43s
CI / test (pull_request) Successful in 41s
b243343cd5
admin merged commit e0f44cc4ef into main 2026-06-09 23:45:50 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/orchestrator#105