13 KiB
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_syncvs callerstage_enginevs реконсилятор) — задача архитектора (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 (~1698–1850) — детерминированный конец, привязка к job. arm_monitor-вызов (~431). Логирование caller/причины (FR-4). |
src/post_deploy.py |
изменить (вероятно) | arm_monitor (~388–411), маркеры 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 (~129–180): подтверждено, что для 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-overlaynotifications.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→donere-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).