architect(ET): auto-commit from architect run_id=512

This commit is contained in:
2026-06-09 22:23:22 +03:00
committed by orchestrator-deployer
parent 520373a694
commit 3d0f51512b
4 changed files with 374 additions and 0 deletions

View File

@@ -477,6 +477,40 @@ developer-пути и **только** при свежем worktree-коммит
Подробнее: [adr-0016](adr/adr-0016-ensure-open-pr-before-merge-verify.md) (amends 0013/0014);
детально — `docs/work-items/ORCH-082/06-adr/ADR-001-ensure-open-pr-before-merge-verify.md`.
#### Ретрай транзиентных merge-ошибок Gitea + гард already-in-main (ORCH-093 — фикс ложного HOLD на 405/5xx)
Инцидент ORCH-063 (09.06): self-deploy прошёл, PR `open`+`mergeable=True`, конфликтов нет — но
`POST …/merge` вернул `HTTP 405 {"message":"Please try again later"}` (Gitea пересчитывал
`mergeable` сразу после пуша). `merge_pr` был **one-shot** → мгновенный `False` → ложный HOLD
ORCH-071/073 + ручной домерж; повторный прогон финализатора после ручного мержа создавал **пустой
PR** на уже влитой ветке. ORCH-093 аддитивно закрывает оба дефекта, не трогая машину стадий:
- **Ретрай-loop в `merge_pr`** оборачивает **только** `POST /pulls/{index}/merge` до
`merge_retry_max_attempts` (дефолт 3) с экспон. backoff и потолком (`merge_retry_backoff_base_s` 2 /
`merge_retry_backoff_max_s` 5; суммарно ≤10 с, не подвешивает monitor-поток). Шаги до POST
(idempotency `pr_already_merged`, поиск код-PR) — без изменений. Лог `attempt i/N` (образец
`check_ci_green`).
- **Классификатор транзиент/терминал** по коду ответа **и** полю `mergeable`: **транзиент** (ретрай)
`405`/`408`/`5xx`/таймаут/сетевое, `409`/`422` при `mergeable==True`; **терминал** (быстрый
честный `False`) — `403`/`404`, `409`/`422` при `mergeable==False`. Неоднозначный `409/422`
разрешается доп. `GET /pulls/{index}`; `mergeable==None`/недоступен → транзиент-по-дефолту в рамках
бюджета (цель — не давать ложного HOLD на икоте; backstop ORCH-071/073 сохранён).
- **Гард already-in-main в `ensure_open_pr`**: перед созданием PR — `git merge-base --is-ancestor
<branch> origin/main` (rc==0 → ветка целиком в `main`) → новый исход `("already-in-main", …)`, PR
**не создаётся**; git-ошибка/ambiguous → **fail-OPEN** на текущий create-путь (икота git не должна
стать ложным no-op мержа). `_handle_merge_verify` трактует `already-in-main` как «мержить нечего» →
пропуск `merge_pr` → авторитетный SHA-в-main (`verify_merged_to_main`) доводит до `done` без мусорного
PR. Это НЕ `failed`-ветка.
- **Защита ORCH-071/073 неприкосновенна:** реальный конфликт → быстрый честный HOLD; подтверждение
merge остаётся ТОЛЬКО SHA-в-main. Терминал/исчерпание ретраев → `(False, …)` → прежний HOLD+alert.
- **Условность / откат:** kill-switch `merge_retry_enabled` (дефолт `true`; `False` → one-shot 1:1,
env `ORCH_MERGE_RETRY_*`); гард already-in-main — без отдельного флага (накрыт
`merge_verify_autocreate_pr_enabled`). Область — `merge_verify_applies` (self-hosting; на прочих
репо мерж за `deployer` — изменение нейтрально). `STAGE_TRANSITIONS`, `QG_CHECKS`, схема БД,
exit-коды хука, merge-gate, image-freshness — без изменений; `main` не push/force-push (INV-4).
Подробнее: [adr-0027](adr/adr-0027-merge-actor-transient-retry-and-already-in-main.md) (amends
0013/0014/0016); детально —
`docs/work-items/ORCH-093/06-adr/ADR-001-merge-transient-retry-and-already-in-main-guard.md`.
### Post-deploy наблюдение прода + реакция на деградацию (ORCH-021 — реализовано)
Конвейер заканчивался на `deploy → done` и **забывал про прод**: «успех» = health-check
в момент рестарта (~60с). Класс «зелёный деплой, красный прод» (прецедент ET-8 —