architect(ET): auto-commit from architect run_id=603
All checks were successful
CI / test (push) Successful in 59s
All checks were successful
CI / test (push) Successful in 59s
This commit is contained in:
@@ -158,6 +158,43 @@ orchestrator (каноны ORCH-52b/c/d/e); enduro-trails эталоном не
|
||||
`docs/work-items/ORCH-009/06-adr/ADR-001-turnkey-onboarding-kit-and-cli.md` (D1…D11),
|
||||
`docs/work-items/ORCH-009/07-infra-requirements.md`.
|
||||
|
||||
## Тираж платформы: фундамент 10-common (ORCH-101 — design)
|
||||
|
||||
Фундамент эпика ORCH-10 (D5.3 «Масштаб»: раздача платформы заказчикам-тестерам, типы A Lite /
|
||||
B Bundled, оба stateless). Платформа разворачивается на новой инфре **без правки кода** — только
|
||||
env/конфиг; конвейер (`STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict/схема БД) —
|
||||
байт-в-байт не тронут. Три слоя:
|
||||
|
||||
- **Расхардкод по принципу «дефолт = боевое значение»** (kill-switch-природа: отсутствие новых
|
||||
переменных = текущее поведение 1:1). Новые ключи: `ORCH_AGENT_HOME_DIR` (HOME акторских
|
||||
процессов: launcher ×2 / self-deploy / post-deploy), `ORCH_AGENT_GIT_NAME` +
|
||||
`ORCH_GIT_EMAIL_DOMAIN` (git-идентичности `<actor>@<domain>`; системные имена
|
||||
`deploy-finalizer`/`post-deploy-monitor` — платформенные литералы), `ORCH_STAGING_PORT`.
|
||||
Ссылки в Plane-комментариях — из существующих `gitea_public_url`/`gitea_owner`.
|
||||
`docker-compose.yml` — интерполяция `${VAR:-default}` (карта `ORCH_HOST_*`/`ORCH_DOCKER_GID`/
|
||||
`ORCH_RUN_UID/GID`; группа ORCH-040 uid/gid/HOME/маунты двигается одними env насквозь, «МИНА 1»
|
||||
`group_add` сохранена); `Dockerfile` — `ARG APP_*` (CMD не трогается: exec-form + `init: true`);
|
||||
deploy-hook — `"${REPO:-…}"` + явная передача `REPO=` инвокерами. **Платформенные константы
|
||||
(нормативно, НЕ конфиг):** `SELF_HOSTING_REPO="orchestrator"` (узел «empty CSV → self-hosting
|
||||
only» всех `*_repos`-leaf'ов), имена сервисов/образов/профиля, контейнерный layout.
|
||||
**Инвариант ORCH-058 усилен:** staging-порт конфигурируем только с fail-closed guard'ом
|
||||
(`staging_port == прод-порт` → отказ freshness-пути ДО любого ssh/build, без тихого fallback).
|
||||
- **Секреты нового хоста:** stdlib `scripts/gen_secrets.py` (криптослучайные webhook-секреты
|
||||
`secrets.token_hex(32)`; печать по умолчанию; `--write` отказывает при существующем `.env`,
|
||||
перезапись — только явный `--force`) + чек-лист внешних токенов. Норматив: боевые секреты
|
||||
текущего хоста не копируются ни на одном шаге.
|
||||
- **Smoke-верификация тиража:** runbook `docs/operations/REPLICATION.md` (deployment golden
|
||||
source: карта env, чек-лист секретов, пошаговый smoke с PASS/FAIL — `/health` → `/queue`+
|
||||
`/metrics` → `onboard_project.py plan/apply/verify` → тестовая задача → артефакты `01–04`;
|
||||
расширенно — до `done`); без нового скрипта — кирпичи уже в репо. Анти-регресс — структурный
|
||||
сканер `tests/test_no_host_hardcodes.py` (запрещённые литералы в исполняемом коде
|
||||
`src/**`+`watchdog/**`; `tokenize`-исключение комментариев/докстрингов; config-модули — канон
|
||||
дефолтов, вне скана; allowlist пуст).
|
||||
|
||||
Подробнее: [adr-0036](adr/adr-0036-replication-foundation-host-parametrization.md), детально —
|
||||
`docs/work-items/ORCH-101/06-adr/ADR-001-host-parametrization-secrets-smoke.md` (D1…D10),
|
||||
`docs/work-items/ORCH-101/07-infra-requirements.md`, `10-tech-risks.md`.
|
||||
|
||||
## Конвейер и Quality Gates
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
work_item: ORCH-101
|
||||
stage: architecture
|
||||
author_agent: architect
|
||||
status: proposed
|
||||
created_at: 2026-06-10
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# adr-0036: Фундамент тиража платформы — параметризация хоста, секреты, smoke (ORCH-101, 10-common)
|
||||
|
||||
## Статус
|
||||
Proposed
|
||||
|
||||
## Контекст
|
||||
|
||||
Эпик ORCH-10 (D5.3 «Масштаб») — тираж платформы для заказчиков-тестеров двумя типами (A Lite /
|
||||
B Bundled), оба stateless. Платформа была фактически прибита к хосту `mva154`: четыре места в
|
||||
`src/**` обходили конфиг (внешний Gitea-URL в `plane_sync`, HOME + git-идентичности акторов в
|
||||
`launcher`/`self_deploy`/`post_deploy`), `docker-compose.yml`/`Dockerfile`/deploy-hook несли
|
||||
литералы путей/uid/gid/портов; механизма выпуска нового комплекта секретов и процедуры верификации
|
||||
развёрнутой копии не существовало. ORCH-101 (10-common) — общий фундамент обоих типов тиража.
|
||||
|
||||
Это сквозное решение: оно задаёт **платформенные конвенции тиража** и трогает блоки, помеченные
|
||||
маркерами ORCH-036/ORCH-040/ORCH-058 (по `docs/_standards/TRACEABILITY.md` — сводный ADR вместо
|
||||
архео-перечисления). Детальный пакет решений (D1…D10) — work-item ADR:
|
||||
`docs/work-items/ORCH-101/06-adr/ADR-001-host-parametrization-secrets-smoke.md`.
|
||||
|
||||
## Решение
|
||||
|
||||
**Принцип: «дефолт = боевое значение».** Каждое хост-специфичное значение читается из конфига
|
||||
(`Settings` env `ORCH_*` / compose-интерполяция `${VAR:-default}` / Dockerfile `ARG` /
|
||||
shell-default хука) с дефолтом, равным текущему боевому значению. Отсутствие новых переменных =
|
||||
байт-в-байт текущее поведение (kill-switch-природа; отдельный функциональный флаг не вводится).
|
||||
`src/config.py` и `watchdog/config.py` — единственные легитимные места хост-литералов в коде.
|
||||
|
||||
**Новые конфиг-ключи:** `agent_home_dir` (`ORCH_AGENT_HOME_DIR`, `/home/slin`) — HOME всех
|
||||
акторских процессов; `agent_git_name` (`claude-bot`) + `git_email_domain` (`mva154.local`) —
|
||||
git-идентичности (`<actor>@<domain>`; системные акторы `deploy-finalizer`/`post-deploy-monitor` —
|
||||
платформенные литералы); `staging_port` (`ORCH_STAGING_PORT`, `8501`). Ссылки в Plane-комментариях —
|
||||
из существующих `gitea_public_url`/`gitea_owner`. Compose-слой — карта `ORCH_HOST_*`/
|
||||
`ORCH_DOCKER_GID`/`ORCH_RUN_UID/GID` + реюз `ORCH_DEPLOY_*`; порт прод/стейджинг — явные `command:`
|
||||
с `${ORCH_DEPLOY_PROD_TARGET_PORT:-8500}` / `${ORCH_STAGING_PORT:-8501}` (CMD образа не трогается —
|
||||
exec-form + `init: true` сохранены).
|
||||
|
||||
**Платформенные конвенции тиража (нормативно):**
|
||||
1. **`SELF_HOSTING_REPO = "orchestrator"` — константа, не конфиг.** На ней «empty CSV →
|
||||
self-hosting only» всех `*_repos`-leaf'ов; конфигурируемость превращала бы опечатку env в
|
||||
активацию деплой-машинерии на чужом репо или тихое выключение всех self-гейтов. Репо платформы
|
||||
в тираже обязан называться `orchestrator` (REPLICATION.md).
|
||||
2. **Имена compose-сервисов/контейнеров/образов, профиль `staging`, `network_mode: host`,
|
||||
контейнерный layout (`/app/data`, `/repos`, `/opt/claude-code`)** — конвенции, не переменные
|
||||
(для образов истина уже в конфиге `deploy_prod_*_image`).
|
||||
3. **Staging-порт конфигурируем ТОЛЬКО с fail-closed guard'ом** (усиление инварианта ORCH-058
|
||||
AC-9): freshness-путь отказывает ДО любого ssh/build при
|
||||
`staging_port == deploy_prod_target_port` — без тихого fallback. Explicit-pass таргета хуку
|
||||
(`TARGET_PORT=` и др.) сохранён; добавлена явная передача `REPO=` обоими инвокерами хука
|
||||
(его строка 38 становится `"${REPO:-…}"` — exit-контракт 0/1/2 ORCH-036 не тронут).
|
||||
4. **Группа ORCH-040 неделима:** uid/gid/HOME/маунт-таргеты/`useradd` управляются одними env
|
||||
насквозь (`ORCH_RUN_UID/GID`, `ORCH_AGENT_HOME_DIR` → compose `user:`/таргеты/`build.args
|
||||
APP_*`); `group_add` docker-gid («МИНА 1») не удаляется — литерал станет
|
||||
`${ORCH_DOCKER_GID:-999}`.
|
||||
|
||||
**Секреты нового хоста:** stdlib-скрипт `scripts/gen_secrets.py` — криптослучайные webhook-секреты
|
||||
(`secrets.token_hex(32)`), печать по умолчанию, `--write` отказывает при существующем `.env`
|
||||
(перезапись — только явный `--force`); внешние токены (Plane/Gitea/Telegram/watchdog) — по
|
||||
чек-листу. Норматив: **боевые секреты текущего хоста не копируются ни на одном шаге**.
|
||||
|
||||
**Smoke-верификация тиража:** runbook `docs/operations/REPLICATION.md` (deployment golden source:
|
||||
карта env, чек-лист секретов, пошаговый smoke с PASS/FAIL: `compose config` → `/health` →
|
||||
`/queue`+`/metrics` → `onboard_project.py plan/apply/verify` → тестовая задача → артефакты `01–04`
|
||||
в ветке; расширенно — до `done`; границы 10-common vs Lite vs Bundled). Нового smoke-скрипта нет —
|
||||
шаги собраны из существующих кирпичей.
|
||||
|
||||
**Анти-регресс (постоянная CI-гарантия):** структурный сканер `tests/test_no_host_hardcodes.py` —
|
||||
запрещённые литералы (`82.22.50.71`, `/home/slin`, `mva154`, `duckdns`; список централизован) в
|
||||
исполняемом коде `src/**`+`watchdog/**`; `tokenize`-исключение комментариев/докстрингов;
|
||||
структурное исключение двух config-модулей (канон дефолтов); allowlist пуст; негативная
|
||||
самопроверка.
|
||||
|
||||
### Что НЕ меняется
|
||||
`STAGE_TRANSITIONS`, состав `QG_CHECKS`, семантика `check_*`, machine-verdict ключи, схема БД —
|
||||
байт-в-байт; значения существующих конфиг-дефолтов; INV-4; прод-контейнер в рамках задачи не
|
||||
рестартуется (правки compose/Dockerfile инертны до штатного деплоя через staging 8501 →
|
||||
`Confirm Deploy`).
|
||||
|
||||
## Альтернативы
|
||||
- **`ORCH_SELF_HOSTING_REPO` конфигом** — отвергнуто: узел безопасности; опечатка = групповой риск.
|
||||
- **Staging-порт константой** — отвергнуто: compose-порт параметризуется (AC-6), константа дала бы
|
||||
рассинхрон слоёв; пара «ключ + guard» строго сильнее.
|
||||
- **Smoke-скрипт-обвязка / генератор в `onboard_project.py`** — отвергнуто: лишняя поверхность;
|
||||
разные жизненные циклы (онбординг проекта ≠ provisioning хоста).
|
||||
|
||||
## Последствия
|
||||
- Платформа разворачивается на чужой инфре env-конфигурацией; критический путь ORCH-10 разблокирован
|
||||
(Lite/Bundled строятся поверх REPLICATION.md).
|
||||
- Инвариант ORCH-058 переходит из «подразумеваемого константой» в исполняемый guard; возврат
|
||||
хост-хардкода ломает CI структурно.
|
||||
- Цена: ~13 новых env-имён (на текущем хосте настраивать нечего — дефолты боевые) и правило
|
||||
«интерполяция читает `.env`/shell, не `env_file`» (зафиксировано в REPLICATION.md).
|
||||
- Откат: не задавать переменные (дефолты = прежнее поведение); полный — revert PR (без миграций).
|
||||
|
||||
## Связи
|
||||
adr-0005 (ORCH-040 — uid/HOME/«МИНА 1»; группа становится параметризуемой, инвариант сохранён),
|
||||
adr-0008 (ORCH-058 — INV-FRESH/AC-9; guard усиливает), adr-0007 (ORCH-036 — exit-контракт хука
|
||||
не тронут), adr-0035 (ORCH-009 — onboarding переиспользуется smoke-процедурой; kit не форкается),
|
||||
adr-0001 (`is_self_hosting_repo` — конвенция имени закреплена). Детально —
|
||||
`docs/work-items/ORCH-101/06-adr/ADR-001-host-parametrization-secrets-smoke.md` (D1…D10),
|
||||
`07-infra-requirements.md`, `10-tech-risks.md`.
|
||||
Reference in New Issue
Block a user