architect(ET): auto-commit from architect run_id=702
All checks were successful
CI / test (push) Successful in 3m1s

This commit is contained in:
2026-06-15 14:20:36 +03:00
parent de77fc3430
commit 0d9215a1f7
6 changed files with 459 additions and 0 deletions

View File

@@ -742,6 +742,40 @@ sentinel-файлы (`<repos_dir>/.deploy-state-<repo>/<wi>/`), без мигр
Подробнее: [adr-0007](adr/adr-0007-executable-self-deploy.md), детально —
`docs/work-items/ORCH-036/06-adr/ADR-001-executable-self-deploy.md`.
#### Гигиена shared deploy-базы: устойчивый self-deploy `git pull` (ORCH-112 — design)
**Инвариант (нормативно):** shared main checkout `<host_repos_dir>/<repo>`
(= `settings.deploy_host_repo_path` = `/home/slin/repos/orchestrator`) — это
**deploy/worktree-management база, НЕ редактируемый workspace.** Рабочие изменения туда
**не пишутся** конвейером/агентами: агенты работают в worktree'ах `/repos/_wt/<repo>/<branch>`
(`git_worktree.ensure_worktree`), `docker build` берёт контекст worktree
(`image_freshness._host_worktree_path`), fallback'и гейтов на main clone — только чтение
(`git show origin/main:...`). Локальные правки в deploy-базе по определению существовать не должны.
**Проблема (инцидент ORCH-111 от грязи ORCH-104):** хук `scripts/orchestrator-deploy-hook.sh`
делал **голый** `git pull origin main` в `$REPO` без гигиены рабочего дерева → любая локальная правка
tracked-файла (`src/config.py`) блокировала merge → деплой падал → ручное вмешательство (групповой риск
self-hosting). **Решение** — **resilient-pull, встроенный в хук** (`--deploy`): перед `git pull` хук
при обнаружении грязи приводит базу к чистому актуальному `origin/main`
(`git fetch` + `git reset --hard origin/main` + **скоупленный** `git clean -fd`). Гейт — env
`CHECKOUT_HYGIENE`, инжектится `self_deploy.build_deploy_command` когда новый чистый never-raise leaf
`src/checkout_hygiene.py`-`applies(repo)` истинен (kill-switch `checkout_hygiene_enabled` + скоуп
`checkout_hygiene_repos`, пусто → self-hosting only).
- **Сохранность (NFR-2, жёсткий контракт):** `git clean` — **только `-fd`, НИКОГДА `-x`** (иначе
удалит gitignored `.env`/прод-секреты, `data/*.db`/БД, `build/`); явные `-e '.deploy-prev-image-*'`
и `-e 'deploy-hook.log'` (untracked-но-НЕ-ignored — иначе сломается rollback `do_rollback`).
Sibling `<repos_dir>/.deploy-state-*` / `.merge-lease-*.json` (под родителем `$REPO`) и
`.git/worktrees/*` (внутри `.git/`) — вне области `git clean` в `$REPO`.
- **Сходимость после failed/cancelled** — этим же deploy-time self-heal (база сходится на следующем
деплое); `cancel_task` (ORCH-090) **не расширяется**, фоновый janitor **не вводится**.
- **Наблюдаемость** — хук пишет sentinel `hygiene` в deploy-state каталог; Phase-C finalizer читает и
шлёт Telegram-алерт (кликабельный номер, best-effort, never-raise).
- **Чистая база / kill-switch off** — голый fast-forward `git pull` байт-в-байт (happy-path без
регресса); `--build-staging` (build из worktree, без pull) не затронут. `STAGE_TRANSITIONS` / реестр
`QG_CHECKS` / `check_*` / machine-verdict / схема БД / exit-code-контракт хука (0/1/2) — не тронуты.
Детально — `docs/work-items/ORCH-112/06-adr/ADR-001-deploy-base-checkout-hygiene.md`, сквозной
[adr-0044](adr/adr-0044-deploy-base-checkout-hygiene.md).
#### Выделенный статус-триггер прод-деплоя «Confirm Deploy» (ORCH-059 — реализовано)
Перегрузка: один Plane-статус `Approved` служил И человеческим гейтом BRD на
`analysis` (`check_analysis_approved`), И триггером Фазы B прод-деплоя на `deploy`

View File

