work_item: ORCH-124
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-16
model_used: claude-opus-4-8
title: "Serial-gate wait/pause semantics — paused predecessor must not block urgent successor"
framework: pytest
scope: >
  Покрывает определение "активной задачи" в serial-gate (build_claim_clause /
  repo_has_active_task / _per_repo_snapshot), durable явный сигнал паузы и его учёт в
  горячем SQL claim, сохранность анти-stale-base ORCH-088, явных блоков (freeze/task_deps),
  наблюдаемости GET /queue, never-raise/fail-directions и kill-switch. Вне покрытия:
  изменения STAGE_TRANSITIONS/QG_CHECKS/check_* (их НЕТ), сетевые вызовы Plane API на hot-path
  (запрещены — проверяется их ОТСУТСТВИЕ), реальный прод-деплой/рестарт.
notes: >
  TC-01 — ОБЯЗАТЕЛЬНЫЙ регресс-тест инцидента ORCH-116/ORCH-123: красный до фикса, зелёный
  после. Точные имена флагов/колонок/эндпоинтов и SQL-форма предиката зависят от выбранного
  механизма (ADR архитектора) — тест-план фиксирует ПОВЕДЕНИЕ, не реализацию. Тесты
  работают на временной SQLite-БД без сети/Plane/прода (паттерн tests/test_serial_gate*.py).
  Полный регресс tests/ должен оставаться зелёным (особенно test_serial_gate*.py).

tests:
  - id: TC-01
    type: integration
    description: "РЕГРЕСС (обязательный): репо с более ранней приостановленной задачей A + более поздняя срочная B → claim_next_job выбирает analyst-job B (гейт открыт). Красный до фикса, зелёный после. Воспроизводит ORCH-116/ORCH-123."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-02
    type: unit
    description: "Предшественник в Backlog (по явному намерению) не считается активным: build_claim_clause не блокирует analyst-job успешника."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-03
    type: unit
    description: "Предшественник в Needs-Input (по явному намерению) не блокирует успешника — параллельно AC-1 для иного wait-состояния."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-04
    type: unit
    description: "АНТИ-РЕГРЕСС ORCH-088: нормально исполняемый предшественник (не на паузе, стадия вне done/cancelled) ПО-ПРЕЖНЕМУ блокирует analyst-job успешника (FIFO цел)."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-05
    type: unit
    description: "Пауза требует явного durable намерения: задача без операторского сигнала паузы остаётся активной (гейт держится); сигнал паузы DB-резолвим."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-06
    type: unit
    description: "Durable: сигнал паузы переживает пересоздание соединения/рестарт (читается из БД, не из памяти процесса)."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-07
    type: unit
    description: "Возобновление (resume) восстанавливает участие задачи в serial-gate (держит гейт / ре-входит в FIFO согласно ADR); нет вечного обхода."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-08
    type: unit
    description: "Явные блоки сохранены: активный repo_freeze продолжает блокировать claim успешника; пауза freeze не обходит."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-09
    type: unit
    description: "Явные блоки сохранены: незавершённая объявленная зависимость (job_deps/task_deps) продолжает блокировать claim; пауза dependency не обходит."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-10
    type: unit
    description: "GET /queue snapshot: приостановленный предшественник НЕ показывается как active_task; причина ожидания успешника корректна (active-task/paused-predecessor/freeze/dependency); существующие ключи snapshot сохранены."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-11
    type: unit
    description: "Согласованность трёх точек: build_claim_clause, repo_has_active_task и _per_repo_snapshot дают один и тот же вердикт 'активна' на одном входе (анти-дрейф)."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-12
    type: unit
    description: "Hot-path offline: claim_next_job + build_claim_clause резолвят паузу без сетевого вызова (Plane API не вызывается); claim работает при недоступном Plane."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-13
    type: unit
    description: "never-raise / fail-directions: инъекция ошибки в логику паузы → build_claim_clause fail-OPEN ('' фрагмент, очередь не клинит), freeze-решение fail-CLOSED; ни одна публичная функция не бросает."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-14
    type: unit
    description: "Kill-switch / нейтральность: при выключенном под-флаге паузы (и/или serial_gate_enabled) поведение serial-gate байт-в-байт как ORCH-088/090; вне области репо — не затронуто (enduro)."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS

  - id: TC-15
    type: unit
    description: "Структурный анти-регресс: STAGE_TRANSITIONS, состав QG_CHECKS, имена check_* и machine-verdict ключи не изменены; схемы существующих таблиц tasks/jobs/job_deps/repo_freeze не сломаны."
    module: tests/test_orch124_serial_gate_pause.py
    expected: PASS
