diff --git a/docs/work-items/ORCH-061/01-brd.md b/docs/work-items/ORCH-061/01-brd.md new file mode 100644 index 0000000..a8e2220 --- /dev/null +++ b/docs/work-items/ORCH-061/01-brd.md @@ -0,0 +1,117 @@ +# 01 — BRD: BUG — deploy-staging петля (откат deploy-staging → development) для self-deploy + +Work Item: **ORCH-061** +Тип: **BUG** +Приоритет: **P0** +Репозиторий: `orchestrator` (self-hosting) +Эпик-контекст: блокер **ORCH-54** (автономное внедрение self-hosting) + +--- + +## 1. Резюме (Executive summary) + +На стадии `deploy-staging` для self-hosting репозитория `orchestrator` задача +зацикливается: гейт ребра `deploy-staging → deploy` даёт FAILED, `stage_engine` +откатывает задачу `deploy-staging → development`, developer-агент перезапускается, +проходит конвейер заново, снова упирается в `deploy-staging`, снова откат — и так +по кругу (с расходом developer-ретраев и кредитов LLM), либо до исчерпания лимита +ретраев и блокировки. + +Следствие: **прод-деплой self-hosting репо невозможен автономно**. Последние +ORCH-задачи (ORCH-58, ORCH-60) доводились до прода **вручную** (ручной merge PR + +ручной build-once retag + ручной `--deploy`). Это прямой блокер автономного +внедрения (эпик ORCH-54). + +## 2. Бизнес-контекст и проблема + +Оркестратор дорабатывает сам себя (self-hosting). Стадия `deploy-staging` +(порт 8501) — обязательная страховка перед прод-деплоем орка (ORCH-35, ADR-0003). +На этой стадии deployer гоняет `scripts/staging_check.py` против живого +staging-стенда и пишет машинный вердикт `staging_status: SUCCESS|FAILED` в +`15-staging-log.md`. Гейт `check_staging_status` читает этот вердикт; `FAILED` +→ откат на `development` (ORCH-35, `_handle_qg_failure_rollbacks`). + +Подтверждены **две независимые причины** зацикливания. + +### Причина №1 — ложный FAILED `check_staging_status` (контекст ORCH-58) + +`staging_check.py` в sandbox-прогоне даёт **8/10 PASS, 2 ложных FAIL** на e2e-блоке +Block C: +- **C9a** — ветка не появляется в `orchestrator-sandbox` (branch not found); +- **C9b** — analyst-job не появляется в staging-очереди (`/queue → recent`). + +Сопутствующая пометка suite: «Plane comment check skipped: bot-tokens not added to +SANDBOX project» — bot-аккаунты агентов (`ORCH_PLANE_BOT_*`) не добавлены членами +SANDBOX-проекта Plane (проект создан после провижининга ботов). Это **отсутствие +sandbox-настроек инфраструктуры, а не регресс кода**. Тем не менее `staging_check.py` +возвращает ненулевой exit-code → deployer пишет `staging_status: FAILED` → гейт +FAILED → откат `deploy-staging → development`. + +### Причина №2 — «no changes to commit» на action-стадии (контекст ORCH-60) + +Стадии деплоя по своей природе **действие, а не правка кода** (рестарт/retag), и +закономерно не порождают git-изменений в `src/`/`tests/`. Сигнал «no changes» +для action-стадии не должен трактоваться как недовыполнение работы; критерий успеха +action-стадии — успешное выполнение действия (exit0 + доказанный health/staging), +а не наличие нового коммита. Сейчас отсутствие изменений на стадии деплоя приводит +к недопродвижению задачи и откату. + +### Совокупный эффект + +Любая из причин по отдельности достаточна, чтобы зациклить self-deploy. Обе +проявились на реальных задачах ORCH-58 и ORCH-60, которые пришлось доводить вручную. + +## 3. Цели (Goals) + +- **G1.** ORCH-задача для self-hosting `orchestrator` проходит + `deploy-staging → deploy → done` **без ручного вмешательства** и **без петли**. +- **G2.** Ложный (инфраструктурный) FAIL `staging_check` в sandbox **не вызывает** + откат `deploy-staging → development`. +- **G3.** Отсутствие git-изменений на стадиях деплоя (`deploy-staging` / `deploy`) + **не трактуется** как недовыполнение и не приводит к откату. +- **G4.** Реальный регресс (настоящий провал staging-проверки или прод-деплоя) + **по-прежнему** приводит к откату `→ development` (страховка не ослабляется). + +## 4. Вне области (Non-goals) + +- Полная автоматизация ручного approve прод-деплоя (это ORCH-54). +- Изменение конвейера стадий (`STAGE_TRANSITIONS`), реестра гейтов как структуры, + контрактов `check_deploy_status` / `check_staging_status` frontmatter-вердиктов. +- Изменение поведения для **не**-self-hosting репозиториев (enduro-trails и пр.): + для них staging-гейт и self-deploy остаются no-op / прежними. +- Изменение схемы БД. + +## 5. Заинтересованные стороны + +| Роль | Интерес | +|------|---------| +| Owner / оператор оркестратора | Автономный self-deploy без ручных шагов и без ночных петель. | +| Другие проекты (enduro-trails) | Их конвейер не должен быть затронут (общий инстанс, общая очередь). | +| Агенты (deployer) | Чёткий, не ложно-срабатывающий контракт стадии деплоя. | + +## 6. Кандидатные направления решения (из бизнес-запроса) + +Бизнес-запрос называет два направления (одно или оба); **выбор и механизм — +за архитектором (ADR)**, BRD требует лишь достижения G1–G4: + +- **(а)** Сделать sandbox-прогон `staging_check` честным (например, настроить + bot-токены SANDBOX Plane-проекта / починить sandbox e2e), чтобы C9a/C9b + проходили честно (10/10) и `check_staging_status` не падал ложно. +- **(б)** Отвязать продвижение стадий деплоя от git-changes для self-deploy: + успех action-стадии = exit0 + health/staging PASS, а не наличие коммита. + +## 7. Бизнес-эффект / риски бездействия + +- **Эффект:** разблокировка автономного внедрения self-hosting (ORCH-54); + устранение ручного труда (merge + retag + deploy) и риска ошибки при ручных шагах. +- **Риск бездействия:** каждая ORCH-задача требует ручного дотягивания до прода; + петли жгут кредиты LLM и developer-ретраи, задачи блокируются. + +## 8. Допущения + +- Прод-контейнер `orchestrator` (8500) обслуживает все проекты из общего инстанса — + его **нельзя** ронять/перезапускать в рамках задачи (см. CLAUDE.md, INFRA.md). +- Изменения касаются self-hosting пути (`is_self_hosting_repo` / `self_deploy_applies`); + для прочих репо поведение не меняется. +- Документация — golden source: затронутые `docs/architecture/README.md`, + `docs/operations/STAGING_CHECK.md`, `CHANGELOG.md` обновляются в том же PR. diff --git a/docs/work-items/ORCH-061/02-trz.md b/docs/work-items/ORCH-061/02-trz.md new file mode 100644 index 0000000..6a30f4d --- /dev/null +++ b/docs/work-items/ORCH-061/02-trz.md @@ -0,0 +1,145 @@ +# 02 — ТЗ: устранение петли deploy-staging → development при self-deploy + +Work Item: **ORCH-061** · Тип: **BUG** · Приоритет: **P0** · Репо: `orchestrator` + +> Это ТЗ фиксирует **требования и контракты**, которые должна удовлетворить +> реализация. Конкретный архитектурный механизм (направление (а), (б) или оба; +> где именно разместить логику) выбирает архитектор в ADR (`06-adr/`). +> ТЗ намеренно не предписывает дизайн, но задаёт инварианты и границы изменений. + +--- + +## 1. Затронутые модули `src/` и артефакты + +Прямо относящиеся к дефекту (для контекста; точечный набор правок — за архитектором): + +| Файл | Роль в дефекте | +|------|----------------| +| `scripts/staging_check.py` | e2e-suite; C9a (branch) / C9b (analyst job) дают ложный FAIL в sandbox; exit-code управляет вердиктом deployer. | +| `src/qg/checks.py` → `check_staging_status`, `_parse_staging_status` | гейт ребра `deploy-staging→deploy`; читает `staging_status:` из `15-staging-log.md`. | +| `src/stage_engine.py` → `advance_stage`, `_handle_qg_failure_rollbacks` | откат `deploy-staging→development` при FAILED (ветка `agent=="deployer" and qg=="check_staging_status"`). | +| `src/agents/launcher.py` → `_handle_completion`/`_try_advance_stage` | пост-ран git-commit; лог «no changes to commit»; обработка deployer-стадий. | +| `src/self_deploy.py` | Phase A/B/C исполняемого self-deploy (контекст продвижения `deploy`). | +| `src/config.py` | место для kill-switch/настроек нового поведения (если потребуется). | +| `.openclaw/agents/deployer.md` | инструкция deployer о написании вердикта; обновить при смене контракта. | +| `docs/operations/STAGING_CHECK.md`, `docs/architecture/README.md`, `CHANGELOG.md` | golden-source документация (обновить в том же PR). | + +## 2. Функциональные требования + +### FR-1 — Нет петли на корректном self-deploy +Для self-hosting `orchestrator`, при корректном состоянии (реальный pipeline в +порядке, staging-стенд здоров), задача проходит `deploy-staging → deploy → done` +**без отката** `deploy-staging → development` и **без ручного вмешательства**. + +### FR-2 — Ложный (инфраструктурный) FAIL не вызывает откат +Ложное падение `staging_check` в sandbox, вызванное **исключительно** отсутствием +sandbox-настроек (например, C9a/C9b при ненастроенных bot-токенах SANDBOX), не +приводит к `staging_status: FAILED` → откату. Должно быть реализовано одним из +способов (выбор — ADR): +- **(а)** sandbox-инфраструктура приведена в состояние, при котором C9a/C9b + проходят честно (10/10); и/или +- **(б)** вердикт staging-гейта перестаёт зависеть от заведомо инфраструктурных + (не пайплайновых) проверок — например, осознанный allowlist/threshold + «известных sandbox-инфра» проверок, отделённый от реальных pipeline-проверок. + +> Любой механизм по FR-2 **обязан** сохранить FR-4 (реальный провал ловится). + +### FR-3 — «no changes» на action-стадии не есть недовыполнение +На стадиях деплоя (`deploy-staging`, `deploy`) для self-deploy отсутствие +git-изменений (`no changes to commit`) **не** трактуется как недовыполнение и +**не** приводит к откату/блокировке. Критерий успеха action-стадии = успешный +exit агента/хука + доказанный health/staging-вердикт, а **не** наличие нового +коммита. + +### FR-4 — Реальный регресс по-прежнему откатывается (страховка цела) +- Настоящий провал реальных pipeline-проверок staging → `staging_status: FAILED` + → откат `deploy-staging → development` (как сейчас). +- Настоящий провал прод-деплоя (`deploy_status: FAILED`, БАГ-8) → откат + `deploy → development` (как сейчас). +- Ослабления страховки быть не должно: «зелёный по умолчанию» при недоступности + проверок запрещён (fail-closed для реальных проверок сохраняется). + +### FR-5 — Условность self-hosting сохранена +Изменения активны **только** для self-hosting пути +(`is_self_hosting_repo` / `self_deploy_applies`). Для прочих репозиториев +поведение `check_staging_status` (no-op N/A) и стадии деплоя — **без изменений**. + +### FR-6 — Управляемость (kill-switch) +Любое новое поведение (толерантность к инфра-FAIL и/или отвязка от git-changes) +закрыто отдельным флагом конфигурации (по образцу `merge_gate_enabled`, +`image_freshness_enabled`, `self_deploy_enabled`), с безопасным дефолтом и +возможностью мгновенно вернуть прежнее поведение без передеплоя кода-логики. + +### FR-7 — Наблюдаемость +Срабатывание нового поведения (например, «staging_check: проигнорирован +инфра-FAIL C9a/C9b» или «action-стадия: no-changes ожидаемо») логируется явной +строкой и при необходимости отражается в Plane-комментарии/Telegram, чтобы +оператор отличал «реальный зелёный» от «зелёного с допущением». + +## 3. Изменения API + +API эндпоинты (`/health`, `/status`, `/queue`, `/webhook/*`) — **без изменений**. +Допускается расширение снапшота `GET /queue` диагностическим полем (опционально, +по решению архитектора) — без удаления/переименования существующих ключей. + +## 4. Изменения схемы БД + +**Нет.** Схема (`events`, `tasks`, `agent_runs`, `jobs`) не меняется. Любое +restart-safe состояние (если потребуется) — через существующие паттерны +(sentinel-файлы / поля `jobs.task_content`), без миграций. + +## 5. Контракты, которые НЕЛЬЗЯ менять + +- `STAGE_TRANSITIONS` (порядок и состав стадий) и `get_previous_stage`. +- Состав/семантика `QG_CHECKS` как реестра; frontmatter-контракты + `staging_status:` (`15-staging-log.md`) и `deploy_status:` (`14-deploy-log.md`) — + читаются ТОЛЬКО из YAML-frontmatter, значения `SUCCESS|FAILED`. +- Откатные контракты БАГ-8 (`deploy→development`) и ORCH-35 + (`deploy-staging→development`) для **реальных** провалов. +- Контракт exit-code хука деплоя (`0/1/2`) и `map_exit_code_to_status`. +- Поведение для не-self-hosting репозиториев. + +## 6. Требования к новым/изменённым QG checks + +- Если выбран механизм толерантности (FR-2 вариант б), он реализуется **внутри** + существующего пути `check_staging_status` / staging-вердикта (не новая стадия), + по образцу условности ORCH-35; контракт «never-raise» сохраняется. +- Любая новая проверка/под-чек регистрируется в `QG_CHECKS` и покрывается + снапшот-тестом реестра (`tests/test_qg_registry_snapshot.py`). + +## 7. Требования к staging_check.py (если затрагивается) + +- Если выбран механизм классификации проверок (FR-2 вариант б через suite), + e2e-проверки, заведомо зависящие от sandbox-инфраструктуры (C9a/C9b и связанные), + должны быть **отличимы** (по метке/категории) от реальных pipeline-проверок, + чтобы вердикт и/или exit-code мог их учитывать осознанно. Прежний дефолтный + режим (`stub`/`full-real`) и существующие проверки A/B сохраняются. +- Никакого «всегда 0»: реальный провал реальных проверок обязан давать ненулевой + exit-code / FAIL-категорию. + +## 8. Требования к pipeline-артефактам + +- Стадия деплоя по-прежнему производит машинный вердикт-артефакт + (`15-staging-log.md` / `14-deploy-log.md`) с корректным frontmatter. +- Артефакты, обновляемые по pipeline в этом PR: `docs/architecture/README.md` + (раздел про staging-гейт/self-deploy — отметить ORCH-061), + `docs/operations/STAGING_CHECK.md` (поведение C9a/C9b и/или sandbox-настройка), + `CHANGELOG.md`, при изменении контракта — `.openclaw/agents/deployer.md`. +- ADR: `docs/work-items/ORCH-061/06-adr/ADR-001-*.md` (решение по направлению/механизму). + +## 9. Нефункциональные требования + +- **Безопасность self-hosting:** реализация НЕ перезапускает/не роняет прод 8500 + в рамках задачи; сборки/recreate — только staging (8501). +- **Идемпотентность / restart-safe:** новое поведение переживает рестарт инстанса. +- **never-raise:** дефект-исправляющая логика не должна пробрасывать исключения в + `advance_stage` (по образцу merge-gate / image-freshness). +- **Обратная совместимость:** при выключенном флаге (FR-6) — прежнее поведение 1:1. +- **Тестируемость:** «чистая» вердикт-логика выделяется так, чтобы покрываться + unit-тестами без live staging/docker. + +## 10. Зависимости и связанные задачи + +- ORCH-35 (условный staging-гейт, ADR-0003), ORCH-36 (исполняемый self-deploy, + ADR-0007), ORCH-58 (провенанс staging-образа), ORCH-60 (skip escalated/Blocked). +- Блокирует: ORCH-54 (автономное внедрение). diff --git a/docs/work-items/ORCH-061/03-acceptance-criteria.md b/docs/work-items/ORCH-061/03-acceptance-criteria.md new file mode 100644 index 0000000..66c4e34 --- /dev/null +++ b/docs/work-items/ORCH-061/03-acceptance-criteria.md @@ -0,0 +1,90 @@ +# 03 — Критерии приёмки: ORCH-061 + +Work Item: **ORCH-061** · Тип: **BUG** · Приоритет: **P0** + +Формат: каждый критерий имеет чёткое условие **PASS/FAIL**. Критерии outcome-ориентированы +(не предписывают механизм); реализация может удовлетворить FR-2 направлением (а), (б) или обоими. + +--- + +## AC-1 — Автономный проход self-deploy без петли (главный критерий) +- **PASS:** для self-hosting `orchestrator` задача в состоянии `deploy-staging` + при здоровом стенде и корректном pipeline продвигается `deploy-staging → deploy` + (далее по штатному approve → `done`) **без** отката на `development` и **без** + ручного вмешательства в шаги staging/merge/retag/deploy. +- **FAIL:** наблюдается хотя бы один автоматический откат `deploy-staging → development` + при отсутствии реального регресса, либо для прохода требуется ручной шаг. + +## AC-2 — Ложный инфраструктурный FAIL не откатывает +- **PASS:** прогон, где **единственные** падения — заведомо sandbox-инфраструктурные + (C9a branch-not-found / C9b analyst-job-not-in-queue при ненастроенных bot-токенах + SANDBOX), а все реальные pipeline-проверки зелёные, приводит к + `staging_status: SUCCESS` (или эквивалентному «не-FAILED») → **нет** отката. +- **FAIL:** такой прогон даёт `staging_status: FAILED` → откат `deploy-staging → development`. + +## AC-3 — Реальный провал staging по-прежнему откатывает (страховка цела) +- **PASS:** прогон с провалом **реальной** pipeline-проверки (не инфра-исключение) + даёт `staging_status: FAILED` → откат `deploy-staging → development` + + `set_issue_blocked`/нотификации (как сейчас, ORCH-35). +- **FAIL:** реальный провал staging проходит как успех / задача доходит до `deploy`. + +## AC-4 — «no changes to commit» на action-стадии не есть недовыполнение +- **PASS:** на стадиях `deploy-staging`/`deploy` для self-deploy отсутствие + git-изменений не вызывает откат/блокировку; продвижение определяется успешным + exit + health/staging-вердиктом. +- **FAIL:** отсутствие коммита на стадии деплоя приводит к откату/недопродвижению. + +## AC-5 — Реальный провал прод-деплоя по-прежнему откатывает (БАГ-8 цел) +- **PASS:** `deploy_status: FAILED` (exit-code хука ≠ 0) → откат `deploy → development` + + `set_issue_blocked` + release merge-lease + clear deploy-state (как сейчас). +- **FAIL:** провал прод-деплоя проходит как `done`. + +## AC-6 — Условность self-hosting сохранена +- **PASS:** для не-self-hosting репо (`is_self_hosting_repo == False`) + `check_staging_status` остаётся `(True, "Staging gate N/A …")`, стадия деплоя + работает как прежде; поведение этих репо байт-в-байт не изменилось. +- **FAIL:** изменилось поведение для не-self-hosting репозиториев. + +## AC-7 — Kill-switch возвращает прежнее поведение +- **PASS:** при выключенном флаге нового поведения (FR-6) система ведёт себя 1:1 + как до ORCH-061 (включая прежний откат на инфра-FAIL, если флаг выключен). +- **FAIL:** новое поведение невозможно отключить / выключение не восстанавливает старое. + +## AC-8 — Контракты не сломаны +- **PASS:** `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, frontmatter-контракты + `staging_status:`/`deploy_status:` (только YAML, `SUCCESS|FAILED`), exit-code хука + (0/1/2) и `map_exit_code_to_status` — без регресса; снапшот-тест реестра гейтов зелёный. +- **FAIL:** изменены контракты стадий/гейтов/вердиктов или сломан снапшот реестра. + +## AC-9 — Схема БД не меняется +- **PASS:** нет миграций; `events`/`tasks`/`agent_runs`/`jobs` без изменений схемы. +- **FAIL:** добавлена/изменена колонка/таблица. + +## AC-10 — never-raise +- **PASS:** новая логика в пути `advance_stage`/staging-вердикта при любой внутренней + ошибке (docker/ssh/io/парсинг) даёт безопасный детерминированный вердикт и не + пробрасывает исключение в `advance_stage`. +- **FAIL:** исключение из новой логики всплывает в `advance_stage`/останавливает конвейер. + +## AC-11 — Наблюдаемость +- **PASS:** срабатывание нового поведения (игнор инфра-FAIL / ожидаемые no-changes) + даёт явную лог-строку (и при необходимости коммент/Telegram), позволяющую отличить + «честно зелёный» от «зелёного с допущением». +- **FAIL:** новое поведение срабатывает молча, неотличимо от честного зелёного. + +## AC-12 — Безопасность self-hosting +- **PASS:** реализация не перезапускает/не роняет прод-контейнер 8500 в рамках + задачи; любые сборки/recreate — только staging (8501). +- **FAIL:** код пути задачи рестартит/собирает прод 8500. + +## AC-13 — Документация обновлена (golden source) +- **PASS:** в том же PR обновлены `docs/architecture/README.md`, + `docs/operations/STAGING_CHECK.md` (поведение C9a/C9b и/или sandbox-настройка), + `CHANGELOG.md`, и (при смене контракта) `.openclaw/agents/deployer.md`; заведён + ADR `docs/work-items/ORCH-061/06-adr/ADR-001-*.md`. +- **FAIL:** функционал изменён без обновления документации/ADR. + +## AC-14 — Регрессионные тесты зелёные +- **PASS:** `pytest tests/ -q` проходит полностью; новые тесты из `04-test-plan.yaml` + присутствуют и зелёные; существующие staging/deploy/qg/stage_engine тесты не упали. +- **FAIL:** любой тест из плана отсутствует или красный. diff --git a/docs/work-items/ORCH-061/04-test-plan.yaml b/docs/work-items/ORCH-061/04-test-plan.yaml new file mode 100644 index 0000000..d1b1d50 --- /dev/null +++ b/docs/work-items/ORCH-061/04-test-plan.yaml @@ -0,0 +1,147 @@ +work_item: ORCH-061 +title: "BUG: deploy-staging петля — откат на development (self-deploy)" +description: > + План тестов на устранение зацикливания deploy-staging -> development для + self-hosting orchestrator. Покрывает обе подтверждённые причины: (1) ложный + FAILED check_staging_status из-за заведомо инфраструктурных C9a/C9b в sandbox; + (2) трактовку "no changes to commit" на action-стадии как недовыполнения. + Тесты outcome-ориентированы и не предписывают механизм: часть кейсов помечена + как mechanism-dependent (а=sandbox-инфра честно, б=толерантность/отвязка) — + финальный набор подтверждает архитектор в ADR; реализуются тесты под выбранный + механизм. Инвариант страховки (реальный регресс откатывает) и условность + self-hosting проверяются ВСЕГДА. +tests: + # --- Главный сценарий: нет петли ---------------------------------------- + - id: TC-01 + type: unit + description: > + Корректный self-deploy: при staging_status SUCCESS и пройденном merge/freshness + sub-gate advance_stage(deploy-staging, finished_agent=deployer) продвигает к + deploy (Phase A approval-pending), НЕ откатывает на development. (AC-1) + module: tests/test_stage_engine.py + expected: PASS + + - id: TC-02 + type: unit + description: > + Регресс-страховка ORCH-35: реальный провал реальной pipeline-проверки -> + staging_status FAILED -> advance_stage откатывает deploy-staging -> development + + set_issue_blocked. (AC-3) + module: tests/test_stage_engine.py + expected: PASS + + # --- Причина №1: ложный инфраструктурный FAIL --------------------------- + - id: TC-03 + type: unit + description: > + Классификация проверок staging_check: проверки, заведомо зависящие от + sandbox-инфраструктуры (C9a/C9b), отличимы (метка/категория) от реальных + pipeline-проверок. Чистая логика классификации/вердикта тестируется без + live staging/docker. (AC-2, mechanism-dependent: вариант б) + module: tests/test_staging_check_b6.py + expected: PASS + + - id: TC-04 + type: unit + description: > + Вердикт-логика: все реальные проверки PASS, падают ТОЛЬКО известные + sandbox-инфра проверки (C9a/C9b) -> итог не-FAILED (нет ложного отката). + (AC-2) + module: tests/test_qg_checks.py + expected: PASS + + - id: TC-05 + type: unit + description: > + Вердикт-логика: падает хотя бы одна РЕАЛЬНАЯ pipeline-проверка (помимо инфра) + -> итог FAILED (страховка не ослаблена, fail-closed). (AC-3) + module: tests/test_qg_checks.py + expected: PASS + + # --- Причина №2: no changes на action-стадии ---------------------------- + - id: TC-06 + type: unit + description: > + На action-стадии (deploy-staging/deploy) для self-deploy отсутствие + git-изменений ("no changes to commit") НЕ приводит к откату/недопродвижению; + продвижение определяется exit + вердиктом, а не наличием коммита. (AC-4) + module: tests/test_launcher.py + expected: PASS + + - id: TC-07 + type: unit + description: > + На code-стадии (development) отсутствие изменений всё ещё обрабатывается + прежним образом (нет ложного "успеха" там, где код должен был измениться) — + изменение FR-3 не протекает на не-action стадии. (AC-4, regression-guard) + module: tests/test_launcher.py + expected: PASS + + # --- Условность self-hosting -------------------------------------------- + - id: TC-08 + type: unit + description: > + Для не-self-hosting репо check_staging_status остаётся (True, "Staging gate + N/A …") и новое поведение НЕ активируется; поведение этих репо неизменно. + (AC-6, FR-5) + module: tests/test_qg.py + expected: PASS + + # --- Kill-switch / обратная совместимость ------------------------------- + - id: TC-09 + type: unit + description: > + При выключенном флаге нового поведения (FR-6) система ведёт себя 1:1 как до + ORCH-061: инфра-FAIL снова приводит к FAILED/откату. Дефолт флага безопасен. + (AC-7) + module: tests/test_config.py + expected: PASS + + # --- БАГ-8: реальный провал прод-деплоя ---------------------------------- + - id: TC-10 + type: unit + description: > + deploy_status FAILED (exit-code хука != 0) -> откат deploy -> development + + set_issue_blocked + release merge-lease + clear deploy-state (БАГ-8 не сломан). + (AC-5) + module: tests/test_deploy_rollback.py + expected: PASS + + # --- Контракты / реестр / never-raise ----------------------------------- + - id: TC-11 + type: unit + description: > + Снапшот реестра QG_CHECKS и STAGE_TRANSITIONS не изменён неожиданно; + frontmatter-контракты staging_status/deploy_status (SUCCESS|FAILED, только + YAML) сохранены. (AC-8) + module: tests/test_qg_registry_snapshot.py + expected: PASS + + - id: TC-12 + type: unit + description: > + never-raise: новая логика staging-вердикта/advance при внутренней ошибке + (io/парсинг/docker/ssh) возвращает безопасный детерминированный вердикт и не + пробрасывает исключение в advance_stage. (AC-10) + module: tests/test_stage_engine.py + expected: PASS + + # --- Интеграционный сквозной сценарий ------------------------------------ + - id: TC-13 + type: integration + description: > + Сквозной self-deploy на тестовой БД: задача deploy-staging при здоровом + стенде с инфра-only недочётами проходит deploy-staging -> deploy (Phase A) -> + (approve) -> deploy финализация SUCCESS -> done, БЕЗ единого отката на + development в логе переходов. (AC-1, AC-4) + module: tests/test_stage_engine.py + expected: PASS + + - id: TC-14 + type: integration + description: > + Наблюдаемость: при срабатывании нового поведения (игнор инфра-FAIL / + ожидаемые no-changes) присутствует явная лог-строка/диагностика, отличающая + "честно зелёный" от "зелёного с допущением". (AC-11) + module: tests/test_stage_engine.py + expected: PASS