---
work_item: ORCH-101
stage: architecture
author_agent: architect
status: proposed
created_at: 2026-06-10
model_used: claude-opus-4-8
---

# 07 — Инфра-требования: ORCH-101 — ORCH-10-common: расхардкод + секреты + smoke

Work Item: **ORCH-101** · Repo: **orchestrator** · Стадия: architecture

> Топология НЕ меняется (контейнеры/порты/сеть/тома — те же при дефолтах); меняется
> **параметризуемость** инфра-файлов. Раздел фиксирует карту переменных и правила раската.

## I-1. Топология / окружения

- **Без изменений при дефолтах:** те же 3 сервиса (`orchestrator` 8500, `orchestrator-watchdog`,
  `orchestrator-staging` 8501 под профилем `staging`), `network_mode: host`, те же тома и
  `group_add` docker-gid («МИНА 1» ORCH-040 — сохраняется, литерал → `${ORCH_DOCKER_GID:-999}`).
- `docker-compose.yml` переводится на интерполяцию `${VAR:-default}` (реестр ТЗ §3.1 B; карта —
  ADR-001 D6); `Dockerfile` получает `ARG APP_UID/APP_GID/APP_USER/APP_HOME` (D5); оба сервиса
  получают явный `command:` с портом из env (`${ORCH_DEPLOY_PROD_TARGET_PORT:-8500}` /
  `${ORCH_STAGING_PORT:-8501}`) — дефолтный резолв эквивалентен текущей конфигурации (AC-2/TC-06).
- **Источник интерполяции** — `.env` проекта / shell-окружение (НЕ `env_file` сервиса):
  интерполяционные значения тиража живут в `.env` (ADR-001 D1; попадает в REPLICATION.md).
- Имена сервисов/контейнеров/образов, профиль `staging`, `network_mode: host`, контейнерные пути
  (`/app/data`, `/repos`, `/opt/claude-code`) — платформенные константы (ADR-001 D3/D4/D6).

## I-2. Переменные окружения / секреты

**Новые `Settings`-ключи** (дефолт = боевому значению; см. ADR-001 D2/D4):

| env | Дефолт | Назначение |
|---|---|---|
| `ORCH_AGENT_HOME_DIR` | `/home/slin` | HOME акторских процессов (launcher ×2 / self-deploy / post-deploy) + таргеты маунтов + `APP_HOME` |
| `ORCH_AGENT_GIT_NAME` | `claude-bot` | git-имя агентских коммитов |
| `ORCH_GIT_EMAIL_DOMAIN` | `mva154.local` | домен git-email всех акторов (`<actor>@<domain>`) |
| `ORCH_STAGING_PORT` | `8501` | порт staging: `image_freshness` (c guard'ом ≠ прод-порт) + compose `command:` |

**Новые compose-only переменные:** `ORCH_HOST_CLAUDE_DIR`, `ORCH_HOST_CLAUDE_JSON`,
`ORCH_HOST_SSH_DIR`, `ORCH_HOST_CLAUDE_CODE_DIR`, `ORCH_HOST_NODE_BIN`, `ORCH_DOCKER_GID`,
`ORCH_RUN_UID`, `ORCH_RUN_GID` (дефолты — текущие значения; полная карта — ADR-001 D6).
**Реюз существующих имён:** `ORCH_HOST_REPOS_DIR`, `ORCH_DEPLOY_SSH_USER`,
`ORCH_DEPLOY_HOST_REPO_PATH`, `ORCH_DEPLOY_PROD_TARGET_PORT`, legacy `DEPLOY_HOOK_SCRIPT`.
**Deploy-hook:** `REPO="${REPO:-/home/slin/repos/orchestrator}"` + явная передача `REPO=` обоими
инвокерами (ADR-001 D7).

**Секреты (BR-3 / AC-5):** новый stdlib-скрипт `scripts/gen_secrets.py` — криптослучайные
`ORCH_PLANE_WEBHOOK_SECRET`/`ORCH_GITEA_WEBHOOK_SECRET` (`secrets.token_hex(32)`), печать по
умолчанию, `--write` с отказом при существующем `.env` (перезапись только `--force`). Внешние
токены (`ORCH_PLANE_API_TOKEN`, `ORCH_PLANE_BOT_*`, `ORCH_GITEA_TOKEN`, `ORCH_TELEGRAM_BOT_TOKEN`,
`WATCHDOG_TG_*`) — по чек-листу REPLICATION.md (где выпустить → куда вписать → как проверить).
Боевые секреты текущего хоста не покидают его (NFR-3); в гит — только шаблоны/плейсхолдеры
(правило агентов №8); `.env.example` доводится до 100% обязательных ключей, `.env.staging.example`
согласуется.

**Карта env в `docs/operations/INFRA.md`** дополняется всеми новыми ключами; deployment-раздел —
новый `docs/operations/REPLICATION.md` (FR-7). Чек-лист тиража обязывает: `ORCH_PROJECTS_JSON`
(fallback-реестр UUID'ов чужого Plane не сматчится), когерентность портов
`ORCH_DEPLOY_PROD_TARGET_PORT` ⇄ `WATCHDOG_METRICS_URL` ⇄ `ORCH_POST_DEPLOY_BASE_URL`.

## I-3. Деплой / рестарт

- **Рестарт прод-контейнера в рамках задачи — НЕ требуется и запрещён** (NFR-1, self-hosting):
  правки `docker-compose.yml`/`Dockerfile`/хука инертны до следующего штатного деплоя через
  конвейер (staging 8501 → ручной `Confirm Deploy`, ORCH-059).
- На текущем хосте ничего донастраивать не нужно: все дефолты = боевым значениям; пустой/
  неизменённый `.env` → поведение 1:1 (BR-5). Откат = не задавать переменные (NFR-2).
- Инвариант ORCH-058 сохранён и усилен: freshness-путь fail-closed отказывает при
  `ORCH_STAGING_PORT == прод-порт` (ADR-001 D4); INV-4 не затрагивается.

## I-4. CI/CD

- `.gitea/workflows/` — **без изменений**. Новые тесты (`test_no_host_hardcodes.py`,
  `test_host_config_keys.py`, `test_infra_parametrization.py`, `test_secrets_gen.py`,
  `test_replication_smoke.py`) попадают в существующие гейты (`check_ci_green`/
  `check_tests_passed`/merge-gate re-test) автоматически — новых QG не вводится (NFR-6).
- Новых pip/системных зависимостей нет (генератор секретов — stdlib).
