analyst(ET): auto-commit from analyst run_id=653
All checks were successful
CI / test (push) Successful in 58s
All checks were successful
CI / test (push) Successful in 58s
This commit is contained in:
187
docs/work-items/ORCH-104/01-brd.md
Normal file
187
docs/work-items/ORCH-104/01-brd.md
Normal file
@@ -0,0 +1,187 @@
|
||||
---
|
||||
work_item: ORCH-104
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-12
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 01 — BRD (бизнес-требования): ORCH-104 — Установочный скрипт для Lite
|
||||
|
||||
Work Item: **ORCH-104** · Repo: **orchestrator** (self-hosting) · Стадия: analysis
|
||||
Тип: FEATURE — UX/онбординг тиража (Type A эпика ORCH-10), поверх ORCH-102 (LITE_SETUP.md)
|
||||
|
||||
> ⚠️ **Объём заморожен (2026-06-12).** Один интерактивный установщик, автоматизирующий
|
||||
> ручной маршрут `docs/deployment/LITE_SETUP.md`. Это **scripts + docs + tests**-изменение:
|
||||
> рантайм/конвейер (`src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, схема БД) — **не трогаются**
|
||||
> (см. §2 «Вне объёма», NFR-1). Установщик НЕ форкает каноны: секреты — кирпичом
|
||||
> `gen_secrets.py`, онбординг — кирпичом `onboard_project.py`, env — из `.env.example`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Бизнес-контекст и проблема
|
||||
|
||||
### 1.1. Цель
|
||||
Максимально упростить установку оркестратора в Lite-режиме на чужой хост: свести
|
||||
тринадцатишаговую ручную инструкцию к **одному запускаемому файлу**, который сам сканирует
|
||||
систему, подсказывает чего не хватает, запрашивает у оператора только действительно
|
||||
неизвестные данные (токены/URL) и доводит инсталляцию до работающего конвейера.
|
||||
|
||||
### 1.2. Корневая боль (установленный факт)
|
||||
`docs/deployment/LITE_SETUP.md` (ORCH-102) — золотой источник Lite-тиража, но это **ручной
|
||||
runbook из 13 разделов**. Оператор вручную: проверяет предусловия хоста (§2), клонирует код (§3),
|
||||
копирует `.env.example`, гоняет `gen_secrets.py`, **заполняет ~20 ключей `.env`** по четырём
|
||||
группам (Plane/Gitea/Telegram/хост-порты, §4), настраивает webhook Plane (иногда **прямым SQL в
|
||||
Postgres**, §5.4 путь Б), выпускает токен и webhook Gitea (§6), ставит claude CLI (§7), заводит
|
||||
**два** Telegram-бота (§8), поднимает compose (§9), регистрирует проект `onboard_project.py` (§10),
|
||||
гоняет smoke (§11). Это долго, легко ошибиться (опечатка в секрете → 401 HMAC; неверный uid →
|
||||
worktree не пишется; занятый порт; пропущенный fail-closed статус `Confirm Deploy`/`STOP`), и
|
||||
ошибка часто всплывает поздно — на `docker compose up`, а не в момент ввода.
|
||||
|
||||
### 1.3. Почему именно установщик (а не «ещё инструкция»)
|
||||
Ручной маршрут уже задокументирован и стабилен (ORCH-102). Ценность ORCH-104 — **автоматизация
|
||||
happy-path и ранняя валидация**: авто-детект всего детектируемого (uid/gid/docker-gid, свободные
|
||||
порты, node/claude, **существующие инсталляции Plane/Gitea**), живая проверка каждого введённого
|
||||
секрета ДО записи в `.env`, идемпотентный безопасный повтор. LITE_SETUP.md остаётся справочником
|
||||
и фолбэком для траблшутинга — установщик его не заменяет, а исполняет.
|
||||
|
||||
### 1.4. Установленные факты (переиспользуемые кирпичи — НЕ изобретать)
|
||||
- **`scripts/bootstrap_bundle.py` (ORCH-103)** — ближайший прецедент: step-движок `check→ensure`,
|
||||
режимы `plan`/`apply`/`verify`, exit-коды `0/2/1`, честные `manual_checkpoint` с
|
||||
`input()`/`getpass()`, stdlib-only, секреты не печатаются, **delete-операций нет вообще**,
|
||||
каноны переиспользуются субпроцессами. Установщик Lite — его «connect-only»-сородич: bundle
|
||||
*поднимает* Plane/Gitea, Lite *подключается* к уже существующим.
|
||||
- **`scripts/gen_secrets.py` (ORCH-101)** — выпуск webhook-секретов (`secrets.token_hex(32)`),
|
||||
отказ перезаписи без `--force`. Единственный легитимный источник секретов.
|
||||
- **`scripts/onboard_project.py` (ORCH-009)** — регистрация проекта (22 статуса с точными
|
||||
именами, лейблы `autoApprove`/`autoDeploy`/`Bug`, репо+webhook), `plan`/`apply`/`verify`,
|
||||
идемпотентно, exit `0/2/1`.
|
||||
- **`.env.example` / `.env.watchdog.example`** — канон 100% ключей старта (дефолт каждого ключа =
|
||||
боевому значению, ORCH-101); установщик рендерит `.env` из них, не выдумывая ключи.
|
||||
- **`docker-compose.yml`** — сам по себе является Lite-подмножеством (дефолтный `up -d` поднимает
|
||||
ровно `orchestrator` + `orchestrator-watchdog`; `orchestrator-staging` за профилем `staging`).
|
||||
|
||||
### 1.5. Решения владельца (Owner decisions)
|
||||
Предложены Владельцу как рекомендованные дефолты 2026-06-12; приняты для старта анализа,
|
||||
пересматриваемы на review.
|
||||
|
||||
| ID | Решение | Дата |
|
||||
|----|---------|------|
|
||||
| D-1 | **Установка зависимостей = детект + управляемая установка.** Установщик сканирует, показывает чего не хватает, печатает **точную команду** под обнаруженный дистрибутив и предлагает выполнить безопасные с явного согласия (`y/N`). Системные пакеты под root — только с подтверждением, **никогда молча**. (Совпадает с self-hosting-этосом и каноном `bootstrap_bundle.py`.) | 2026-06-12 |
|
||||
| D-2 | **Plane/Gitea = только подключение (Lite = Type A).** Установщик **детектит существующие** инсталляции; при нескольких — показывает нумерованный список и даёт выбрать; ручной ввод URL — всегда фолбэк. Если их нет вовсе → инструктирует поставить самостоятельно либо указывает на Bundled-тираж (ORCH-103). Установщик их **не поднимает**. | 2026-06-12 |
|
||||
| D-3 | **Режимы = интерактивный мастер + `plan`/`apply`/`verify`.** Канон `bootstrap_bundle.py`: `plan` (дефолт, ноль мутаций) / `apply` / `verify`; exit `0/2/1`; без TTY → fail-closed exit 2 с инструкцией; идемпотентный повтор. Скрипт пригоден и для повторного/CI-прогона. | 2026-06-12 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Объём (scope)
|
||||
|
||||
### В объёме
|
||||
- **FR-1** — Единый entry-point `scripts/install_lite.py` с режимами `plan`/`apply`/`verify`.
|
||||
- **FR-2** — Скан-предусловий хоста (детект docker/compose/git/python3/node/claude CLI/портов/
|
||||
uid/gid/docker-gid/каталогов) с понятным списком «чего не хватает».
|
||||
- **FR-3** — Управляемая установка недостающих зависимостей (детект дистрибутива → точная команда →
|
||||
выполнение безопасных с согласия; D-1).
|
||||
- **FR-4** — Детект существующих инсталляций Plane/Gitea на хосте + выбор при нескольких + ручной
|
||||
фолбэк (D-2).
|
||||
- **FR-5** — Интерактивный сбор данных оператора (Plane/Gitea/Telegram токены/URL) с **живой
|
||||
верификацией каждого ДО записи** и скрытым вводом секретов.
|
||||
- **FR-6** — Выпуск webhook-секретов строго кирпичом `gen_secrets.py`.
|
||||
- **FR-7** — Сборка `.env` / `.env.watchdog` из канона `.env.example` / `.env.watchdog.example`
|
||||
(идемпотентный рендер, права 600, без молчаливой перезаписи).
|
||||
- **FR-8** — Подъём `orchestrator` + `orchestrator-watchdog` (`docker compose up`) + ожидание
|
||||
готовности.
|
||||
- **FR-9** — Регистрация проекта строго кирпичом `onboard_project.py apply`/`verify` + запись
|
||||
`ORCH_PROJECTS_JSON`.
|
||||
- **FR-10** — Health-верификация (`/health` / `/queue` / `/metrics`) + итоговая сводка PASS/FAIL.
|
||||
- **FR-11** — Синхронизация документации (указатель LITE_SETUP.md на установщик; CLAUDE/README/
|
||||
overview/CHANGELOG).
|
||||
|
||||
### Вне объёма
|
||||
- ❌ **Любые изменения рантайма/конвейера** — `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`,
|
||||
machine-verdict ключи, схема БД (NFR-1; установщик вне процесса орка и вне конвейера QG).
|
||||
- ❌ **Подъём самих Plane/Gitea** — это Bundled-тираж (ORCH-103); Lite только подключается (D-2).
|
||||
- ❌ **Полный безусловный авто-install системных пакетов под root без согласия** (D-1 отвергает).
|
||||
- ❌ **Teardown / удаление** — установщик не несёт delete-операций (NFR-4); снос — документированная
|
||||
процедура.
|
||||
- ❌ **Замена LITE_SETUP.md** — runbook остаётся золотым источником и фолбэком (дополняем, не
|
||||
выкидываем).
|
||||
- ❌ **Форк канонов** — секреты/онбординг/env/compose не реимплементируются (NFR-7).
|
||||
- ❌ **Автоматизация интерактивного логина claude CLI** — это поток Anthropic; остаётся
|
||||
верифицируемым manual-step (OQ-6).
|
||||
|
||||
---
|
||||
|
||||
## 3. Заинтересованные стороны
|
||||
- **Заказчик/инициатор:** Владелец (Слава) — цель «максимально упростить установку для пользователей».
|
||||
- **Прямой пользователь:** внешний оператор/заказчик платформы, разворачивающий Lite на своём хосте.
|
||||
- **Затрагиваемые:** сопровождающие LITE_SETUP.md (норматив синхронизации, BR-9); агенты
|
||||
пайплайна (reviewer — проверка doc-sync; tester — прогон новых тестов).
|
||||
- **Принимает результат:** reviewer (стадия review) + tester (стадия testing) по критериям §03.
|
||||
|
||||
---
|
||||
|
||||
## 4. Бизнес-требования (BR)
|
||||
|
||||
| ID | Требование | Связь |
|
||||
|----|------------|-------|
|
||||
| **BR-1** | Один запускаемый файл проводит оператора от «код склонирован» до «работающий Lite-конвейер», автоматизируя LITE_SETUP.md §2–§11. | FR-1, AC-1 |
|
||||
| **BR-2** | Установщик сканирует хост и выдаёт чёткий список отсутствующих предусловий (что есть / чего не хватает). | FR-2, AC-2 |
|
||||
| **BR-3** | Для каждого недостающего предусловия — точная команда установки под обнаруженный дистрибутив + предложение выполнить безопасные с явного согласия (никогда молча, D-1). | FR-3, AC-3 |
|
||||
| **BR-4** | Данные, которые знает только оператор (токены/URL Plane, Gitea, Telegram), запрашиваются интерактивно в момент установки, **каждое — с живой проверкой ДО записи**; секреты вводятся скрыто и не логируются. | FR-5, AC-5, AC-6 |
|
||||
| **BR-5** | Установщик детектит существующие инсталляции Plane и Gitea; при нескольких — показывает список и даёт выбрать; ручной ввод URL — всегда доступный фолбэк (D-2). | FR-4, AC-4 |
|
||||
| **BR-6** | Каноны не форкаются: webhook-секреты — `gen_secrets.py`, регистрация проекта — `onboard_project.py`, env — из `.env.example`/`.env.watchdog.example`, стек — из `docker-compose.yml`. | FR-6, FR-7, FR-9, AC-7 |
|
||||
| **BR-7** | Идемпотентность и наблюдаемость: режимы `plan`(дефолт)/`apply`/`verify`; повтор пропускает завершённые шаги; exit `0/2/1`; без TTY → fail-closed exit 2 с инструкцией; финальная сводка PASS/FAIL. | FR-1, FR-10, AC-8, AC-11 |
|
||||
| **BR-8** | Self-hosting-безопасность: установщик — только scripts/docs/tests; никогда не правит `src/**`/конвейер/схему; исполняется на хосте заказчика; говорит только с локальным хостом и собственными Plane/Gitea/Telegram заказчика; delete-операций нет. | NFR-1, NFR-4, AC-9, AC-10 |
|
||||
| **BR-9** | Норматив сопровождения: установщик автоматизирует LITE_SETUP.md → оба держатся в синхроне (меняешь шаги установки → обнови LITE_SETUP.md в том же PR; держит анти-дрейф тест). | FR-11, AC-12 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Нефункциональные требования (NFR)
|
||||
|
||||
| ID | Требование |
|
||||
|----|------------|
|
||||
| **NFR-1** | **Рантайм байт-в-байт.** `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`, machine-verdict ключи, схема БД — не трогаются. Kill-switch не нужен: активация = только явный запуск оператором (паттерн ORCH-009/102/103). |
|
||||
| **NFR-2** | **Гигиена секретов.** Значения секретов никогда не печатаются в stdout/логи; `.env`/`.env.watchdog` пишутся правами 600; существующие секреты не перетираются без явного согласия/`--force`. |
|
||||
| **NFR-3** | **Never-raise в детекте.** Сбой любой эвристики обнаружения/пробы деградирует на ручной ввод и не роняет установщик и не блокирует прогон (best-effort, fail-safe). |
|
||||
| **NFR-4** | **Нет delete-операций** нигде в скрипте (teardown — только документированная процедура; зеркало ORCH-103 D9). |
|
||||
| **NFR-5** | **Идемпотентный ensure.** Каждый шаг `check→ensure`; повтор безопасен; валидный существующий конфиг пропускается; дублей проекта/webhook не создаётся. |
|
||||
| **NFR-6** | **stdlib-only.** Никаких новых зависимостей платформы — работает на голом `python3` целевого хоста ДО первого `docker compose up` (как `gen_secrets.py`/`bootstrap_bundle.py`). Каноны-знания — только субпроцессами кирпичей. |
|
||||
| **NFR-7** | **Детерминированные анти-дрейф тесты.** В unit-тестах — без сети/docker/subprocess/LLM; чистые функции изолированы; HTTP/процессы — через инъекцию фейков. |
|
||||
| **NFR-8** | **Кросс-дистрибутив.** Детект и команды установки работают на распространённых Linux (Debian/Ubuntu `apt`, RHEL/Fedora `dnf`); неизвестный дистрибутив → деградация на «инструктировать». |
|
||||
|
||||
---
|
||||
|
||||
## 6. Допущения и ограничения
|
||||
- **Контур Lite** (LITE_SETUP §1–§2): Linux x86_64, у оператора есть root/sudo для установки
|
||||
системных пакетов (или он ставит их сам). Вне контура — вне гарантии.
|
||||
- **Plane и Gitea — собственные инсталляции заказчика** (Type A). Установщик к ним подключается,
|
||||
не управляет их жизненным циклом.
|
||||
- **Plane CE не даёт API первичной инициализации/иногда webhook** (LITE_SETUP §5.4): такие шаги
|
||||
остаются честными manual-step с верификацией результата (контракт `manual_checkpoint`).
|
||||
- **Интерактивный логин claude CLI** не автоматизируется (поток Anthropic) — manual-step (OQ-6).
|
||||
- **Платформенные конвенции (не менять):** репо обязан называться `orchestrator`
|
||||
(`SELF_HOSTING_REPO`); имена compose-сервисов/профиля — константы; `ORCH_STAGING_PORT` ≠
|
||||
прод-порт (fail-closed guard ORCH-058).
|
||||
|
||||
---
|
||||
|
||||
## 7. Критерии успеха (резюме)
|
||||
Оператор на свежем хосте запускает один файл, отвечает на минимум вопросов (только то, что
|
||||
система не может определить сама), и получает поднятый Lite-контур с зарегистрированным проектом и
|
||||
зелёными `/health` `/queue` `/metrics`. Повторный запуск безопасен и пропускает сделанное. Рантайм
|
||||
не изменён. Детальные PASS/FAIL — в `03-acceptance-criteria.md`.
|
||||
|
||||
---
|
||||
|
||||
## 8. Риски (кратко; детали — 10-tech-risks.md, заполняет архитектор)
|
||||
- **R-1** — Эвристика детекта Plane/Gitea ложно-положительна/отрицательна (нестандартные имена
|
||||
контейнеров/порты) → митигируется ручным фолбэком (NFR-3) и живой верификацией URL (BR-4).
|
||||
- **R-2** — Авто-install системных пакетов небезопасен/дистрибутиво-зависим → митигируется D-1
|
||||
(только с согласия, точная команда, неизвестный дистрибутив → инструктировать).
|
||||
- **R-3** — Дрейф установщик ↔ LITE_SETUP.md при будущих правках → митигируется BR-9 + анти-дрейф
|
||||
тестом.
|
||||
- **R-4** — Случайная утечка секрета в лог/перетирание `.env` → митигируется NFR-2 (маскирование,
|
||||
600, без silent overwrite), покрыто AC-6.
|
||||
- **R-5** — Дублирование логики `bootstrap_bundle.py` (parse_env/render_env/manual_checkpoint) →
|
||||
архитектурный вопрос «общий модуль vs самодостаточный файл» (OQ-4), не блокирует анализ.
|
||||
193
docs/work-items/ORCH-104/02-trz.md
Normal file
193
docs/work-items/ORCH-104/02-trz.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
work_item: ORCH-104
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-12
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 02 — ТЗ (TRZ): ORCH-104 — Установочный скрипт для Lite
|
||||
|
||||
Work Item: **ORCH-104** · Repo: **orchestrator** · Стадия: analysis
|
||||
|
||||
> ТЗ описывает **конкретные требования к реализации**, выведенные из BRD и фактического кода.
|
||||
> Архитектурное обоснование (структура скрипта, точные эвристики детекта, общий код с
|
||||
> `bootstrap_bundle.py`, финальное имя файла) — задача архитектора (`06-adr/`). Открытые вопросы —
|
||||
> §12.
|
||||
|
||||
## 1. Сводка изменения
|
||||
Добавляется **один интерактивный установщик** `scripts/install_lite.py`, автоматизирующий ручной
|
||||
маршрут `docs/deployment/LITE_SETUP.md` §2–§11 для Lite-тиража (Type A). Скрипт сканирует хост,
|
||||
детектит/предлагает доустановить зависимости, обнаруживает существующие Plane/Gitea (выбор при
|
||||
нескольких), интерактивно собирает и **живо верифицирует** токены/URL, выпускает секреты кирпичом
|
||||
`gen_secrets.py`, собирает `.env`/`.env.watchdog` из канон-`.example`, поднимает `orchestrator` +
|
||||
`orchestrator-watchdog`, регистрирует проект кирпичом `onboard_project.py` и проверяет health.
|
||||
Изменение **аддитивно** и **вне рантайма**: `src/**`/`STAGE_TRANSITIONS`/`QG_CHECKS`/схема БД — не
|
||||
трогаются; kill-switch не нужен (активация — только явный запуск). Каноны не форкаются.
|
||||
|
||||
## 2. Задействованные модули / пути
|
||||
|
||||
| Путь | Действие |
|
||||
|------|----------|
|
||||
| `scripts/install_lite.py` | **создать** — интерактивный установщик Lite (entry-point; имя — OQ-1) |
|
||||
| `scripts/gen_secrets.py` | **переиспользовать** (subprocess-кирпич), без изменений |
|
||||
| `scripts/onboard_project.py` | **переиспользовать** (subprocess-кирпич, `apply`/`verify`), без изменений |
|
||||
| `.env.example`, `.env.watchdog.example` | **переиспользовать** как канон-источник рендера, без изменений |
|
||||
| `docker-compose.yml` | **переиспользовать** (`docker compose up -d --build`), без изменений |
|
||||
| `scripts/bootstrap_bundle.py` | **эталон-паттерн** (parse_env/render_env/preflight_verdict/manual_checkpoint/exit-коды) — не изменяется; общий код — OQ-4 |
|
||||
| `docs/deployment/LITE_SETUP.md` | **обновить** — указатель на установщик как рекомендованный путь + синхронизация шагов |
|
||||
| `tests/test_install_lite_script.py` | **создать** — unit (чистые функции) + структурные анти-дрейф тесты |
|
||||
| `tests/test_lite_setup_doc.py` | **обновить** — ассерт ссылки на установщик; существующие ассерты зелёные |
|
||||
| `CLAUDE.md`, `CHANGELOG.md`, `docs/architecture/README.md`, `docs/overview/` | **обновить** (docs golden-source, правило агентов №2) |
|
||||
|
||||
## 3. Функциональные требования
|
||||
|
||||
### FR-1 — Entry-point и режимы
|
||||
Скрипт `scripts/install_lite.py`, запускаемый из корня чекаута: `argparse`, позиционный `mode ∈
|
||||
{plan, apply, verify}` (дефолт `plan`). Exit-коды (контракт): **0** — успех; **2** — остановка на
|
||||
manual-step / незавершённое предусловие / нет TTY; **1** — ошибка. `plan` — ноль мутаций (печать
|
||||
плана + read-only preflight-диагностика). `apply` — полный прогон step-движком `check→ensure`
|
||||
(повтор = каскад skip; «resume» = повторный запуск). `verify` — read-only пост-проверка
|
||||
(health-контракты + `onboard_project.py verify`). Привязка: BR-1, BR-7.
|
||||
|
||||
### FR-2 — Скан предусловий хоста (preflight)
|
||||
Read-only снимок хоста (по образцу `bootstrap_bundle.collect_facts`/`preflight_verdict`): наличие
|
||||
`docker`, `docker compose` v2, `git`, `python3`, `node`, `claude` CLI + читаемость кред; свободность
|
||||
портов (прод-порт `ORCH_DEPLOY_PROD_TARGET_PORT` дефолт 8500, при self-hosting-вилке staging 8501);
|
||||
`uid`/`gid`/`docker-gid` и владелец каталога репозиториев; наличие ssh-каталога. Чистая функция-
|
||||
вердикт возвращает `(blockers, warnings)`; человекочитаемый список «есть/нет». Привязка: BR-2.
|
||||
|
||||
### FR-3 — Управляемая установка зависимостей (D-1)
|
||||
Для каждого блокера-зависимости: детект пакетного менеджера (`apt`/`dnf` по наличию бинаря /
|
||||
`/etc/os-release`) → **точная команда** установки (чистая функция «дистрибутив+пакет → команда»);
|
||||
печать команды; для безопасных — предложение выполнить с согласия (`y/N`, `input()`); отказ/нет
|
||||
TTY/неизвестный дистрибутив → печать инструкции и `exit 2` (никакой молчаливой root-мутации).
|
||||
Привязка: BR-3, AC-3.
|
||||
|
||||
### FR-4 — Детект существующих Plane/Gitea + выбор (D-2)
|
||||
Best-effort обнаружение (never-raise, NFR-3): кандидаты из `docker ps` (имена/образы, похожие на
|
||||
Plane: `plane-*`/`makeplane`/`proxy`; Gitea: `gitea/gitea`/`gitea-*`) и из слушающих портов
|
||||
(типовые Plane 80/8080/443, Gitea 3000). По кандидату — проба живости (Plane: `GET /api/instances/`;
|
||||
Gitea: `GET /api/v1/version`). Чистая функция формирует ранжированный список кандидатов. Поведение:
|
||||
0 кандидатов → запрос ручного URL; ≥2 → нумерованный список + выбор (`input()` индекс), вне
|
||||
диапазона → ручной ввод; 1 → предложить с подтверждением. Выбор наполняет `ORCH_PLANE_*` /
|
||||
`ORCH_GITEA_*`. Привязка: BR-5, AC-4.
|
||||
|
||||
### FR-5 — Интерактивный сбор данных + живая верификация
|
||||
Honest-checkpoint контракт (как `bootstrap_bundle.manual_checkpoint`): для каждого требуемого
|
||||
секрета/параметра — печать откуда взять (ссылка на LITE_SETUP §5–§8), скрытый ввод секрета
|
||||
(`getpass`), **верификация ДО записи**: Plane — `GET /api/v1/workspaces/<slug>/projects/` с
|
||||
`X-API-Key`; Gitea — `GET /api/v1/user` с `Authorization: token`; Telegram — `GET /bot<token>/getMe`.
|
||||
Провал → повтор (до N) или `exit 2` с подсказкой, значение **не пишется**. Авто-детект и
|
||||
пред-заполнение всего детектируемого (uid/gid/docker-gid/порты/пути/node/claude/выбранные URL) —
|
||||
оператор только подтверждает. Привязка: BR-4, AC-5.
|
||||
|
||||
### FR-6 — Выпуск webhook-секретов кирпичом `gen_secrets.py`
|
||||
`ORCH_PLANE_WEBHOOK_SECRET` / `ORCH_GITEA_WEBHOOK_SECRET` выпускаются **строго** субпроцессом
|
||||
`gen_secrets.py` (никакого собственного `secrets.token_hex` в установщике — анти-форк, AC-7); если
|
||||
уже присутствуют в `.env` и валидны — пропуск (не перетирать без `--force`). Привязка: BR-6, NFR-2.
|
||||
|
||||
### FR-7 — Сборка `.env` / `.env.watchdog`
|
||||
Идемпотентный рендер из канона (`render_env`-паттерн): существующий файл — обновить ключи-
|
||||
override, отсутствующий — отрендерить из `.env.example` / `.env.watchdog.example`; комментарии
|
||||
канона сохранены; неизвестные ключи — управляемым блоком в конец; запись правами **600**; значения
|
||||
секретов в stdout/лог **не попадают**; молчаливой перезаписи нет. Watchdog-ключи (`WATCHDOG_TG_*`)
|
||||
кладутся **только** в `.env.watchdog` (файл-носитель, LITE_SETUP §4.3). Привязка: BR-6, NFR-2.
|
||||
|
||||
### FR-8 — Подъём стека + готовность
|
||||
`docker compose up -d --build` ровно `orchestrator` + `orchestrator-watchdog` (staging НЕ
|
||||
поднимается — за профилем). Ожидание готовности поллингом `GET /health` (таймаут). Перед записью
|
||||
`ORCH_PROJECTS_JSON` стек уже жив. Привязка: BR-1.
|
||||
|
||||
### FR-9 — Регистрация проекта кирпичом `onboard_project.py`
|
||||
Сбор параметров проекта (имя/repo/prefix/стек/тест-команда/порты/webhook-URL — флаги или интерактивно),
|
||||
вызов `onboard_project.py apply` затем `verify` субпроцессом; парс merged-`ORCH_PROJECTS_JSON` из
|
||||
отчёта и запись в `.env`; ручные пункты отчёта (manual-step) пробрасываются оператору. **Никакого
|
||||
собственного создания статусов/лейблов/репо** (анти-форк, 22 статуса — только онбординг-кирпич).
|
||||
Привязка: BR-6, AC-7.
|
||||
|
||||
### FR-10 — Health-верификация + сводка
|
||||
После `apply` (и в `verify`): `GET /health` → 200, `GET /queue` / `GET /metrics` → валидный JSON.
|
||||
Итоговая сводка по шагам (`ok`/`skipped`/`manual-step`) + общий вердикт; любой FAIL → `exit 1` с
|
||||
диагностикой (хвост `docker logs` / снапшот). Привязка: BR-7, AC-11.
|
||||
|
||||
### FR-11 — Синхронизация документации
|
||||
`LITE_SETUP.md` дополняется указателем «рекомендованный путь — `install_lite.py`; ручной маршрut
|
||||
ниже как фолбэк/референс». Обновляются `CLAUDE.md` (раздел тиража), `docs/architecture/README.md`
|
||||
(Type A), `docs/overview/` (если затронута витрина), `CHANGELOG.md`. Привязка: BR-9, AC-12.
|
||||
|
||||
## 4. Изменения API
|
||||
**Нет.** Установщик — вне процесса орка; обращается только к существующим read-only эндпоинтам
|
||||
(`/health`, `/queue`, `/metrics`) как HTTP-клиент и к собственным Plane/Gitea/Telegram заказчика.
|
||||
Новых/изменённых эндпоинтов оркестратора не вводится.
|
||||
|
||||
## 5. Изменения схемы БД
|
||||
**Нет.** Установщик не касается БД оркестратора (её создаёт сам орк пустой при первом старте,
|
||||
stateless-инвариант LITE_SETUP §12).
|
||||
|
||||
## 6. Требования к новым/изменённым QG checks
|
||||
**Нет.** `QG_CHECKS` / `check_*` / `STAGE_TRANSITIONS` / machine-verdict ключи — байт-в-байт не
|
||||
трогаются (INV-1). Установщик не участвует в решении ни одного гейта.
|
||||
|
||||
## 7. Конфигурация
|
||||
Новых **рантайм**-ключей `config.py` / kill-switch — **нет** (NFR-1; активация = явный запуск).
|
||||
Установщик читает/пишет только `.env` / `.env.watchdog` (канон ключей — `.env.example` /
|
||||
`.env.watchdog.example`, ORCH-101). CLI-флаги установщика (имена — OQ-7): режим + параметры проекта
|
||||
для `onboard_project.py` (`--repo`/`--prefix`/`--stack`/…), возможный `--force` (перевыпуск
|
||||
секретов), возможный `--non-interactive`/значения из env для CI.
|
||||
|
||||
## 8. Наблюдаемость
|
||||
- Прогресс-лог по шагам (`ok`/`skipped`/`manual-step`/`error`) — **без значений секретов** (только
|
||||
имена ключей/пути файлов, NFR-2).
|
||||
- Итоговая сводка PASS/FAIL + код выхода `0/2/1`.
|
||||
- `manual_checkpoint` печатает точную инструкцию и верифицирует результат (молчаливый пропуск
|
||||
запрещён); без TTY → `exit 2` с той же инструкцией.
|
||||
|
||||
## 9. Артефакты pipeline (создаются/обновляются)
|
||||
- `scripts/install_lite.py` (новый исполняемый артефакт).
|
||||
- `tests/test_install_lite_script.py` (новый), `tests/test_lite_setup_doc.py` (обновление).
|
||||
- `docs/work-items/ORCH-104/06-adr/ADR-001-<slug>.md` (архитектор) + опц. сквозной
|
||||
`docs/architecture/adr/adr-NNNN-*.md`.
|
||||
- `docs/deployment/LITE_SETUP.md`, `CLAUDE.md`, `docs/architecture/README.md`, `docs/overview/`,
|
||||
`CHANGELOG.md` — обновления (BR-9).
|
||||
|
||||
## 10. Совместимость / регресс
|
||||
Аддитивно: новый файл-скрипт + новый тест + правки docs. Существующие кирпичи (`gen_secrets.py`,
|
||||
`onboard_project.py`) и compose — байт-в-байт. Полный регресс `pytest tests/ -q` остаётся зелёным.
|
||||
Обратимость — тривиальная (удаление нового файла/теста). Область раската — только хосты заказчиков
|
||||
Lite; **наш прод не затронут** (установщик исполняется на чужом хосте, говорит только с локальным
|
||||
хостом и инфраструктурой заказчика).
|
||||
|
||||
## 11. Инварианты (не нарушать)
|
||||
- **INV-1** — `src/**` / `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / machine-verdict ключи /
|
||||
схема БД — байт-в-байт.
|
||||
- **INV-2** — Каноны не форкаются: секреты — `gen_secrets.py`; статусы/лейблы/репо/webhook —
|
||||
`onboard_project.py`; env — из `.env.example`/`.env.watchdog.example`; стек — из `docker-compose.yml`.
|
||||
- **INV-3** — Нет delete-операций (никаких `docker … rm`, `rm -rf`, удаления веток, force-push).
|
||||
- **INV-4** — Секреты не печатаются; `.env`/`.env.watchdog` — права 600; без молчаливой перезаписи.
|
||||
- **INV-5** — Никогда не трогает наш прод / `main` / force-push; говорит только с локальным хостом и
|
||||
собственными Plane/Gitea/Telegram заказчика.
|
||||
- **INV-6** — Платформенные конвенции: репо `orchestrator`; имена compose-сервисов/профиля —
|
||||
константы; staging за профилем; `ORCH_STAGING_PORT` ≠ прод-порт (guard ORCH-058) — установщик
|
||||
уважает, не форкает.
|
||||
- **INV-7** — stdlib-only (NFR-6).
|
||||
|
||||
## 12. Открытые вопросы для архитектора (OQ — не блокируют анализ)
|
||||
- **OQ-1** — Финальное имя/путь: `scripts/install_lite.py` (понятно конечному оператору) vs
|
||||
`scripts/bootstrap_lite.py` (симметрия с `bootstrap_bundle.py`). Рекомендация анализа —
|
||||
`install_lite.py`.
|
||||
- **OQ-2** — Точные эвристики детекта Plane/Gitea (паттерны имён/образов контейнеров, набор
|
||||
портов/URL-проб, ранжирование уверенности).
|
||||
- **OQ-3** — Какие зависимости считать «безопасными для авто-выполнения с согласия» (напр.
|
||||
`pip install -r requirements.txt` в venv — да; `apt install docker` под sudo — только consent;
|
||||
claude CLI через npm); владелец distro-команд-карты.
|
||||
- **OQ-4** — Общий код с `bootstrap_bundle.py` (вынести `parse_env`/`render_env`/`manual_checkpoint`
|
||||
в общий stdlib-модуль) vs самодостаточный один файл (ради «1 установочный файл» и stdlib-only).
|
||||
Trade-off DRY ↔ простота/одно-файловость.
|
||||
- **OQ-5** — Драйвить ли путь Б Plane-webhook (raw-SQL, LITE_SETUP §5.4) автоматически (как
|
||||
`bootstrap_bundle.step_plane_webhook`) или всегда оставлять верифицируемым manual-step.
|
||||
- **OQ-6** — Подтвердить: интерактивный логин claude CLI остаётся manual-step с верификацией
|
||||
(`claude --version` + читаемость кред), не автоматизируется.
|
||||
- **OQ-7** — Набор CLI-флагов/env для не-интерактивного (CI) прогона: какие входы принимают
|
||||
флаги/env vs только prompt.
|
||||
171
docs/work-items/ORCH-104/03-acceptance-criteria.md
Normal file
171
docs/work-items/ORCH-104/03-acceptance-criteria.md
Normal file
@@ -0,0 +1,171 @@
|
||||
---
|
||||
work_item: ORCH-104
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-12
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 03 — Критерии приёмки (Acceptance Criteria): ORCH-104 — Установочный скрипт для Lite
|
||||
|
||||
Work Item: **ORCH-104** · Repo: **orchestrator** · Стадия: analysis
|
||||
|
||||
Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL** (что
|
||||
считается провалом). Reviewer/tester проверяют их буквально по файлам репозитория и поведению
|
||||
скрипта (фейки HTTP/процессов — в тестах; сеть/docker в unit не нужны).
|
||||
|
||||
> Область: автоматизация LITE_SETUP.md §2–§11 одним установщиком (scripts+docs+tests). Подъём самих
|
||||
> Plane/Gitea (Bundled), teardown, правки рантайма — вне области (см. 01-brd §2).
|
||||
|
||||
---
|
||||
|
||||
## AC-1 — Единый entry-point и режимы
|
||||
|
||||
**Условие:** `python3 scripts/install_lite.py` (дефолт-режим `plan`) запущен из корня чекаута.
|
||||
- **PASS:** печатается нормативный план шагов + read-only preflight-диагностика; **ноль мутаций**
|
||||
(никаких записей в `.env`/`.env.watchdog`, никаких `docker compose up`); exit `0` (предусловия
|
||||
чисты) либо `2` (есть блокеры). Поддержаны режимы `plan`/`apply`/`verify` (argparse).
|
||||
- **FAIL:** режим `plan` что-то пишет/поднимает; нет одного из режимов; неизвестный код выхода
|
||||
(не из `{0,1,2}`).
|
||||
|
||||
---
|
||||
|
||||
## AC-2 — Скан предусловий выявляет нехватку
|
||||
|
||||
**Условие:** на хосте отсутствует одно из предусловий (напр. `node` или свободный прод-порт).
|
||||
- **PASS:** `plan`/preflight перечисляет отсутствующее как блокер с понятной строкой и подсказкой
|
||||
(что доустановить / какой порт занят); при всех присутствующих — блокеров нет, разрешён `apply`.
|
||||
- **FAIL:** отсутствующая зависимость не отмечена; ложный блокер при фактически выполненном
|
||||
предусловии; preflight роняет скрипт исключением.
|
||||
|
||||
---
|
||||
|
||||
## AC-3 — Управляемая установка зависимостей (D-1)
|
||||
|
||||
**Условие:** недостающая зависимость, для которой определён пакетный менеджер хоста (`apt`/`dnf`).
|
||||
- **PASS:** установщик печатает **точную команду** установки под обнаруженный дистрибутив; авто-
|
||||
выполнение — только после явного согласия (`y/N`); при отказе / отсутствии TTY / неизвестном
|
||||
дистрибутиве — печатает инструкцию и завершает `exit 2`, **не выполнив ни одной root-мутации
|
||||
молча**.
|
||||
- **FAIL:** скрипт ставит системный пакет без подтверждения; команда не соответствует дистрибутиву;
|
||||
неизвестный дистрибутив приводит к падению вместо инструкции.
|
||||
|
||||
---
|
||||
|
||||
## AC-4 — Детект существующих Plane/Gitea и выбор (D-2)
|
||||
|
||||
**Условие:** на хосте присутствует ≥2 кандидата Plane (или Gitea); отдельный прогон — 0 кандидатов.
|
||||
- **PASS:** при ≥2 — установщик показывает **нумерованный список** обнаруженных инсталляций и
|
||||
принимает выбор оператора; выбранный URL наполняет `ORCH_PLANE_*`/`ORCH_GITEA_*`. При 0 —
|
||||
запрашивает ручной ввод URL (фолбэк). Выбор/ввод проходит живую верификацию (AC-5) до записи.
|
||||
- **FAIL:** при нескольких инсталляциях выбор не предложен (молча берётся первая/случайная); нет
|
||||
ручного фолбэка при 0 кандидатов; сбой детекта роняет установщик (нарушение never-raise NFR-3).
|
||||
|
||||
---
|
||||
|
||||
## AC-5 — Живая верификация введённых данных ДО записи
|
||||
|
||||
**Условие:** оператор вводит токен/URL Plane, Gitea или Telegram.
|
||||
- **PASS:** введённое значение проверяется онлайн перед записью (Plane `GET …/projects/`; Gitea
|
||||
`GET /api/v1/user`; Telegram `getMe`); неверное → отклоняется (повтор до N либо `exit 2` с
|
||||
подсказкой) и **в `.env` не пишется**; верное → принимается и пишется. Секреты вводятся скрыто
|
||||
(`getpass`).
|
||||
- **FAIL:** неверный секрет записан в `.env`; верификация отсутствует/после записи; секрет виден на
|
||||
экране при вводе.
|
||||
|
||||
---
|
||||
|
||||
## AC-6 — Гигиена секретов
|
||||
|
||||
**Условие:** прогон `apply`, затем повторный `apply`.
|
||||
- **PASS:** ни одно значение секрета не появляется в stdout/логах (только имена ключей/пути);
|
||||
`.env` и `.env.watchdog` создаются правами **600**; повторный прогон **не перетирает** уже
|
||||
присутствующие значения секретов без `--force`/явного согласия.
|
||||
- **FAIL:** секрет утёк в вывод/лог; права файла шире 600; повтор молча перезаписал существующий
|
||||
секрет.
|
||||
|
||||
---
|
||||
|
||||
## AC-7 — Каноны переиспользуются, не форкаются
|
||||
|
||||
**Условие:** ревизия `scripts/install_lite.py` и его прогон.
|
||||
- **PASS:** webhook-секреты выпускаются вызовом `gen_secrets.py`; проект регистрируется вызовом
|
||||
`onboard_project.py apply`+`verify`; `.env` рендерится из `.env.example`. Структурный тест
|
||||
подтверждает ссылки на оба кирпича и **отсутствие форка** канона статусов Plane (нет
|
||||
захардкоженных 22 имён статусов) и собственной генерации секретов.
|
||||
- **FAIL:** установщик сам генерирует webhook-секреты / сам создаёт статусы-лейблы-репо / сам
|
||||
выдумывает ключи env вместо рендера из канона.
|
||||
|
||||
---
|
||||
|
||||
## AC-8 — Идемпотентный apply
|
||||
|
||||
**Условие:** два последовательных `apply` (фейки Plane/Gitea/процессов в тесте).
|
||||
- **PASS:** второй прогон помечает завершённые шаги как `skipped`; дублей проекта/webhook не
|
||||
создаётся; значения `.env` стабильны; exit-код консистентен (`0`, либо `2` если остался
|
||||
manual-step).
|
||||
- **FAIL:** повтор создаёт дубли / перевыпускает секреты / падает на уже сделанном шаге.
|
||||
|
||||
---
|
||||
|
||||
## AC-9 — Рантайм не затронут
|
||||
|
||||
**Условие:** диф PR ORCH-104.
|
||||
- **PASS:** изменены только `scripts/**`, `docs/**`, `tests/**` (+ `CLAUDE.md`/`CHANGELOG.md`);
|
||||
`src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`, machine-verdict ключи, схема БД —
|
||||
**байт-в-байт** (снапшот-тест инвариантов зелёный, не изменён этим PR).
|
||||
- **FAIL:** PR трогает `src/**` / реестр стадий / гейты / схему БД; снапшот-тест инвариантов
|
||||
изменён или падает.
|
||||
|
||||
---
|
||||
|
||||
## AC-10 — stdlib-only, без delete-операций, без импорта платформы
|
||||
|
||||
**Условие:** структурный анализ `scripts/install_lite.py` (AST/токенайз/grep).
|
||||
- **PASS:** только stdlib-импорты (из разрешённого набора); нет `from src …`/`import src`; нет
|
||||
деструктивных операций (`docker … rm`, `rm -rf`, удаление веток, `git push --force`); каноны-
|
||||
знания — только субпроцессами кирпичей.
|
||||
- **FAIL:** найден сторонний/платформенный импорт; найдена delete/force-операция; найден захардкод
|
||||
хост-литералов (переиспользуется `FORBIDDEN`-набор `tests/test_no_host_hardcodes.py`).
|
||||
|
||||
---
|
||||
|
||||
## AC-11 — Health-гейт и итоговый вердикт
|
||||
|
||||
**Условие:** успешный `apply`, затем `verify`.
|
||||
- **PASS:** `GET /health` → 200, `GET /queue` и `GET /metrics` → валидный JSON; итоговая сводка
|
||||
печатает PASS; любой FAIL шага даёт `exit 1` с диагностикой. `verify` (read-only) повторяет
|
||||
health-контракты + `onboard_project.py verify`.
|
||||
- **FAIL:** скрипт рапортует успех при неотвечающем `/health`; нет финальной сводки; FAIL не
|
||||
даёт `exit 1`.
|
||||
|
||||
---
|
||||
|
||||
## AC-12 — Синхронизация документации
|
||||
|
||||
**Условие:** ревизия `docs/deployment/LITE_SETUP.md` и анти-дрейф теста.
|
||||
- **PASS:** LITE_SETUP.md содержит указатель на установщик как рекомендованный путь (ручной
|
||||
маршрут сохранён фолбэком); `tests/test_lite_setup_doc.py` ассертит наличие ссылки и **остаётся
|
||||
зелёным** во всех существующих проверках (13 разделов, кирпичи, key-sync); обновлены
|
||||
`CLAUDE.md`/`CHANGELOG.md` (и витрина `docs/overview/`, если затронута).
|
||||
- **FAIL:** установщик добавлен, но LITE_SETUP.md/`CLAUDE.md` о нём молчат; анти-дрейф тест не
|
||||
обновлён/красный (reviewer-ось обзорных доков, ORCH-079/011 → finding ≥P1).
|
||||
|
||||
---
|
||||
|
||||
## Сводная матрица AC ↔ BR/FR/NFR
|
||||
| AC | Покрывает | Тип проверки |
|
||||
|----|-----------|--------------|
|
||||
| AC-1 | BR-1 / FR-1 | integration (plan zero-mutation) |
|
||||
| AC-2 | BR-2 / FR-2 | unit (preflight verdict) |
|
||||
| AC-3 | BR-3 / FR-3 / D-1 | unit + integration (consent / no-TTY) |
|
||||
| AC-4 | BR-5 / FR-4 / D-2 | unit (discovery/select) |
|
||||
| AC-5 | BR-4 / FR-5 | integration (verify-before-write) |
|
||||
| AC-6 | BR-8 / NFR-2 | unit + integration (mask / 600 / no-overwrite) |
|
||||
| AC-7 | BR-6 / FR-6 / FR-9 / INV-2 | structural (reuse bricks, anti-fork) |
|
||||
| AC-8 | BR-7 / NFR-5 | integration (idempotency) |
|
||||
| AC-9 | BR-8 / NFR-1 / INV-1 | structural (invariant snapshot) |
|
||||
| AC-10 | BR-8 / NFR-4 / NFR-6 / INV-3 / INV-7 | structural (AST/grep) |
|
||||
| AC-11 | BR-7 / FR-10 | integration (health gate) |
|
||||
| AC-12 | BR-9 / FR-11 | structural (doc anti-drift) |
|
||||
150
docs/work-items/ORCH-104/04-test-plan.yaml
Normal file
150
docs/work-items/ORCH-104/04-test-plan.yaml
Normal file
@@ -0,0 +1,150 @@
|
||||
work_item: ORCH-104
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-12
|
||||
model_used: claude-opus-4-8
|
||||
title: "Установочный скрипт для Lite — интерактивный установщик scripts/install_lite.py"
|
||||
framework: pytest
|
||||
scope: >
|
||||
FR-1..FR-11 / AC-1..AC-12. Покрывается поведение установщика (чистые функции + step-движок
|
||||
с инъекцией фейков HTTP/процессов) и анти-дрейф (stdlib-only, no-delete, reuse-bricks, doc-sync,
|
||||
invariant snapshot). ВНЕ объёма тестов: реальная установка пакетов, реальный docker compose up,
|
||||
реальные Plane/Gitea/Telegram (unit/integration детерминированы, без сети/docker/LLM — NFR-7).
|
||||
notes: >
|
||||
Зеркало паттернов tests/test_bootstrap_script.py и tests/test_lite_setup_doc.py: модуль грузится
|
||||
через importlib; side-effects (subprocess/HTTP/getpass/input) инъектируются фейками; чистые
|
||||
функции (parse_env/render_env/preflight_verdict/distro-команда/discovery/select) тестируются
|
||||
изолированно. Полный регресс `pytest tests/ -q` обязан оставаться зелёным. Имена функций ниже —
|
||||
ориентир по образцу bootstrap_bundle.py; финальные сигнатуры уточняет архитектор/разработчик.
|
||||
|
||||
tests:
|
||||
# ---- FR-1 / AC-1: entry-point и режимы ----
|
||||
- id: TC-01
|
||||
type: integration
|
||||
description: "plan-режим (дефолт) печатает план + preflight и НЕ делает мутаций (нет записи .env, нет compose up); exit 0 при чистых предусловиях, 2 при блокерах."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-02
|
||||
type: unit
|
||||
description: "build_plan() возвращает нормативный список шагов Lite в правильном порядке (preflight→deps→discovery→inputs→secrets→env→up→onboard→health)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-2 / AC-2: скан предусловий ----
|
||||
- id: TC-03
|
||||
type: unit
|
||||
description: "preflight-вердикт: отсутствие docker/compose/node, занятый прод-порт, mismatch uid:gid владельца repos-dir → блокеры; полностью укомплектованный хост → блокеров нет."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-3 / AC-3 / D-1: управляемая установка зависимостей ----
|
||||
- id: TC-04
|
||||
type: unit
|
||||
description: "distro→команда: apt-хост даёт apt-команду установки, dnf-хост — dnf-команду; неизвестный дистрибутив → деградация на текстовую инструкцию (без команды-мутации)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-05
|
||||
type: integration
|
||||
description: "remediation: при отказе оператора (ответ 'N') и при отсутствии TTY установщик НЕ выполняет установку, печатает инструкцию и возвращает exit 2 (никакой молчаливой root-мутации)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-4 / AC-4 / D-2: детект Plane/Gitea + выбор ----
|
||||
- id: TC-06
|
||||
type: unit
|
||||
description: "discovery: по фейковым фактам docker ps/портов с 2 кандидатами Plane возвращается ранжированный список из 2; 0 кандидатов → пустой список (триггерит ручной фолбэк)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-07
|
||||
type: unit
|
||||
description: "select_candidate: валидный индекс выбирает кандидата; индекс вне диапазона/пустой ввод → режим ручного ввода URL (never-raise)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-08
|
||||
type: unit
|
||||
description: "detect never-raise: исключение в пробе docker/порта/URL деградирует в 'кандидатов нет' и не роняет установщик (NFR-3)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-5 / AC-5: живая верификация ввода ----
|
||||
- id: TC-09
|
||||
type: integration
|
||||
description: "verify-before-write: фейк Plane/Gitea, отвечающий 401, отклоняет токен — значение НЕ пишется в .env; ответ 200 принимает и пишет. Telegram getMe ok:false → отклонение."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-6 / FR-7 / AC-6 / AC-7: секреты и env ----
|
||||
- id: TC-10
|
||||
type: unit
|
||||
description: "parse_env round-trip: KEY=value строки → словарь, комментарии/пустые игнорируются."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-11
|
||||
type: unit
|
||||
description: "render_env: ключи-override обновляются в каноне, комментарии сохранены, неизвестные ключи дописываются управляемым блоком; идемпотентно (повторный рендер стабилен)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-12
|
||||
type: integration
|
||||
description: "секрет-гигиена: после прогона ни одно секрет-значение не встречается в собранном stdout/логе (маскирование); записанные .env/.env.watchdog имеют права 600."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-13
|
||||
type: integration
|
||||
description: "no-silent-overwrite: при уже заполненных секретах повторный apply без --force их не перетирает (значения стабильны); webhook-секреты выпускаются вызовом gen_secrets.py, а не собственным кодом."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-9 / AC-7: онбординг кирпичом ----
|
||||
- id: TC-14
|
||||
type: integration
|
||||
description: "onboard reuse: установщик вызывает onboard_project.py apply+verify субпроцессом (фейк), парсит merged ORCH_PROJECTS_JSON из отчёта и пишет его в .env; ручные пункты отчёта пробрасываются (exit 2)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- FR-1 / FR-10 / AC-8 / AC-11: идемпотентность, health, no-TTY ----
|
||||
- id: TC-15
|
||||
type: integration
|
||||
description: "идемпотентность: два apply подряд (фейки) → второй помечает шаги skipped, без дублей проекта/webhook, значения .env стабильны."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-16
|
||||
type: integration
|
||||
description: "no-TTY fail-closed: stdin не tty → manual_checkpoint печатает инструкцию и поднимает остановку → exit 2 (никакого зависания на input)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-17
|
||||
type: integration
|
||||
description: "health-гейт: фейк отвечает 200 на /health и валидным JSON на /queue,/metrics → сводка PASS, exit 0; /health не 200 → exit 1 с диагностикой (нет ложного success)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- AC-9 / AC-10 / INV: структурные анти-дрейф ----
|
||||
- id: TC-18
|
||||
type: unit
|
||||
description: "stdlib-only + no-src-import: AST-скан install_lite.py — импорты только из разрешённого stdlib-набора; нет 'from src'/'import src' (зеркало test_bootstrap_script)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-19
|
||||
type: unit
|
||||
description: "no-delete-ops: AST/regex-скан не находит деструктивных операций (docker … rm/down -v, rm -rf, git push --force, удаление веток) и хост-хардкодов (FORBIDDEN-набор test_no_host_hardcodes)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-20
|
||||
type: unit
|
||||
description: "reuse-bricks / anti-fork: скрипт ссылается на gen_secrets.py и onboard_project.py; не несёт захардкоженного канона имён статусов Plane (FORBIDDEN_STATUS_NEEDLES) и собственной генерации секретов."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
- id: TC-21
|
||||
type: unit
|
||||
description: "invariant snapshot: STAGE_TRANSITIONS/QG_CHECKS не изменены этим PR (существующий снапшот-тест зелёный; ORCH-104 их не трогает)."
|
||||
module: tests/test_install_lite_script.py
|
||||
expected: PASS
|
||||
|
||||
# ---- AC-12: синхронизация документации ----
|
||||
- id: TC-22
|
||||
type: unit
|
||||
description: "doc-sync: tests/test_lite_setup_doc.py ассертит, что LITE_SETUP.md ссылается на install_lite.py как рекомендованный путь; все существующие проверки дока (13 разделов, кирпичи, env key-sync, секрет-гигиена) остаются зелёными."
|
||||
module: tests/test_lite_setup_doc.py
|
||||
expected: PASS
|
||||
Reference in New Issue
Block a user