developer(ET): auto-commit from developer run_id=642
This commit is contained in:
@@ -245,7 +245,7 @@ Type B). Анти-дрейф — `tests/test_bundle_compose.py` / `test_bundled_
|
||||
[adr-0038](adr/adr-0038-bundled-replication-canon.md), детально —
|
||||
`docs/work-items/ORCH-103/06-adr/ADR-001-bundled-stack-compose-and-bootstrap.md`.
|
||||
|
||||
**Интерактивный installer Lite (ORCH-104 — design).** Lite получает инструмент, симметричный
|
||||
**Интерактивный installer Lite (ORCH-104).** Lite получает инструмент, симметричный
|
||||
Bundled-bootstrap'у: **`scripts/setup_lite.py`** — python stdlib-only wizard, автоматизирующий
|
||||
маршрут LITE_SETUP §2–§12 (скан предусловий с офером доустановки per-package consent'ом;
|
||||
discovery docker-инсталляций Plane/Gitea строго по image-префиксам с выбором пользователя;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
> Хост-специфика в командах — только плейсхолдеры `<...>` и `$ENV_VAR`.
|
||||
> Тираж **stateless**: данные/задачи/секреты исходного (боевого) хоста **НЕ переносятся**
|
||||
> ни на одном шаге — всё создаётся заново (§12).
|
||||
> **Быстрый путь — `scripts/setup_lite.py`** (§1.1): интерактивный installer проводит по
|
||||
> §2–§12 за один прогон; ручной маршрут ниже остаётся каноном и fallback'ом.
|
||||
|
||||
---
|
||||
|
||||
@@ -32,6 +34,35 @@ compose-файле, но строго за профилем `staging` и в ба
|
||||
- контейнерные пути (`/app/data`, `/repos`, `/opt/claude-code`) — layout контейнера,
|
||||
не хост-значения; не параметризуются.
|
||||
|
||||
### 1.1. Быстрый путь: `setup_lite.py` (рекомендуется)
|
||||
|
||||
Вместо ручного прохода §2–§12 запустите **интерактивный installer** — он сканирует
|
||||
предусловия хоста и предлагает доустановить недостающее, обнаруживает ваши инсталляции
|
||||
Plane/Gitea (при нескольких — даёт выбрать), запрашивает обязательные ключи **в момент
|
||||
установки с немедленной верификацией**, автодетектит хост-параметры, собирает
|
||||
`.env`/`.env.watchdog` от канонов (свежие webhook-секреты — кирпичом `gen_secrets.py`),
|
||||
поднимает ровно орк+watchdog и регистрирует ваш проект строго кирпичом `onboard_project.py`.
|
||||
|
||||
```bash
|
||||
cd <путь-чекаута> # корень репо orchestrator
|
||||
python3 scripts/setup_lite.py # apply (дефолт): интерактивная установка
|
||||
python3 scripts/setup_lite.py plan # read-only диагностика (ноль мутаций)
|
||||
python3 scripts/setup_lite.py verify # read-only пост-проверка контура
|
||||
```
|
||||
|
||||
**Контракт:** дефолт-режим `apply` — установка «одной командой»; безопасность дефолта
|
||||
структурна — фаза 0 любого `apply` ≡ `plan` (read-only скан), каждая мутация хоста — с
|
||||
**явного согласия** (per-action consent с печатью точной команды), существующий чужой
|
||||
`.env`/`.env.watchdog` **не перетирается** без `--force` (guard managed-маркера), в
|
||||
non-TTY без `--yes` — честный выход без зависания. Exit-коды: `0` — все шаги PASS; `2` —
|
||||
остановка на ручном шаге (повторный запуск продолжит с него — resume); `1` — ошибка.
|
||||
Секреты вводятся скрыто и **никогда не печатаются**; delete-операций скрипт не выполняет
|
||||
(лечение — всегда инструкция). Любой ручной шаг ссылается на соответствующий § ниже —
|
||||
ручной маршрут §2–§13 остаётся полным каноном и fallback'ом для MANUAL-шагов.
|
||||
|
||||
**Проверка:** `python3 scripts/setup_lite.py plan` завершается без блокеров (exit 0) —
|
||||
PASS; есть блокеры (exit 2) — устраните по выводу и повторите.
|
||||
|
||||
---
|
||||
|
||||
## 2. Предусловия хоста
|
||||
@@ -588,9 +619,10 @@ PR-merge API оркестратора, ручной merge не требуетс
|
||||
|
||||
---
|
||||
|
||||
*Golden source Lite-тиража (ORCH-102, ADR-001). **Норматив сопровождения (NFR-5):**
|
||||
меняешь шаги тиража (env-ключи, compose-сервисы, маршрут онбординга, smoke) → обнови
|
||||
этот док В ТОМ ЖЕ PR (правило агентов №2). Полноту и гигиену дока держит структурный
|
||||
*Golden source Lite-тиража (ORCH-102, ADR-001). **Норматив сопровождения (NFR-5, расширен
|
||||
ORCH-104):** меняешь шаги тиража (env-ключи, compose-сервисы, маршрут онбординга, smoke) →
|
||||
обнови этот док **И установочный скрипт `scripts/setup_lite.py`** В ТОМ ЖЕ PR (правило
|
||||
агентов №2). Полноту и гигиену дока держит структурный
|
||||
анти-дрейф тест `tests/test_lite_setup_doc.py`; кирпичи-каноны: REPLICATION.md (карта
|
||||
env §2, секреты §3, smoke §4), ONBOARDING.md (статусы §1, онбординг), SETUP_WEBHOOKS.md
|
||||
(формат вебхуков), `.env.example` / `.env.watchdog.example` (канон ключей).*
|
||||
|
||||
@@ -426,3 +426,45 @@ def test_replication_boundaries_reference_lite_setup():
|
||||
|
||||
def test_changelog_has_orch_102_entry():
|
||||
assert "ORCH-102" in CHANGELOG.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TC-27 (ORCH-104, FR-11 / D12): LITE_SETUP.md вводит установочный скрипт как
|
||||
# рекомендованный быстрый путь и сохраняет ручной маршрут (пиннинг «13 разделов»
|
||||
# в порядке держит test_doc_exists_with_all_13_sections_in_order — не трогается).
|
||||
# ---------------------------------------------------------------------------
|
||||
def test_doc_introduces_setup_lite_fast_path():
|
||||
text = _doc_text()
|
||||
assert "setup_lite.py" in text, (
|
||||
"LITE_SETUP.md не вводит установочный скрипт setup_lite.py (ORCH-104 FR-11)"
|
||||
)
|
||||
# быстрый путь — подраздел §1.1 ВНУТРИ §1 (нумерация ## 1.…## 13. не меняется)
|
||||
body1 = _section_bodies()["## 1. Рамка Lite"]
|
||||
assert "1.1" in body1 and "setup_lite.py" in body1, (
|
||||
"быстрый путь обязан быть подразделом §1.1 внутри §1 (D12)"
|
||||
)
|
||||
# ручной маршрут сохранён как канон/fallback — упомянут явно
|
||||
assert "fallback" in text.lower() or "ручной маршрут" in text, (
|
||||
"ручной маршрут §2–§13 обязан остаться каноном/fallback (FR-11)"
|
||||
)
|
||||
# норматив сопровождения расширен на скрипт (D12)
|
||||
assert "scripts/setup_lite.py" in text
|
||||
|
||||
|
||||
def test_setup_lite_fast_path_block_is_clean():
|
||||
"""§1.1 fenced-блок проходит те же сканы, что весь док: без боевых литералов,
|
||||
без секретоподобных значений, без неизвестных env-токенов."""
|
||||
body1 = _section_bodies()["## 1. Рамка Lite"]
|
||||
blocks = _fenced_blocks(body1)
|
||||
assert blocks, "§1.1 обязан нести fenced-блок с командой запуска (D12)"
|
||||
for i, block in enumerate(blocks):
|
||||
for literal in FORBIDDEN:
|
||||
assert literal not in block, f"§1.1 блок #{i}: боевой литерал {literal!r}"
|
||||
for rx in (_SECRET_HEX_RE, _SECRET_ALNUM_RE):
|
||||
assert rx.search(block) is None, f"§1.1 блок #{i}: секретоподобное значение"
|
||||
# упомянутые в §1.1 env-токены (если есть) — только из канона .env.example
|
||||
canon = _env_keys(ENV_EXAMPLE)
|
||||
mentioned = set(_ENV_TOKEN_RE.findall(body1))
|
||||
assert not (mentioned - canon), (
|
||||
f"§1.1 упоминает env-токены вне .env.example: {sorted(mentioned - canon)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user