# Lessons Learned — 2026-06-07: замыкание автономности self-deploy (5 задач в прод) ## Итог За одну сессию закрыты в прод **5 задач**, завершающих автономный self-deploy эпика ORCH-54: | Задача | Что | Прод-коммит | |--------|-----|-------------| | ORCH-58 | provenance retag-guard (свежесть staging-образа перед BUILD-ONCE) | 094b5e2 | | ORCH-60 | reconciler не трогает escalated/Blocked/Needs-Input | d4c6cc0 | | ORCH-61 | фикс петли deploy-staging (staging_verdict: waive sandbox-infra FAILs C9a/C9b) | e18947d | | ORCH-21 | post-deploy мониторинг прода + auto-rollback (self-hosting=alert-only) | f85e449 | | ORCH-65 | job-reaper + stale merge-lease reclaim + idempotent merge | bb03350 | **Главное:** после ORCH-60/61 конвейер впервые провёз задачи (ORCH-21/65) через deploy-staging **автономно** без отката; после ORCH-65 (job-reaper в проде) зомби-job и зависшие merge-lease лечатся сами. Последняя ручная точка автономного деплоя закрыта. --- ## Класс багов: «процесс умер — ресурс захвачен навсегда» (ORCH-65) Три связанных отказа, все воспроизвелись на ORCH-58/60/61/21: - **zombie jobs:** агент завершился/умер, строка jobs осталась running. requeue_running_jobs() спасает только на старте процесса; зомби без рестарта не лечился → при concurrency=1 встаёт конвейер ВСЕХ проектов. (jobs 236/239/242/254/265 — все зомби за сессию.) - **stale merge-lease:** merge-gate берёт .merge-lease-.json, делает rebase+re-test green, а на финальном merge процесс умирает с зажатым lease → merge не докатывается. - **неидемпотентный merge:** re-drive повторно пытается слить уже слитый PR. Фикс: фоновый job_reaper (паттерн reconciler, dead_ticks streak + мёртвый pid + exit_code, атомарный reap-claim, never-raise, kill-switch, снимок в /queue) + проактивный lease-reclaim по pid + guard pr_already_merged ПЕРЕД merge. ## Петля deploy-staging (ORCH-61) — ДВЕ причины 1. ложный check_staging_status FAILED: staging_check падает на C9a/C9b (sandbox e2e branch + analyst-job-in-queue), т.к. bot-токены SANDBOX-проекта не настроены — НЕ регресс кода. 2. no-changes для action-стадий (деплой = рестарт/retag, не правка → коммитить нечего). Фикс: staging_verdict waive sandbox-infra-only FAILs. ## Инфра-каскад от переполненного диска (инцидент дня) - Частые build-once/--build-staging пересборки за день забили docker build cache до 11 ГБ → диск 100% → CI red (No space left). - ДАЖЕ после чистки диска Gitea осталась в сломанном состоянии: внутренняя queue (/data/gitea/queues/common/*.log) залипла → post-receive hook 500 → actions tasks НЕ создаются, CI не триггерится вовсе (статус пустой, не failure). runner при этом online+idle. - Лечение: docker builder prune -af + рестарт Gitea (queue распускается → CI ожил). --- ## Уроки 1. **Self-hosting safety (сквозной принцип):** прод-орк обслуживает ВСЕ проекты. Нельзя авто- откатывать/рестартить self в рамках задачи; нельзя пушить main. ORCH-21 post-deploy для self-hosting = alert-only, авто-rollback только для не-self репо. 2. **TDD без доводки (повтор ORCH-58 и ORCH-65 v1):** тесты есть, реализация/wiring не подключены к боевому пути → мёртвый код + врущая дока. Reviewer обязан грепать вызовы из прод-кода, не только наличие функции. 3. **Concurrency-баги ловятся итеративно:** ORCH-65 3 прохода reviewer (мёртвый guard → race condition side-effects-before-claim → approve) — каждый раз НОВЫЙ реальный дефект, не зацикливание. Atomic-claim ДО side-effects — обязательное правило. 4. **При красном CI + зелёных локальных тестах — ПЕРВЫМ делом df -h / и docker system df**, не копаться в коде. После disk-full обязателен рестарт Gitea (queue залипает). 5. **Bootstrap-разрыв:** задача про автономность деплоя не может задеплоить себя автономно, пока её механизм не в проде. Последний прод-деплой каждого такого фикса — вручную. 6. **Перед прод-retag (build-once SOURCE_IMAGE=staging):** проверить revision-label staging- образа == целевой main HEAD, иначе guard fail-closed (by design). Если != → пересобрать --build-staging GIT_SHA=
. ## Ручная доводка прод-deploy (схема до ORCH-65 в проде) cancel zombie job → park task In Progress → merge PR (Gitea pulls/{n}/merge Do=merge, CI green) → --build-staging GIT_SHA=
(проставит label) → rollback-снимок → --deploy с EXPECTED_REVISION= (guard сверит → retag → health 200) → Plane Done + UPDATE tasks stage=done. ## Follow-up (Backlog) - ORCH-62: авто-prune docker build cache (cron/daemon.json defaultKeepStorage). - ORCH-63: мониторинг диска mva154 + алерт >85%. - ORCH-64: починить NTP/часы mva154 (ушли ~+3ч от UTC). ## Осталось в эпике ORCH-54 ORCH-22 (security-гейт), ORCH-59 (Confirm Deploy статус), ORCH-23 (budget circuit-breaker), P2: ORCH-57, ORCH-51.