Files
orchestrator/docs/work-items/ORCH-117/04-test-plan.yaml

114 lines
7.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
work_item: ORCH-117
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-15
model_used: claude-opus-4-8
title: "Sandbox-only fail-closed изоляция записи в Plane (регресс ORCH-114)"
framework: pytest
scope: >
Покрывает fail-closed гард записи в Plane: блок прод-записи из тест-процесса даже при живом
боевом токене (обязательный регресс ORCH-114), sandbox-only-разрешение под явным opt-in,
default-deny по умолчанию, отличие тест-процесса от боевого/staging рантайма, перехват на
момент вызова (устойчивость к захвату токена на импорте), аудит. ВНЕ покрытия: реальные сетевые
вызовы к боевому Plane (запрещены самим фиксом) — всё через мок httpx; выбор механизма детекта —
зона ADR (тесты проверяют поведение, не реализацию).
notes: >
TC-01 — ОБЯЗАТЕЛЬНЫЙ регресс инцидента ORCH-114: красный до фикса, зелёный после. Все три
примитива записи (update_issue_state / add_comment / _set_issue_state_direct) проверяются на
блок/разрешение через мок httpx.patch/httpx.post (никаких реальных сетевых вызовов). Полный
регресс tests/ должен оставаться зелёным (autouse fail-closed-фикстура не ломает существующие
тесты, большинство из которых уже мокируют plane_*/add_comment). Боевой ID проекта в тестах —
7a79f0a9-5278-49cd-9007-9a338f238f9c; sandbox — 8c5a3025-4f9d-4190-b79f-fa06276bb27e.
tests:
- id: TC-01
type: integration
description: "РЕГРЕСС ORCH-114: pytest-env + живой прод-токен → notify_stage_change('ORCH-114','deploy','done') на боевой проект НЕ делает ни одного httpx.patch/post (мок httpx не вызван для prod-URL / гард блокирует). Красный до фикса, зелёный после."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-02
type: unit
description: "update_issue_state в тест-процессе с целевым боевым проектом 7a79f0a9-… → блок (httpx.patch не вызван); аудит-причина prod-project-in-test."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-03
type: unit
description: "add_comment в тест-процессе с боевым проектом → блок (httpx.post не вызван)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-04
type: unit
description: "_set_issue_state_direct в тест-процессе с боевым проектом → блок (httpx.patch не вызван). Покрывает все set_issue_* (Done/In Review/Blocked/…), сводящиеся к этому примитиву."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-05
type: unit
description: "Default-deny: без явного opt-in запись в тест-процессе блокируется для ЛЮБОГО целевого проекта (в т.ч. sandbox)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-06
type: unit
description: "Sandbox-разрешение: opt-in включён + целевой проект SANDBOX 8c5a3025-… → реальный httpx-вызов разрешён и адресован sandbox-URL (мок подтверждает вызов)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-07
type: unit
description: "Sandbox-only даже с opt-in: opt-in включён, но целевой проект боевой → блок (allowlist sandbox-only), независимо от opt-in."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-08
type: unit
description: "Fail-closed при неопределённости: целевой project_id неразрешим/пуст в тест-процессе → блок (NFR-1 'не знаю ⇒ не пишу')."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-09
type: unit
description: "Устойчивость к захвату на импорте: PLANE_HEADERS содержит реальный токен, env/settings не подменяются постфактум → гард всё равно блокирует прод-запись на момент вызова (не зависит от os.environ.setdefault / подмены plane_api_token)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-10
type: unit
description: "Нулевая регрессия боевого рантайма: при имитации НЕ-pytest процесса гард = no-op, httpx.patch/post вызывается с прежним URL/headers/payload (запись в Plane как до ORCH-117)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-11
type: unit
description: "Staging != pytest: имитация staging-рантайма (sandbox-проект, не тест-процесс) → запись в SANDBOX проходит (детект тест-процесса не срабатывает ложно)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-12
type: unit
description: "Аудит: на блокировку эмитится структурный WARNING/ERROR с project_id/work_item/операцией/причиной (caplog); на разрешённую sandbox-запись — audit-INFO."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-13
type: integration
description: "Дефолтная autouse-страховка conftest: репрезентативный advance стадии в обычном тесте не делает реальной записи в боевой Plane (страховка активна по умолчанию для всего сьюта)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-14
type: unit
description: "Kill-switch без чёрного хода: при выключенном kill-switch гарда запись в БОЕВОЙ проект из pytest всё равно не разрешается молча (реальная sandbox-запись управляется только opt-in+allowlist)."
module: tests/test_orch117_plane_write_isolation.py
expected: PASS
- id: TC-15
type: integration
description: "Полный регресс tests/ зелёный — внедрённая autouse fail-closed-фикстура не ломает существующие тесты (smoke: pytest tests/ -q)."
module: tests/
expected: PASS