Files
orchestrator/docs/work-items/ORCH-124/08-data-requirements.md
claude-bot de4f067655
All checks were successful
CI / test (push) Successful in 1m12s
architect(ET): auto-commit from architect run_id=764
2026-06-16 19:17:43 +03:00

55 lines
4.0 KiB
Markdown
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-124
stage: architecture
author_agent: architect
status: proposed
created_at: 2026-06-16
model_used: claude-opus-4-8
---
# 08 — Требования к данным: ORCH-124 — per-task park-сигнал serial-gate
Work Item: **ORCH-124** · Repo: **orchestrator** · Стадия: architecture
> When-applicable / информационный (гейтом не парсится).
## Изменения схемы БД
**Одна аддитивная нуллабельная колонка** на существующей таблице `tasks` (никаких новых таблиц):
| Таблица | Колонка | Тип / дефолт | Семантика |
|---------|---------|--------------|-----------|
| `tasks` | `paused_at` | `TEXT` (по умолчанию отсутствует → `NULL`) | `NULL` = не на паузе; ISO-таймстамп (`datetime('now')`) = задача поставлена оператором на паузу (park) |
Миграция — идемпотентный `_ensure_column(conn, "tasks", "paused_at", "TEXT")` в `init_db()`, ровно по
образцу `tasks.cancelled_at` / `tasks.cancel_requested_at` / `tasks.track` (`src/db.py:141-149`). На уже
мигрированной БД — no-op.
**Индекс не требуется.** Горячий SQL `build_claim_clause` сканирует `tasks t2` уже сегодня (по `repo`/`id`);
терм `AND t2.paused_at IS NULL` — дополнительный фильтр в существующем `EXISTS`-подзапросе, не новый план
доступа. Кардинальность `tasks` per-repo мала; добавление индекса — преждевременная оптимизация (принцип
минимума).
## Новые/изменённые сущности
- **`tasks.paused_at`** — единственное durable хранилище намерения паузы. Запись — `db.set_task_paused`
(`paused_at=datetime('now')`); сброс`db.clear_task_paused` (`paused_at=NULL`); чтение —
`db.is_task_paused` и SQL-предикат serial-gate. Все хелперы never-raise.
- **Инвариант оси:** `paused_at`**ортогональная** ось «пауза», независимая от оси «терминальность»
(`stage IN ('done','cancelled')`). serial-gate «активна» = `stage NOT IN ('done','cancelled') AND
paused_at IS NULL`. `task_deps`/`stages.py` колонку `paused_at` **не читают** (терминал не трогается,
NFR-4).
- **Существующие таблицы** (`jobs` / `job_deps` / `repo_freeze` / `agent_runs`) — без изменений.
## Совместимость данных / миграции
- **Аддитивно и идемпотентно:** `_ensure_column` — no-op на уже-мигрированной БД; новая колонка
дефолтит в `NULL` для всех существующих строк ⇒ все текущие задачи считаются «не на паузе» ⇒ поведение
до ORCH-124 сохраняется до первой явной операторской паузы.
- **Restart-safe / durable:** значение в БД переживает рестарт процесса/контейнера (BR-2, R-3).
- **Общая прод-БД (self-hosting):** колонка добавляется на общей БД; при дефолтном `serial_gate_pause_enabled`
и отсутствии паузнутых задач — нулевая регрессия для enduro (`paused_at` везде `NULL`).
- **Откат:** колонка инертна при `ORCH_SERIAL_GATE_PAUSE_ENABLED=false` (pause-терм опускается из SQL).
Колонку можно оставить (безвредна); деструктивный drop не требуется и не рекомендуется на прод-БД.
</content>