Files
orchestrator/docs/work-items/ORCH-123/03-acceptance-criteria.md
claude-bot 3865b14a1c
All checks were successful
CI / test (push) Successful in 1m12s
analyst(ET): auto-commit from analyst run_id=747
2026-06-16 07:55:43 +03:00

12 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-123 analysis analyst ready-for-review 2026-06-16 claude-opus-4-8

03 — Критерии приёмки (Acceptance Criteria): ORCH-123 — staging-runner execution strategy fix

Work Item: ORCH-123 · Repo: orchestrator · Стадия: analysis

Формат: каждый критерий имеет PASS (что должно быть истинно для приёмки) и FAIL (что считается провалом). Любой машинный/ручной reviewer проверяет их буквально по файлам репозитория. Критерии механизм-агностичны (конкретную стратегию выбирает архитектор), проверяют требуемый инвариант, а не способ реализации.


AC-1 — staging-сюита реально исполняется в проде (без docker CLI в контейнере)

Условие: Для self-hosting orchestrator на deploy-staging staging-runner запускает staging_check.py так, что сюита исполняется в боевом окружении, не завися от бинаря docker внутри прод-контейнера.

  • PASS: Стратегия исполнения staging-сюиты не требует наличия docker CLI внутри прод-контейнера orchestrator (исполняется host-side через существующий доверенный канал, либо через смонтированный сокет/SDK с security-обоснованием, либо CLI добавлен в образ — на выбор ADR); тест воспроизводит окружение «нет docker в контейнере» и подтверждает, что сюита исполняется (а не падает spawn-error'ом).
  • FAIL: staging-runner по-прежнему вызывает docker exec напрямую из прод-контейнера без доступного исполняемого/канала → proc_group spawn-error → tool-error.

AC-2 — ORCH-116-подобная задача проходит deploy-staging

Условие: Задача с зелёными reviewer/tester и корректным кодом доходит до deploy, а не откатывается на development из-за раннера.

  • PASS: При успешной staging-сюите (exit 0) → staging_status: SUCCESS → штатное продвижение по под-гейтам ребра deploy-staging → deploy (контракт не тронут); ORCH-116-подобный сценарий в тесте/симуляции достигает deploy.
  • FAIL: Корректная задача откатывается на development по причине раннера/окружения.

AC-3 — environment/tool-error НЕ даёт вводящего в заблуждение код-фейл-отката

Условие: Невозможность исполнить сюиту по причине окружения (нет исполняемого/канал недоступен) не трактуется как код-фейл.

  • PASS: environment/tool-error → отличимый инфра/environment-исход (задача не откатывается на development как код-фейл; developer-retry не инкрементируется; оператору идёт алерт «инфра/ окружение, НЕ дефект кода»). Подтверждено тестом: при недоступном исполняемом задача не уходит в development и счётчик developer-retry не растёт.
  • FAIL: environment-дефект завершается write_staging_log("FAILED") + advance (откат на development) и/или жжёт developer-retry.

AC-4 — настоящий код-фейл по-прежнему откатывает (анти-over-tolerance)

Условие: Если сюита реально исполнилась и упала (exit≠0), поведение не ослаблено.

  • PASS: exit≠0 при исполнившейся сюите → staging_status: FAILEDпрежний откат deploy-staging → development + developer-retry (байт-в-байт контракт ORCH-115 для «сюита исполнилась»). Тест подтверждает, что реальный фейл сюиты НЕ маскируется как «инфра».
  • FAIL: Настоящий код-фейл сюиты трактуется как environment/инфра и не откатывает на development.

AC-5 — prod-like preflight ловит «исполняемое/стратегия неработоспособна» до раската

Условие: Условие инцидента детектируется заранее, а не ложным откатом реальной задачи.

  • PASS: Существует preflight (на старте сервиса и/или в smoke/staging_check.py/applies/ should_intercept), который при неработоспособной стратегии исполнения сигнализирует (лог/алерт/ отметка) до того, как задача дойдёт до ложного отката; есть тест, симулирующий «нет docker в контейнере», и он проверяет именно это.
  • FAIL: Нет механизма раннего детекта; «исполняемое отсутствует» обнаруживается только постфактум откатом реальной задачи.

AC-6 — обязательный регресс-тест (red → green)

Условие: Инцидент ORCH-116 воспроизводится тестом.

  • PASS: Есть тест, моделирующий исполнение staging-сюиты в окружении без docker CLI в контейнере; он красный на коде до фикса (воспроизводит spawn-error → tool-error → ложный откат/false-FAILED) и зелёный после фикса (сюита исполняется / environment-дефект не даёт код-фейл-отката).
  • FAIL: Регресс-теста нет, либо он зелёный и до фикса (значит, не воспроизводит дефект).

AC-7 — гейт/контракт/стадии — без регресса (NFR-1)

Условие: Меняется продюсер/стратегия исполнения, не гейт.

  • PASS: STAGE_TRANSITIONS, реестр QG_CHECKS, имена и семантика check_staging_status/ _parse_staging_status, machine-verdict ключи (staging_status:/deploy_status:/…), схема БД — байт-в-байт прежние (структурный анти-регресс-тест зелёный); 15-staging-log.md сохраняет staging_status:-frontmatter + 52c-схему (author_agent: staging-runner/model_used: n/a).
  • FAIL: Любое из перечисленного изменено (имя/регистр/семантика/значение) либо введена миграция БД.

AC-8 — self-hosting safety (NFR-2)

Условие: Путь исполнения staging-runner безопасен для общего прод-инстанса.

  • PASS: Путь никогда не рестартит прод orchestrator (8500), не делает docker compose up orchestrator/--build прода, не force-push, не пишет в main, не правит .env; оперирует только запуском staging-сюиты (8501) и записью лога (статический/поведенческий ассерт зелёный).
  • FAIL: Путь способен затронуть прод-контейнер/main/.env/сделать force-push.

AC-9 — security-review для socket/CLI-вариантов (NFR-3)

Условие: Если выбран вариант с прямым docker.sock/CLI из контейнера.

  • PASS: ADR (06-adr/) содержит явный security-разбор (поверхность атаки docker.sock = root-эквивалент, ограничение прав, :ro где возможно) либо выбран host-side ssh-вариант, переиспользующий доверенный ORCH-036 механизм без расширения привилегий — и это зафиксировано.
  • FAIL: Введён доступ к docker.sock/CLI из контейнера без security-обоснования в ADR.

AC-10 — kill-switch / область (NFR-4, NFR-6)

Условие: Обратимость и скоуп сохранены.

  • PASS: staging_runner_enabled=Falsedeploy-staging снова через LLM-deployer (_spawn) байт-в-байт; applies(repo): self-hosting orchestrator — real, прочие репо — no-op; любой новый флаг стратегии имеет дефолт = боевое (откат флагом → поведение до ORCH-123). Подтверждено тестом.
  • FAIL: Выключение kill-switch не возвращает прежний путь, либо затронуты прочие репо.

AC-11 — never-raise / очередь не клинится (NFR-5)

Условие: Сбой стратегии исполнения не роняет worker и не клинит очередь.

  • PASS: Любая ошибка исполнения/классификации изолирована (never-raise); задача либо штатно продвигается, либо остаётся на deploy-staging для reconciler/reaper без вечного залипания; полный pytest tests/ -q зелёный.
  • FAIL: Ошибка исполнения роняет worker / задача залипает на deploy-staging навсегда / тесты красные.

AC-12 — документация границы исполнения (BR-5)

Условие: Граница исполнения staging-сюиты задокументирована.

  • PASS: docs/operations/INFRA.md и docs/architecture/README.md содержат явное описание: где/как исполняется staging-сюита относительно прод-контейнера, какие исполняемые/сокеты доступны, почему docker-операции идут host-side (структурная сверка зелёная); CHANGELOG.md/CLAUDE.md обновлены.
  • FAIL: Граница исполнения нигде не описана, или docs противоречат фактическому коду.

Сводная матрица AC ↔ FR/BR

AC Покрывает
AC-1 BR-1 / FR-1
AC-2 BR-1 / FR-1
AC-3 BR-2 / FR-2, FR-3
AC-4 BR-3 / FR-2
AC-5 BR-4 / FR-4
AC-6 BR-4 / FR-1, FR-2
AC-7 NFR-1 / FR-(6)
AC-8 NFR-2
AC-9 NFR-3
AC-10 NFR-4, NFR-6 / FR-5
AC-11 NFR-5
AC-12 BR-5 / FR-6