From cad5e9889260721507dd654124b39b84cd2f4f71 Mon Sep 17 00:00:00 2001 From: stream Date: Sun, 7 Jun 2026 19:24:08 +0300 Subject: [PATCH] =?UTF-8?q?docs(history):=20lessons=202026-06-07=20?= =?UTF-8?q?=E2=80=94=20autonomy=20closure=20(5=20=D0=B7=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D1=87:=20ORCH-58/60/61/21/65=20=D0=B2=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LESSONS_2026-06-07_autonomy-closure.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/history/LESSONS_2026-06-07_autonomy-closure.md diff --git a/docs/history/LESSONS_2026-06-07_autonomy-closure.md b/docs/history/LESSONS_2026-06-07_autonomy-closure.md new file mode 100644 index 0000000..42fd37d --- /dev/null +++ b/docs/history/LESSONS_2026-06-07_autonomy-closure.md @@ -0,0 +1,78 @@ +# 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.