Files
claude-bot 69aa6eacde
All checks were successful
CI / test (push) Successful in 1m9s
analyst(ET): auto-commit from analyst run_id=602
2026-06-10 20:02:14 +03:00

176 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.