Files
orchestrator/docs/work-items/ORCH-022/03-acceptance-criteria.md
claude-bot 5344084225
All checks were successful
CI / test (push) Successful in 18s
analyst(ET): auto-commit from analyst run_id=326
2026-06-07 16:54:54 +00:00

8.7 KiB
Raw Blame History

03 — Критерии приёмки: Security-гейт (ORCH-022)

Формат: каждый критерий имеет чёткое условие PASS/FAIL. Привязка к 01-brd.md (BR-) и 02-trz.md (FR-).


A. Secret-scanning (FR-1, BR-1/BR-2)

AC-1 — Подсаженный секрет блокирует гейт

  • PASS: ветка с тестовым секретом (напр. фиктивный AWS-ключ формата AKIA… вне аллоулиста) → security_status: FAIL; гейт возвращает (False, reason), причина называет секрет/файл.
  • FAIL: секрет не обнаружен ИЛИ гейт зелёный при наличии секрета.

AC-2 — Чистая ветка проходит

  • PASS: ветка без секретов → security_status: PASS; secrets_found: 0; гейт возвращает (True, …).
  • FAIL: ложное срабатывание (FAIL на чистой ветке).

AC-3 — Аллоулист подавляет заведомо-безопасное (BR-13)

  • PASS: совпадение, явно занесённое в версионируемый аллоулист (напр. плейсхолдер в .env.example / фикстура теста), не даёт FAIL.
  • FAIL: аллоулист игнорируется и даёт ложный FAIL.

B. Dependency audit (FR-2, BR-3/BR-4)

AC-4 — CVE уровня блокировки краснит гейт

  • PASS: зависимость с известной CRITICAL/HIGH CVE (при пороге по умолчанию HIGH) → вклад в security_status: FAIL; deps_blocking >= 1.
  • FAIL: блокирующая уязвимость не приводит к FAIL.

AC-5 — Низкая severity = warning, не блок

  • PASS: только MEDIUM/LOW уязвимости → security_status: PASS, при этом deps_warning >= 1 и находки перечислены в теле артефакта.
  • FAIL: MEDIUM/LOW блокирует продвижение.

AC-6 — Порог блокировки конфигурируем (BR-10)

  • PASS: при ORCH_SECURITY_DEP_BLOCK_SEVERITY=CRITICAL та же HIGH-уязвимость становится warning (не блок); при =HIGH — блок. Поведение детерминированно определяется флагом.
  • FAIL: флаг не влияет на классификацию.

AC-7 — Degrade при недоступном CVE-фиде

  • PASS: недоступность фида обрабатывается по решению ADR детерминированно и протестированно (дефолт: fail-open + громкий warning, гейт не краснеет ложно).
  • FAIL: недоступность фида даёт неконтролируемый красный/исключение.

C. Вердикт и артефакт (FR-3, BR-6)

AC-8 — Машинный вердикт только из frontmatter

  • PASS: вердикт читается ТОЛЬКО из YAML-frontmatter 17-security-report.md; проза с «PASS»/«FAIL» в теле не влияет на решение. Negative-токен (FAIL) авторитетен.
  • FAIL: вердикт извлекается из тела/прозы.

AC-9 — Битый/отсутствующий frontmatter → fail-closed на чтении

  • PASS: нет frontmatter / битый YAML / нет поля security_status(False, reason) (как _parse_deploy_status/check_reviewer_verdict).
  • FAIL: битый артефакт трактуется как PASS.

AC-10 — Артефакт создаётся с корректными полями

  • PASS: после прогона существует 17-security-report.md с валидным frontmatter (security_status, secrets_found, deps_blocking, deps_warning) и телом-списком.
  • FAIL: артефакт не создан/без машинных полей.

D. Откат и retry (FR-4, BR-5)

AC-11 — Красный гейт → откат на development + developer-retry

  • PASS: FAIL → стадия задачи становится development, enqueue developer, Plane-коммент + notify_qg_failure; счётчик developer-retry растёт.
  • FAIL: при FAIL задача продвигается дальше / не откатывается.

AC-12 — task_desc несёт дословную причину (ORCH-046-паттерн)

  • PASS: task_desc для перезапущенного developer содержит конкретику находок (какие секреты/CVE), а не только ссылку на артефакт.
  • FAIL: developer получает только ссылку без сути.

AC-13 — Cap retry и эскалация

  • PASS: после MAX_DEVELOPER_RETRIES (3) безуспешных фиксов — set_issue_blocked + Telegram-алерт; бесконечного отскока нет.
  • FAIL: откат зацикливается без cap/эскалации.

E. Условный раскат и устойчивость (FR-5/FR-6, BR-8/BR-9)

AC-14 — Не-self репозиторий = no-op pass

  • PASS: для repo, не входящего в scope и не self-hosting → гейт возвращает (True, "security-gate N/A for <repo>") мгновенно, конвейер такого репо не меняется.
  • FAIL: гейт реально запускается/блокирует чужой репо при пустом scope.

AC-15 — Kill-switch отключает гейт

  • PASS: ORCH_SECURITY_GATE_ENABLED=false → гейт — no-op pass ((True, …)), поведение конвейера 1:1 как до ORCH-022.
  • FAIL: при выключенном флаге гейт всё ещё блокирует.

AC-16 — never-raise

  • PASS: искусственный сбой (нет бинаря сканера / таймаут / исключение внутри) → (False, reason) без проброса исключения; advance_stage не падает, конвейер других задач/проектов не встаёт.
  • FAIL: внутренняя ошибка пробрасывается/вешает движок.

AC-17 — Таймаут ограничен

  • PASS: сканирование, превысившее ORCH_SECURITY_SCAN_TIMEOUT_S, корректно прерывается → детерминированный вердикт (по политике degrade), без зависания.
  • FAIL: сканер висит без таймаута.

F. Инварианты и интеграция (BR-7/BR-12, TRZ §7)

AC-18 — STAGE_TRANSITIONS/QG_CHECKS консистентны

  • PASS: при варианте «под-гейт ребра» STAGE_TRANSITIONS не изменён; новый чек зарегистрирован в QG_CHECKS; _run_qg корректно его диспетчеризует. Все существующие тесты гейтов/стадий зелёные.
  • FAIL: сломан реестр/переходы/существующие тесты.

AC-19 — Гейт не деплоит/не рестартит прод

  • PASS: код гейта не вызывает деплой-хук/рестарт прод-контейнера; только чтение/сканирование.
  • FAIL: гейт инициирует рестарт/деплой.

AC-20 — Документация обновлена в том же PR (BR-12)

  • PASS: обновлены CLAUDE.md (артефакт 17-…), docs/architecture/README.md (таблица гейтов + реестр QG + раздел ORCH-022), CHANGELOG.md, .env.example (ORCH_SECURITY_*); заведён ADR 06-adr/ADR-001-*.
  • FAIL: функционал есть, документация/ADR не обновлены → reviewer обязан REQUEST_CHANGES (CLAUDE.md §6).

AC-21 — End-to-end на тестовой задаче

  • PASS: прогон на self-hosting-репо: грязная ветка (секрет/CVE) → откат на development; после фикса чистая ветка → гейт зелёный → конвейер идёт дальше; прод не затронут в процессе.
  • FAIL: любой шаг E2E не воспроизводится.