42 lines
5.4 KiB
Markdown
42 lines
5.4 KiB
Markdown
---
|
||
work_item: ORCH-126
|
||
stage: architecture
|
||
author_agent: architect
|
||
status: accepted
|
||
created_at: 2026-06-17
|
||
model_used: claude-opus-4-8
|
||
track: bug
|
||
---
|
||
|
||
# 10 — Технические риски: ORCH-126 — гигиена run-ownership queued-job
|
||
|
||
Work Item: **ORCH-126** · Repo: **orchestrator** · Стадия: architecture
|
||
|
||
> Информационный (гейтом не парсится). Риски реализации сброса `run_id`/`pid` на путях возврата в
|
||
> `queued` и их митигейшн. На bug-маршруте необязателен, но включён: правка — горячий путь клейма,
|
||
> затрагивает 4 маркированных инварианта (ORCH-065/113/114/099) на **общей** очереди всех проектов.
|
||
|
||
## Реестр рисков
|
||
|
||
| ID | Риск | Вер. | Влия. | Митигейшн |
|
||
|----|------|------|-------|-----------|
|
||
| TR-1 | **Сброс run-ownership не в той точке** — обнуление `run_id`/`pid` у **активного** `running`-job стёрло бы идентичность живого run'а (reaper/`/metrics` потеряли бы pid живого процесса; зомби-детекция сломалась бы). | Низ. | Выс. | Сброс **строго на переходе В `queued`** (D1) и в `claim` **до** `_spawn` (D2). Активный `running` не трогается. TC-10 (анти-регресс здорового job'а) + TC-04 (атомарный `WHERE status='running'`-guard сохранён). |
|
||
| TR-2 | **Забытый будущий путь возврата в `queued`** (6-й путь мимо инварианта) воскрешает класс «stale run-ownership». | Сред. | Сред. | Named-инвариант (adr-0052) + D4 startup/reap self-heal (идемпотентно лечит пропуск) + счётчик `impossible_queued` в `GET /queue` + reviewer-норматив «нарушение = ≥P1». |
|
||
| TR-3 | **Регресс reaper Tier-1** — неверная трактовка `pid IS NULL` как «dead → reap» реапнула бы легитимный старт. | Низ. | Выс. | Правка reaper НЕ требуется: `job_reaper.py:245` реапит лишь `pid is not None and not pid_alive(pid)`, `:257` сбрасывает streak при «no pid». Фикс **восстанавливает** предусловие. Покрыто TC-07. |
|
||
| TR-4 | **Гонка worker↔reaper↔monitor** на возврате в `queued` (двойная обработка строки). | Низ. | Сред. | Атомарные `status`-guard'ы (`reap_running_job ... WHERE status='running'`, rowcount) сохранены байт-в-байт (FR-1). Restart-safe (TC-04 повторный вызов → rowcount 0). |
|
||
| TR-5 | **Окно claim→spawn без pid** — job, чей `_spawn` упал до стампа pid и не был реквью́ен, висит `running` с `pid IS NULL` до Tier-3 backstop. | Низ. | Низ. | Штатный путь — немедленный реквью через `_drain_once`+D1 (TC-09). Worst-case ловит Tier-3 `reaper_max_running_s` (без изменений). Поведение не хуже текущего. |
|
||
| TR-6 | **Ошибка в горячем пути клейма роняет/клинит очередь всех проектов** (NFR-1). | Низ. | Выс. | Сброс — часть существующего `UPDATE` (без нового SELECT/сети, offline NFR-2); D4-диагностика изолирована (never-raise) от клейма. Полный `pytest tests/ -q` зелёный (AC-7). |
|
||
| TR-7 | **Невозможные строки на проде на момент апгрейда** (job 2286/2303) не санируются. | Низ. | Сред. | D4 авто-санация при первом старте `main.lifespan` (миграция не требуется); идемпотентно, выдерживает повторный рестарт (NFR-5). Покрыто TC-08. |
|
||
|
||
## Сводный вывод
|
||
|
||
Доминирующий класс — **точечная гигиена данных в горячем пути** при сохранении атомарных guard'ов и
|
||
4 маркированных инвариантов. Все риски — низкой вероятности; высокое влияние (TR-1/TR-3/TR-6) полностью
|
||
снимается тем, что (а) сброс ограничен переходом В `queued`/claim-до-`_spawn`, (б) reaper не правится и
|
||
его предусловие лишь восстанавливается, (в) изменения — внутри существующих UPDATE без сети.
|
||
**Эскалация не требуется** (`arch:major-change` — нет; возврат в анализ — нет): схема БД / `STAGE_TRANSITIONS`
|
||
/ `QG_CHECKS` / `check_*` / machine-verdict — байт-в-байт, решение реализуемо без нарушения принципов.
|
||
Остаточный риск для прод-конвейера (self-hosting) — **низкий**; обязательный регресс-тест (TC-01,
|
||
red→green) + анти-регресс здорового job'а (TC-10) фиксируют корректность.
|
||
</content>
|