# Инфра-требования — ORCH-058

Work Item ID: ORCH-058

Топология не меняется (тот же сервер mva154, те же контейнеры 8500/8501, общая БД). Меняется
**что делает self-deploy на ребре `deploy-staging → deploy`** для self-hosting. Полная
топология/риски — `docs/operations/INFRA.md` (обновить в том же PR).

## IR-1. Host-сборка staging-образа (Стратегия A)

Шаг свежести пересобирает `orchestrator-orchestrator-staging` на ХОСТЕ (docker CLI/compose
есть на хосте, НЕ в контейнере — образ ставит только `openssh-client git`). Требуется:

- Рабочий ssh `slin@127.0.0.1` (уже есть, ORCH-36 / LESSONS п.1–2: passwd-запись uid 1000,
  ключ смонтирован, `ORCH_DEPLOY_*` префиксы).
- На хосте под `slin` доступны `docker build` и `docker compose --profile staging`
  (recreate 8501). Группа docker (`group_add: "999"` / host-доступ к `docker.sock`) — уже
  настроено.
- **Build-context = host-путь worktree** валидированной ветки
  (`/home/slin/repos/_wt/<repo>/<branch-slug>`), читаемый под `slin`. Worktree уже
  создаётся launcher'ом/merge-gate под slin (ADR-0005 run-as-host-uid) — права ок.
- Лог-директория хука writable под slin (`/var/log/orchestrator`, LESSONS п.3) — уже.

## IR-2. Вывод host-пути worktree

В контейнере worktree виден как `ORCH_WORKTREES_DIR=/repos/_wt/...`; на хосте — как
`/home/slin/repos/_wt/...`. Маппинг = замена `repos_dir → host_repos_dir` (как
`self_deploy.host_state_dir`). Реализация: производный helper host-worktree-пути, либо новая
настройка `ORCH_HOST_WORKTREES_DIR` (дефолт `/home/slin/repos/_wt`). Без неё — деривация из
`host_repos_dir`.

## IR-3. OCI-лейбл происхождения (Стратегия B)

`Dockerfile`: `ARG GIT_SHA` + `LABEL org.opencontainers.image.revision=$GIT_SHA`. Сборки БЕЗ
build-arg (ручные/legacy) дают пустой лейбл → B fail-closed (это by design, не регрессия:
прод-retag без доказуемого провенанса должен падать). Любой существующий способ сборки прод/
staging-образа (CI, ручной) при включённой фиче ОБЯЗАН передавать `--build-arg GIT_SHA=<sha>`,
иначе деплой задачи fail-fast'нется на guard. Шаг A это делает автоматически.

## IR-4. ssh-режим хука `--build-staging`

Новый режим `orchestrator-deploy-hook.sh --build-staging` запускается синхронно (рестарт
staging безопасен, detached/finalizer не нужны — в отличие от Phase B прод). Дефолты режима —
STAGING-safe (`TARGET_PORT=8501`, `--profile staging`). Прод (8500) этим режимом НЕ
затрагивается.

## IR-5. Конфигурация (env, префикс `ORCH_`)

- `ORCH_IMAGE_FRESHNESS_ENABLED` (дефолт true) — единый kill-switch A+B.
- `ORCH_IMAGE_FRESHNESS_REPOS` (дефолт пусто → self-hosting).
- (опц.) `ORCH_HOST_WORKTREES_DIR` (дефолт `/home/slin/repos/_wt`).

`EXPECTED_REVISION` для хука строится в `build_deploy_command` — отдельной настройки не
требует. `deploy_prod_source_image` (= `orchestrator-orchestrator-staging`) переиспользуется.

## IR-6. Безопасность self-hosting (инварианты)

- Любые `docker build` / `compose up` / recreate — ТОЛЬКО staging (8501); прод (8500) не
  рестартуется в рамках шага свежести.
- `main` не пушится; force-only — `--force-with-lease` на ветку задачи (merge-gate, без
  изменений). Шаг A не пушит ничего (только локальный `docker build`).
- B-guard срабатывает ДО `docker tag`/restart — прод не трогается на сомнении.

## IR-7. Bootstrap-чеклист (урок ORCH-36 «сквозной»)

Перед мержем ORCH-058 — **реальный** прогон в staging-петле (не только бумажные гейты):
сборка staging из worktree с GIT_SHA → лейбл присутствует
(`docker image inspect ... revision`) → recreate 8501 → `staging_check` зелёный →
`build_deploy_command` отдаёт непустой `EXPECTED_REVISION` → хук-guard пропускает при
совпадении и `exit 1` при подмене `SOURCE_IMAGE` на устаревший. Зафиксировать в bootstrap-
заметке (как LESSONS_ORCH-036).