@@ -0,0 +1,67 @@
---
work_item: ORCH-112
stage: architecture
author_agent: architect
status: proposed
created_at: 2026-06-15
model_used: claude-opus-4-8
---
# adr-0044: Гигиена shared deploy-базы — устойчивый self-deploy `git pull`
Сквозное (cross-cutting) решение. Детальный per-work-item ADR —
`docs/work-items/ORCH-112/06-adr/ADR-001-deploy-base-checkout-hygiene.md`.
## Статус
Proposed (ORCH-112)
## Контекст (сквозной)
Глобальный путь прод-деплоя self-hosting (`deploy`-стадия, ORCH-036) исполняет хост-хук
`scripts/orchestrator-deploy-hook.sh`, чей шаг «2. Pull latest code» — **голый** `git pull origin main`
в shared main clone (`settings.deploy_host_repo_path`). Любая грязь рабочего дерева (модифицированный
tracked-файл и/или untracked-остатки failed/cancelled/брошенной задачи) **блокирует** merge → деплой
встаёт → ручное вмешательство. На self-hosting (один прод-инстанс на все проекты с общей БД/очередью)
это **групповой риск**: залипший self-deploy орка останавливает обслуживание всех проектов
(инцидент ORCH-111, грязь от ORCH-104).
## Решение (сквозное)
Вводится **resilient-pull, встроенный в прод-deploy-хук** (`--deploy`), + новый чистый never-raise
leaf-компонент `src/checkout_hygiene.py`:
- **Хук** перед `git pull origin main` приводит грязную deploy-базу к чистому актуальному `origin/main`
(`git fetch` + `git reset --hard origin/main` + **скоупленный** `git clean -fd`), **строго сохраняя**
rollback/лог-артефакты. Гейт — env `CHECKOUT_HYGIENE`, инжектится `self_deploy.build_deploy_command`.
- **Leaf** `checkout_hygiene` решает условность (`applies(repo)`: kill-switch `checkout_hygiene_enabled`
+ скоуп `checkout_hygiene_repos`, пусто → self-hosting only), строит env-префикс, читает sentinel
отчёта, шлёт Telegram-алерт. Образец `serial_gate`/`cancel`/`self_deploy`.
- **Сходимость** базы после failed/cancelled (FR-2) — этим же deploy-time self-heal; `cancel_task`
(ORCH-090) **не расширяется**, фоновый janitor **не вводится**.
- **Наблюдаемость** — хук пишет sentinel `hygiene`, Phase-C finalizer читает и шлёт Telegram-алерт
(best-effort, never-raise).
- **Инвариант** «main checkout — deploy/worktree-management база, НЕ workspace» документируется
(INFRA.md + architecture/README.md); de-facto энфорс — сам resilient-pull.
## Кросс-каттинг-инварианты (обязательны к соблюдению будущими задачами)
- **INV-HYGIENE-1 (никогда `-x`):** hygiene-`git clean` — только `git clean -fd`. `-x` удалил бы
gitignored `.env` (прод-секреты) / `data/*.db` (БД прода) / `build/`. Анти-регресс — статический тест.
- **INV-HYGIENE-2 (явные excludes):** `.deploy-prev-image-*` (rollback, `deploy_prod_prev_image_file`)
и `deploy-hook.log` — untracked-но-НЕ-ignored → обязательны `-e`-исключения; их удаление сломало бы
rollback.
- **INV-HYGIENE-3 (скоуп = `$REPO`):** гигиена оперирует только рабочим деревом deploy-базы;
sibling `<repos_dir>/.deploy-state-*` / `.merge-lease-*.json` и `.git/worktrees/*` — вне области.
- **Self-hosting safety (NFR-1):** никогда не трогать `main` на remote, не force-push, не рестартить
прод вне штатного гейта, не сносить worktree/ветки других активных задач.
- **Нулевая регрессия (NFR-5):** `STAGE_TRANSITIONS` / реестр `QG_CHECKS` / семантика и имена `check_*` /
machine-verdict ключи / схема БД / exit-code-контракт хука (0/1/2, ORCH-036) — байт-в-байт. Это
устойчивость deploy-пути, **не** Quality Gate и **не** стадия.
## Связи
- Дополняет: adr-0007 (executable self-deploy, ORCH-036), adr-0008 (image-freshness, ORCH-058).
- Не нарушает: adr-0026 (STOP/cancel, ORCH-090) — каскад cancel не трогается.
## Откат
`ORCH_CHECKOUT_HYGIENE_ENABLED=false` → прод-деплой байт-в-байт до ORCH-112 (голый `git pull origin main`).
</content>