141 lines
8.7 KiB
Markdown
141 lines
8.7 KiB
Markdown
# 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 не воспроизводится.
|