From 56ee99323332d9955eeeb0839cf4e9a5176a2aa1 Mon Sep 17 00:00:00 2001 From: orchestrator-deployer Date: Mon, 15 Jun 2026 09:28:36 +0300 Subject: [PATCH] docs(lessons): record ORCH-111 reaper finalization race --- ...-06-15_orch111-reaper-finalization-race.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/history/LESSONS_2026-06-15_orch111-reaper-finalization-race.md diff --git a/docs/history/LESSONS_2026-06-15_orch111-reaper-finalization-race.md b/docs/history/LESSONS_2026-06-15_orch111-reaper-finalization-race.md new file mode 100644 index 0000000..d0d7c63 --- /dev/null +++ b/docs/history/LESSONS_2026-06-15_orch111-reaper-finalization-race.md @@ -0,0 +1,49 @@ +# Lessons Learned — 2026-06-15: reaper race during deploy-staging finalization (ORCH-111) + +## Контекст +ORCH-111 добавляла мониторинг долгоживущих pytest/child-процессов в sidecar-watchdog. Задача прошла полный цикл до `deploy-staging`: review, testing, staging, security и первый merge-gate были зелёными. + +## Инцидент +На ребре `deploy-staging → deploy` произошла гонка между штатной финализацией deployer job и job-reaper. + +Факты: +- Work item: `ORCH-111`. +- Deployer job: `1914`, run_id `683`. +- Deployer успешно записал `15-staging-log.md` со `staging_status: SUCCESS`. +- После выхода агента `agent_runs.exit_code=0`, но job ещё оставалась `running`, потому что monitor продолжал послеагентную финализацию. +- Финализация `deploy-staging` включает тяжёлые edge-гейты: security, merge-gate, локальный full re-test, coverage/image-freshness. +- Первый merge-gate re-test был зелёным: `rebased onto main, re-test green`. +- После `reaper_finalize_grace_s=300` reaper решил, что monitor умер, и повторно вызвал gate-driven advance для той же job/stage. +- В результате `deploy-staging` edge-гейты запустились повторно: security-gate, merge-gate, rebase, full re-test. +- Повторный re-test стал красным: `3 failed, 1916 passed, 1 warning, 14 errors in 444.79s`. +- Орк откатил задачу `deploy-staging → development` и запустил developer retry. +- Параллельно prod-deploy/finalizer завершился успешно: hook exit `0`, PR #130 был смержен, merge-verify прошёл, задача дошла `deploy → done`. + +## Root Cause +Reaper использовал слишком грубый сигнал: `exit_code=0` уже записан, job всё ещё `running` дольше grace-периода. Для обычных стадий это похоже на умерший monitor, но для `deploy-staging` это может быть нормальная долгая финализация. + +`deploy-staging` — не короткая стадия. После выхода LLM-agent там ещё выполняются дорогие детерминированные гейты. Поэтому `running + exit_code=0 + age>300s` не доказывает смерть monitor. + +## Почему это опасно +Система получила две конкурирующие ветки истины: +- reaper повторно обработал `deploy-staging` и откатил задачу в `development`; +- штатный deploy/finalizer параллельно довёл prod-deploy до `SUCCESS` и задачу до `done`. + +Это ломает доверие к автономности: одна часть системы уже успешно внедряет, другая в это же время считает задачу неуспешной. + +## Уроки +1. **Reaper не должен повторно запускать тяжёлые edge-гейты без строгого владения состоянием.** `deploy-staging → deploy` содержит дорогие операции: rebase, локальный re-test, coverage, merge-lease. +2. **`exit_code=0` агента ≠ финализация стадии завершена.** Для action-стадий после выхода агента есть отдельная длинная фаза: git/Plane comments/QG/merge/deploy/finalizer. +3. **Grace-период 300s недостаточен как универсальный критерий смерти monitor.** Полный re-test/coverage может занимать больше 5 минут даже в штатном режиме. +4. **Нужна явная модель состояния `finalizing` или эквивалентный lock/idempotency guard.** Reaper должен отличать «monitor умер» от «monitor жив и делает долгие deterministic gates». +5. **Deploy-gates должны быть safely re-drivable.** Повторный запуск не должен создавать второй re-test/rollback, если первый проход уже владеет stage/job или уже дошёл до deploy result. +6. **Успешный prod-deploy и rollback одной задачи не должны сосуществовать.** Это признак рассинхронизации stage ownership. + +## Follow-up +- `ORCH-113` — `BUG: job-reaper must not re-run deploy-staging finalization while original finalizer is alive`. + +## Related +- `ORCH-111` — watchdog proc-blocking alert. +- `ORCH-110` — merge-gate local re-test timeout/false rollback. +- `ORCH-112` — cleanup failed/cancelled task artifacts from shared checkout. +- ADR: `docs/architecture/adr/adr-0011-job-reaper-lease-reclaim.md`.