---
work_item: ORCH-101
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-10
model_used: claude-opus-4-8
---

# 01 — BRD (бизнес-требования): ORCH-101 — ORCH-10-common: расхардкод + секреты + smoke (фундамент тиража)

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

## 1. Бизнес-контекст и проблема

Эпик **ORCH-10** (домен 📈 D5 «Масштаб», `docs/epics/self-evolution.md`, D5.3) — тираж платформы
для раздачи **текущей** функциональности нескольким заказчикам **на тест**. Решения Славы 10.06:

- **Два типа тиража, оба stateless** (наши задачи/данные НЕ переносятся, чистый старт):
  - **Тип A (Lite):** перенос орк + watchdog на новую инфру; окружение донастраивается по чёткой
    инструкции.
  - **Тип B (Bundled):** весь стек (Plane/Gitea/орк) одним комплектом.
- **ORCH-101 = 10-common** — общий фундамент **обоих** типов. Без него ни Lite, ни Bundled не поедут.

**Проблема.** Платформа фактически прибита гвоздями к хосту `mva154`:

1. **Хардкоды хоста/окружения.** Аудит репо (стадия analysis, см. реестр в `02-trz.md` §3.1)
   подтвердил: в `src/**` есть код, который **обходит конфиг** — внешний URL Gitea
   `http://git.mva154.duckdns.org` зашит в `src/plane_sync.py`, `HOME=/home/slin` и git-идентичность
   `*@mva154.local` зашиты в трёх местах (`launcher`/`self_deploy`/`post_deploy`); в
   `docker-compose.yml` зашиты пути `/home/slin/...`, gid docker-группы `999`, uid `1000:1000`,
   node-пути; в `Dockerfile` — `useradd … -d /home/slin slin` и порт CMD; в
   `scripts/orchestrator-deploy-hook.sh` — `REPO=/home/slin/repos/orchestrator`. На новом хосте
   (другой пользователь, другие пути, другой gid docker, другие URL) платформа не заведётся без
   правки кода — это блокер тиража.
2. **Секреты.** Боевые секреты (`.env`) копировать на чужую инфраструктуру нельзя (общий
   webhook-secret = чужой хост сможет слать нам валидные вебхуки; утечка токенов). Механизма
   «сгенерировать НОВЫЙ комплект секретов на новом хосте» нет; `.env.example` не имеет чек-листа
   «что обязан заполнить оператор».
3. **Верификация.** Нет процедуры убедиться, что развёрнутая копия платформы **жива**: «завести
   тестовый проект + задачу → конвейер доехал». Без неё каждый тираж — слепой деплой.

**Ценность:** после ORCH-101 платформа разворачивается на новой инфре конфигурацией (env), с
собственными секретами и проверяется воспроизводимым smoke-прогоном. Это критический путь всего
эпика ORCH-10.

## 2. Объём (scope)

### В объёме

1. **Расхардкод** — вынести все хардкоды хоста/окружения в конфиг/env **с дефолтами, равными
   текущим значениям**: IP/hostname (`82.22.50.71`, `mva154`, `*.duckdns.org`), пути
   (`/home/slin/...`, `/repos`), порты (8500/8501/3000/8091), gid docker `999`, uid `1000`, имена
   контейнеров/сервисов/образов, URL Plane/Gitea, git-идентичность агентов. Зоны:
   `src/**`, `watchdog/**`, `docker-compose.yml`, `Dockerfile`, `scripts/`, `.env.example`.
   Аудит — **весь репо** (нормативный реестр находок — `02-trz.md` §3.1).
2. **Секреты** — механизм генерации **новых** секретов на новом хосте (webhook-секреты —
   криптослучайная генерация на месте; внешние токены Plane/Gitea/Telegram — выпуск на целевых
   системах по чек-листу). Полный шаблон `.env.example` с плейсхолдерами + чек-лист «что заполнить».
   Боевые секреты не покидают текущий хост.
3. **Smoke-верификация** — документированная воспроизводимая процедура (и/или скрипт-обвязка):
   «завести тестовый проект + задачу → конвейер доехал», с чёткими критериями PASS/FAIL.
4. **Анти-регресс** — структурный тест (grep-тест по образцу `tests/test_agent_prompts_canon.py`),
   запрещающий возврат хост-хардкодов в `src/**`.
