diff --git a/docs/work-items/ORCH-117/13-test-report.md b/docs/work-items/ORCH-117/13-test-report.md new file mode 100644 index 0000000..410fd6a --- /dev/null +++ b/docs/work-items/ORCH-117/13-test-report.md @@ -0,0 +1,69 @@ +--- +result: PASS +work_item: ORCH-117 +stage: testing +author_agent: tester +status: pass +created_at: 2026-06-15 +model_used: claude-opus-4-8 +type: test-report +work_item_id: ORCH-117 +--- + +# Test Report — ORCH-117 — sandbox-only fail-closed изоляция записи в Plane + +## Окружение +- Python: 3.12.13 +- pytest: 8.3.3 (plugins: cov-5.0.0, anyio-4.13.0, asyncio-0.23.8) +- Worktree: `/repos/_wt/orchestrator/feature_ORCH-117-bug-test-staging-plane-writes-` +- Ветка: `feature/ORCH-117-bug-test-staging-plane-writes-` +- Дата: 2026-06-15 + +## Smoke API (read-only) +- `GET /health` → `{"status":"ok","service":"orchestrator"}` ✅ +- `GET /status` → 200, ORCH-117 (task 104) на стадии `testing`, `agent_running: null` ✅ +- `GET /queue` → 200; блок `serial_gate` присутствует ✅; блок `auto_labels` присутствует ✅ + (регресс смока ORCH-088 не обнаружен). + +## Результаты — покрытие test-plan (04-test-plan.yaml) + +| TC ID | Описание | Тест | Результат | +|-------|----------|------|-----------| +| TC-01 | РЕГРЕСС ORCH-114: pytest-env + живой прод-токен → `notify_stage_change('ORCH-114','deploy','done')` на боевой проект делает 0 httpx.patch/post | `test_tc01_notify_stage_change_prod_makes_zero_writes` | PASS | +| TC-02 | `update_issue_state` в тест-процессе с боевым проектом → блок; аудит `prod-project-in-test` | `test_tc02_update_issue_state_prod_blocked` | PASS | +| TC-03 | `add_comment` в тест-процессе с боевым проектом → блок (httpx.post не вызван) | `test_tc03_add_comment_prod_blocked` | PASS | +| TC-04 | `_set_issue_state_direct` + `set_issue_done` в тест-процессе с боевым проектом → блок | `test_tc04_set_issue_state_direct_prod_blocked`, `test_tc04_set_issue_done_prod_blocked` | PASS | +| TC-05 | Default-deny: без opt-in запись блокируется для ЛЮБОГО проекта (вкл. sandbox) | `test_tc05_default_deny_blocks_sandbox_and_prod` | PASS | +| TC-06 | Sandbox-разрешение: opt-in + SANDBOX `8c5a3025-…` → реальный httpx-вызов разрешён | `test_tc06_sandbox_optin_allows_write` | PASS | +| TC-07 | Sandbox-only даже с opt-in: opt-in включён, боевой проект → блок | `test_tc07_optin_still_blocks_prod` | PASS | +| TC-08 | Fail-closed при неопределённости: пустой/неразрешимый project_id → блок | `test_tc08_ambiguous_target_blocked` | PASS | +| TC-09 | Устойчивость к захвату токена на импорте: гард блокирует на момент вызова | `test_tc09_blocks_regardless_of_captured_token` | PASS | +| TC-10 | Нулевая регрессия боевого рантайма: НЕ-pytest → гард no-op, реальный httpx-вызов | `test_tc10_live_runtime_is_noop` | PASS | +| TC-11 | Staging != pytest: staging-рантайм (sandbox) → запись проходит | `test_tc11_staging_writes_sandbox` | PASS | +| TC-12 | Аудит: блок → структурный WARNING/ERROR с полями; sandbox-allow → audit-INFO | `test_tc12_block_audited_loudly`, `test_tc12_sandbox_allow_audited_info` | PASS | +| TC-13 | Дефолтная autouse-страховка conftest: обычный тест не пишет в боевой Plane | `test_tc13_conftest_floor_default_deny` | PASS | +| TC-14 | Kill-switch без чёрного хода: прод-запись из pytest не разрешается молча | `test_tc14_no_killswitch_backdoor` | PASS | +| TC-15 | Полный регресс `tests/ -q` зелёный (autouse-фикстура не ломает существующие тесты) | `pytest tests/` | PASS | + +Сопоставление с `03-acceptance-criteria.md`: AC-1↔TC-01, AC-2↔TC-06, AC-3↔TC-07, +AC-4↔TC-05/08, AC-5↔TC-10, AC-6↔TC-11, AC-7↔TC-09, AC-8↔TC-12, AC-9↔TC-14, +AC-10 (docs/config — проверено reviewer'ом, APPROVED), AC-11↔TC-15. Все AC покрыты. + +## Вывод pytest + +Целевой файл: +``` +tests/test_orch117_plane_write_isolation.py ... 16 passed, 1 warning in 0.40s +(TC-01…TC-14; TC-04 и TC-12 — по два теста) +``` + +Полный регресс: +``` +2068 passed, 1 warning in 88.02s (0:01:28) +``` +(единственный warning — PydanticDeprecatedSince20 в `src/config.py:8`, не связан с ORCH-117.) + +## Итог +**PASS** — все 15 TC выполнены и сопоставлены с критериями приёмки; целевой сьют (16 тестов) и +полный регресс (2068 passed) зелёные; smoke API (`/health`, `/status`, `/queue` с блоками +`serial_gate`/`auto_labels`) — OK. Задача готова к переходу на `deploy-staging`.