108 lines
7.9 KiB
YAML
108 lines
7.9 KiB
YAML
work_item: ORCH-114
|
||
stage: analysis
|
||
author_agent: analyst
|
||
status: ready-for-review
|
||
created_at: 2026-06-15
|
||
model_used: claude-opus-4-8
|
||
escalate: full-cycle
|
||
title: "Ownership-lease для side-effectful переходов стадий + умное восстановление при старте"
|
||
framework: pytest
|
||
scope: >
|
||
Покрывается: единое владение side-effectful переходом (FR-1), CAS/epoch на запись стадии (FR-2),
|
||
осведомлённость reaper о живом/мёртвом владении на всех путях (FR-3), умное восстановление при
|
||
рестарте (FR-4), skip/defer в reconciler F-1 и webhook (FR-5), наблюдаемость (FR-6), kill-switch
|
||
и never-raise (FR-7). Вне покрытия: переход на uvicorn --workers>1, частные симптомы ORCH-110/112
|
||
(уже закрыты и переиспользуются), изменение STAGE_TRANSITIONS/QG_CHECKS/check_*.
|
||
notes: >
|
||
TC-01 — ОБЯЗАТЕЛЬНЫЙ регресс класса инцидента ORCH-111: красный до фикса, зелёный после.
|
||
Все side-effectful вызовы (merge_pr / coverage-ratchet / image-rebuild / deploy-init) проверяются
|
||
через тест-двойники со счётчиком вызовов — без сети/реального git/прода/ssh. Restart-recovery
|
||
моделируется сбросом in-memory состояния + повторным прогоном стартового восстановления над durable
|
||
состоянием БД. Полный регресс tests/ должен оставаться зелёным; при выключенном kill-switch
|
||
поведение байт-в-байт прежнее.
|
||
|
||
tests:
|
||
- id: TC-01
|
||
type: integration
|
||
description: "ОБЯЗАТЕЛЬНЫЙ РЕГРЕСС. Два конкурентных входа в advance_stage(deploy-staging) одной задачи (живой финализатор + reaper/reconciler/webhook): каждый side-effectful шаг (merge_pr/ratchet/rebuild/deploy-init/enqueue) вызывается ровно один раз; персистится один согласованный исход; второй актор — lost-race/defer без побочных эффектов. Красный до фикса, зелёный после."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-02
|
||
type: unit
|
||
description: "CAS-запись стадии: первый writer применяет (rowcount=1), второй с устаревшим предусловием получает lost-race (rowcount=0) и не мутирует стадию (FR-2/AC-2)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-03
|
||
type: unit
|
||
description: "Жизненный цикл владения: acquire на границе финализации; release в try/finally при нормальном завершении, при исключении и при откате (lease не течёт); durable-запись видна другому актору (FR-1/AC-3)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-04
|
||
type: integration
|
||
description: "Reaper defer при живом владении на путях за пределами Tier-2/deploy-staging ORCH-113: повторный advance не выполняется, атомарный reap_running_job rowcount-guard сохранён, ведётся счётчик defer (FR-3/AC-4)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-05
|
||
type: unit
|
||
description: "Reaper добивает мёртвое/устаревшее владение в пределах Tier-3 backstop reaper_max_running_s; маркер владения backstop не обходит; задача не клинится бессрочно (FR-3/AC-5/NFR-6)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-06
|
||
type: integration
|
||
description: "Умное восстановление при рестарте: процесс убит в середине финализации, in-memory сброшен; стартовое восстановление над durable-состоянием + авторитетными фактами (SHA-in-main, INITIATED) сходится к единственному исходу без повторного необратимого эффекта (FR-4/AC-6)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-07
|
||
type: integration
|
||
description: "Reconciler F-1 (advance_if_gate_passed) делает defer/skip при активном lease перехода; fail-safe: неопределённость lease → консервативный skip (FR-5/AC-7)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-08
|
||
type: integration
|
||
description: "Webhook-путь (plane._try_advance_stage, Approved/Confirm Deploy) делает defer при активном lease; поздний легитимный сигнал не теряется (повтор после release / идемпотентный no-op) (FR-5/AC-8)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-09
|
||
type: integration
|
||
description: "Kill-switch off: lease не пишется/не читается, CAS вырождается в прежний безусловный update_task_stage, reaper/reconciler/webhook/startup — байт-в-байт до ORCH-114; существующий pytest tests/ зелёный (FR-7/AC-9/NFR-8)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-10
|
||
type: unit
|
||
description: "never-raise + fail-open/fail-closed: ошибка/повреждённая запись lease/исключение БД не роняют конвейер; hot-path claim/guard fail-open; prod-safety решение fail-closed; WARNING + безопасный дефолт (FR-7/AC-10/NFR-1)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-11
|
||
type: unit
|
||
description: "Структурный аудит инвариантов: STAGE_TRANSITIONS / QG_CHECKS / имена-семантика check_* / вердикт-ключи байт-в-байт; новое хранилище аддитивно/идемпотентно (CREATE TABLE IF NOT EXISTS / _ensure_column), схемы существующих таблиц неизменны (NFR-3/AC-11)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-12
|
||
type: integration
|
||
description: "Наблюдаемость: GET /queue несёт аддитивный read-only блок владения (держатели/возраст/defer/реклеймы), существующие ключи не сломаны; форсированный/устаревший реклейм даёт Telegram-алерт с кликабельным номером (FR-6/AC-12)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-13
|
||
type: unit
|
||
description: "Self-hosting безопасность: механизм владения не инициирует рестарт прод-контейнера, не пушит/force-push в main, не трогает detached deploy-процесс (NFR-5/AC-13)."
|
||
module: tests/test_orch114_transition_ownership.py
|
||
expected: PASS
|
||
|
||
- id: TC-14
|
||
type: integration
|
||
description: "Полный регресс конвейера: pytest tests/ остаётся зелёным; deploy-staging-ребро и deploy-finalizer (Phase C) проходят при включённом механизме без двойных эффектов в одно-акторном happy-path (BR-8)."
|
||
module: tests/
|
||
expected: PASS
|