5. **Доки** — deployment-раздел (параметризация, карта новых env-ключей, чек-лист секретов,
   smoke-процедура) + обновление карты env в `docs/operations/INFRA.md` + `CHANGELOG.md`.

### Вне объёма

- **Сама инструкция тиража Типа A (Lite) end-to-end** и **сборка комплекта Типа B (Bundled)** —
  отдельные задачи эпика ORCH-10; 10-common даёт им фундамент.
- **Перенос данных/задач/истории** — тираж stateless по решению Славы 10.06 (чистый старт).
- **Мультитенантность** (D5.6), горизонтальный воркер-пул (D5.4), IaC-автоматизация
  (Terraform/Ansible) — не сейчас.
- **Изменение конвейера**: `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / machine-verdict ключи /
  схема БД — не трогаются (задача конфигурационная, не процессная).
- **Расхардкод исторических документов** `docs/**`, `memory/**`, `CHANGELOG.md` — историческая
  правда не переписывается; аудит судит **код и инфра-файлы**, не архив.
- **`tests/**`** — тестам разрешены литералы как фикстуры/ожидания.
- **Onboarding-kit** (`onboarding/`, ORCH-009) — уже параметризован плейсхолдерами `{{NAME}}`;
  правится только при необходимости согласовать новые env-ключи.

## 3. Заинтересованные стороны

- **Слава (Owner)** — заказчик эпика ORCH-10; принимает BRD (гейт Approved) и прод-деплой
  (Confirm Deploy).
- **Будущие заказчики-тестеры** — потребители тиража Типов A/B (получают платформу на своей инфре).
- **Стрим** — оператор тиража: выполняет инструкцию, генерирует секреты, гоняет smoke.
- **Последующие задачи эпика ORCH-10 (Lite/Bundled)** — прямые потребители фундамента.
- **Агенты конвейера / self-hosting** — изменения катятся через общий прод-инстанс; регресс на
  текущем хосте недопустим (обслуживает и enduro-trails).

## 4. Бизнес-требования (BR)

- **BR-1 (расхардкод src)** — в `src/**` и `watchdog/**` не остаётся хост-специфичных литералов
  (IP/hostname/пути/порты/URL/идентичности), **обходящих конфиг**: каждое такое значение читается
  из `Settings` (env `ORCH_*` / `WATCHDOG_*`) с дефолтом, равным текущему боевому значению.
  Дефолты в `src/config.py` / `watchdog/config.py` — легитимное место значений по умолчанию.
- **BR-2 (расхардкод инфра-файлов)** — `docker-compose.yml`, `Dockerfile`,
  `scripts/orchestrator-deploy-hook.sh` параметризованы (compose-интерполяция `${VAR:-default}`,
  `ARG`, env-override соответственно); без заданных переменных конфигурация резолвится в текущие
  значения 1:1.
- **BR-3 (секреты)** — существует механизм получения **нового** комплекта секретов на новом хосте:
  генерируемые локально (webhook-секреты) создаются криптослучайно; выпускаемые внешними системами
  (токены Plane/Gitea/Telegram) перечислены в чек-листе с указанием, где их выпустить.
  `.env.example` покрывает 100% обязательных ключей. Копирование боевых секретов не требуется ни
  на одном шаге.
- **BR-4 (smoke)** — существует документированная воспроизводимая процедура верификации тиража:
  «развёрнутый инстанс → тестовый проект + задача → конвейер доехал», с момента старта до явного
  PASS/FAIL-критерия; воспроизводимость подтверждена прогоном на текущей инфре (staging-песочница
  8501 / sandbox-проект).
- **BR-5 (zero-regression)** — на текущем хосте поведение 1:1: все новые параметры имеют дефолты =
  сегодняшним значениям; пустой/неизменённый `.env` даёт байт-в-байт текущее поведение; полный
  `pytest tests/ -q` зелёный.
- **BR-6 (анти-регресс)** — возврат хост-хардкода в `src/**` ломает CI: структурный тест
  сканирует код (вне комментариев/докстрингов) на запрещённые литералы.
- **BR-7 (доки)** — deployment-раздел + карта env + чек-лист секретов + smoke-процедура
  опубликованы в `docs/operations/`; `CHANGELOG.md` обновлён (правило агентов №2).

## 5. Нефункциональные требования (NFR)

- **NFR-1 (self-hosting safety)** — задача не перезапускает и не роняет прод-контейнер
  `orchestrator`; правки `docker-compose.yml`/`Dockerfile` инертны до следующего штатного деплоя
  через конвейер (staging 8501 → Confirm Deploy). Никаких push/force-push в `main` мимо PR.
- **NFR-2 (обратимость)** — «kill-switch природа» параметризации: отсутствие новых env-переменных
  = текущее поведение. Отдельный функциональный kill-switch не требуется — дефолты и есть откат.
- **NFR-3 (секреты вне гита)** — реальные значения только в `.env`/`.env.staging` на хосте
  (правило агентов №8); в гит попадают только шаблоны/плейсхолдеры; генератор секретов никогда не
  перезаписывает существующий `.env` молча.
- **NFR-4 (инварианты соседних задач, правило №9)** — параметризация не ослабляет зафиксированные
  инварианты: ORCH-058 «freshness-путь целится ТОЛЬКО в staging, никогда в прод 8500»; ORCH-040
  «uid 1000 + group_add 999 (МИНА 1 — не удалять) + HOME согласован с маунтами»; INV-4 «мерж только
  через Gitea PR-merge API». Затронутые маркеры читаются перед правкой.
- **NFR-5 (стабильность анти-регресс теста)** — grep-тест детерминирован и не флапает: судит код,
  исключает комментарии/докстринги/`tests/**`/`docs/**`; список запрещённых литералов
  централизован в самом тесте.
- **NFR-6 (конвейер не трогаем)** — `STAGE_TRANSITIONS`, состав `QG_CHECKS`, семантика `check_*`,
  machine-verdict ключи, схема БД — байт-в-байт прежние.

## 6. Допущения и ограничения

- Целевой хост тиража: Linux + Docker + Compose; Plane и Gitea доступны (для Типа A — донастройка
  по инструкции Lite-задачи; их URL/токены подаются через env). Claude CLI присутствует на хосте
  (пути маунтов параметризуются).
- Тираж — **single-tenant**: один инстанс платформы на заказчика; общая мультитенантная топология
  вне объёма.
- Имя self-hosting репо платформы (`orchestrator`) — платформенная конвенция; делать ли его
  конфигурируемым (`SELF_HOSTING_REPO`) — решение архитектора (см. `02-trz.md` §3.4, вопрос А-2).
- Встроенный fallback-реестр проектов (`src/projects.py::_DEFAULT_PROJECTS`) содержит UUID'ы Plane
  текущего хоста; на новом хосте обязателен `ORCH_PROJECTS_JSON` — фиксируется в чек-листе, сами
  UUID'ы в дефолте безвредны (не сматчатся) и остаются как документированный fallback.
- Историческая документация и комментарии кода могут упоминать `mva154`/пути — это не хардкоды
  поведения и аудитом кода не считаются.

## 7. Критерии успеха

Платформа разворачивается на чужой инфре **без правки кода** — только env/конфиг; секреты
выпускаются заново по чек-листу; smoke-прогон даёт явный PASS; на текущем хосте — ноль изменений
поведения и зелёный полный регресс. Детальные условия PASS/FAIL — `03-acceptance-criteria.md`
(AC-1…AC-8); прослеживаемость BR ↔ AC — в сводной матрице там же.

## 8. Риски

Кратко (детально — `10-tech-risks.md`, заполняет архитектор):

- **Р-1: скрытый регресс при параметризации горячих путей** (`launcher` env агентов, compose
  volumes) — митигируется дефолтами = текущим значениям + полным регрессом + staging-прогоном.
- **Р-2: ослабление инварианта ORCH-058** при конфигуризации staging-порта (`_STAGING_PORT`) —
  митигируется guard-условием «staging-порт ≠ прод-порт» и решением архитектора (возможно,
  оставить константой с обоснованием).
- **Р-3: флап анти-регресс grep-теста** (ложные срабатывания на комментарии) — митигируется
  правилами исключений NFR-5.
- **Р-4: неполный аудит** (пропущенный хардкод всплывает на первом реальном тираже) — митигируется
  нормативным реестром §3.1 ТЗ + smoke-процедурой как последней линией обнаружения.
- **Р-5: расползание скоупа в Lite/Bundled** — митигируется явным «вне объёма» §2.
