diff --git a/CHANGELOG.md b/CHANGELOG.md index 82ea966..17cd6e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ - **Наблюдаемость (D5):** блок `serial_gate` в `GET /queue` дополнен ключом `paused` (список приостановленных незавершённых задач репо — НЕ показываются как `active_task`) и `reason` ожидания у каждого waiting-job с приоритетом `freeze` → `dependency` → `active-task` → `null`; существующие ключи снапшота (`active_task`/`waiting`/`frozen`/`frozen_reason`/`frozen_at`) — байт-в-байт (BC). - **Условность/откат (D6):** независимый под-флаг `serial_gate_pause_enabled` (env `ORCH_SERIAL_GATE_PAUSE_ENABLED`, дефолт `True`; зеркало `serial_gate_freeze_enabled`; область переиспользует `serial_gate_repos`, новый `*_repos` не вводится). Дефолт `True` — **истинный no-op** до явной операторской паузы (`paused_at` всюду NULL). `False` ⇒ pause-терм опущен из SQL, эндпоинты no-op, serial-gate **байт-в-байт ORCH-088/090** (осознанный rollback-режим). Глубже — `serial_gate_enabled=false`. - **Покрытие:** `tests/test_orch124_serial_gate_pause.py` (TC-01 обязательный регресс инцидента ORCH-116/ORCH-123 — красный до фикса, зелёный после; TC-02…TC-15: анти-регресс ORCH-088, durable/restart, resume, сохранность freeze/dependency, снапшот-reason, анти-дрейф 3 точек, offline hot-path, never-raise/fail-OPEN, kill-switch-нейтральность, структурный анти-регресс реестров/схем). - - **Доки:** обновлены `docs/architecture/README.md` (раздел serial-gate + ось «пауза без блокировки») и `docs/architecture/internals.md` (ось «пауза» ⊥ оси «терминальность»); сквозной ADR `adr-0051`. + - **Доки:** обновлены `docs/architecture/README.md` (раздел serial-gate + ось «пауза без блокировки») и `docs/architecture/internals.md` (ось «пауза» ⊥ оси «терминальность»); сквозной ADR `adr-0051`. **Витрина системы `docs/overview/` (ORCH-011, синхронно в том же PR):** `tech-pipeline.md` (исключение FIFO «пауза без блокировки» рядом с freeze), `tech-data-model.md` (durable-сигнал `tasks.paused_at`), `tech-observability.md` (`paused`/`reason` в блоке `serial_gate` `GET /queue` + эндпоинты `pause|resume`). Зачищены протёкшие хвостовые теги tool-call (``/``) в 4 golden-source доках этого PR (`06-adr/ADR-001`, `adr-0051`, `08-data-requirements.md`, `10-tech-risks.md`). - **Тест-гигиена (development-стадия, латентный регресс ORCH-123):** изолирован `settings.repos_dir` в фикстуре `tests/test_orch123_staging_runner_exec.py` (зеркально уже имевшейся изоляции `worktrees_dir`). `check_staging_status` при отсутствии фиче-worktree фолбэчит на `/` (и его `origin/main`); после мержа ORCH-123 реальный `/repos/orchestrator/docs/work-items/ORCH-123/15-staging-log.md` (вердикт SUCCESS) появился на диске и делал предполагавшийся-КРАСНЫМ staging-гейт в `test_r2_held_deploy_staging_not_rolled_back` зелёным при полном прогоне `pytest tests/` (order-dependent: тест проходил в одиночку, падал в сьюте). Инвариант ORCH-123 R-2 («held `deploy-staging` не откатывается на `development`», adr-0049/ADR-001 D4) **сохранён и усилен** — изоляция лишь восстанавливает заявленную предпосылку теста «15-staging-log.md отсутствует ⇒ гейт красный». `src/**`/`STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*` не тронуты (правка только теста). - **Детерминированный test-раннер вместо LLM-тестера на `testing`** (ORCH-116, `feat`): второй реализованный срез determinization-roadmap (ORCH-118 A5, `needs-hybrid-fallback`) — на стадии `testing` для self-hosting `orchestrator` **LLM-агент `tester` заменён детерминированным кодом** (`src/test_runner.py`). PASS/FAIL-ядро агента было деривируемым (регресс `pytest` + read-only smoke → `result:`); каждый прогон жёг токены/время opus-агента (~60–150k / 5–20 мин) и встраивал недетерминизм LLM в точку ветвления `testing → deploy-staging` / `testing → development`. **Инвариант (NFR-1):** это замена *продюсера* артефакта, **не** гейта — контракт `13-test-report.md`, гейт `check_tests_passed`/`_parse_tests_verdict`, `STAGE_TRANSITIONS`, machine-verdict `result:` (+ legacy `verdict:`/`status:`), схема БД — **байт-в-байт не тронуты**. Аддитивно, под kill-switch, never-raise, fail-closed, скоуп self-hosting, гибрид (LLM строго off-control-path). Эталон — `src/staging_runner.py` (ORCH-115). ADR: `docs/work-items/ORCH-116/06-adr/ADR-001-deterministic-test-runner.md`, сквозной `docs/architecture/adr/adr-0050-deterministic-test-runner.md`. - **Перехват в `launch_job` до `_spawn` (D1):** `if job.agent=="tester" and test_runner.should_intercept(job)` → `_run_test_runner_job` (зеркало `_run_staging_runner_job`, прецедент `deploy-finalizer`/`post-deploy-monitor`/`staging-runner` `launcher.py:397/402/405`): синхронно ведёт `jobs`-строку через `mark_job`, возвращает `None` (нет `agent_runs`, нет токенов). Дискриминатор — роль `tester` **И** стадия задачи `testing` (defense-in-depth: `tester` — единственный агент входа в `testing`, коллизии стадий нет, в отличие от общей роли `deployer`) **И** `applies(repo)`; `should_intercept` never-raise → `False` → штатный `_spawn` (fail-safe к LLM-пути). diff --git a/docs/architecture/adr/adr-0051-serial-gate-pause-without-blocking.md b/docs/architecture/adr/adr-0051-serial-gate-pause-without-blocking.md index 0988e09..8ae73f1 100644 --- a/docs/architecture/adr/adr-0051-serial-gate-pause-without-blocking.md +++ b/docs/architecture/adr/adr-0051-serial-gate-pause-without-blocking.md @@ -108,4 +108,3 @@ rebase-машинерии нет: отложенный срез ветки (ORCH - Данные: `docs/work-items/ORCH-124/08-data-requirements.md` - Связанные: adr-0017 (serial-gate ORCH-088), adr-0026 (терминал `{done,cancelled}` ORCH-090), adr-0015 (task-deps), adr-0027 (merge-актор rebase/retry ORCH-093), adr-0042 (merge-gate re-test ORCH-110) - diff --git a/docs/overview/tech-data-model.md b/docs/overview/tech-data-model.md index bf2cdf1..5710dd3 100644 --- a/docs/overview/tech-data-model.md +++ b/docs/overview/tech-data-model.md @@ -19,7 +19,8 @@ Project ──1:N──► Work-Item / Task ──1:N──► Job ──1:N─ ### Work-Item / Task — задача конвейера Строка таблицы `tasks`: текущая **стадия** (`stage`), **маршрут** (`track`: полный или -багфикс), рабочая **ветка**, счётчики откатов, отметки отмены. Натуральные ключи — ID задачи +багфикс), рабочая **ветка**, счётчики откатов, отметки отмены и **паузы** (`paused_at` — +durable-сигнал «пропустить меня в serial gate», не терминальный). Натуральные ключи — ID задачи в Plane и человекочитаемый номер (`ORCH-NNN`). На каждой стадии задача накапливает **артефакты** — номерные документы в `docs/work-items//` (от бизнес-запроса до deploy-лога; манифест — [PIPELINE_DOCS](../_standards/PIPELINE_DOCS.md)). diff --git a/docs/overview/tech-observability.md b/docs/overview/tech-observability.md index 0a10794..e9e428f 100644 --- a/docs/overview/tech-observability.md +++ b/docs/overview/tech-observability.md @@ -20,9 +20,10 @@ ## Служебные страницы платформы - **`GET /queue`** — человекочитаемый снимок всего конвейера: очередь и job'ы, состояние - serial gate и заморозок, авто-лейблы, багфикс-трек, coverage, журнал уроков, владение - переходами (`transition_lease`), фоновые демоны. Первая точка диагностики «что сейчас - происходит». + serial gate (заморозки, паузы задач, причина ожидания успешника), авто-лейблы, багфикс-трек, + coverage, журнал уроков, владение переходами (`transition_lease`), фоновые демоны. Первая + точка диагностики «что сейчас происходит». Паузу/возобновление задачи в serial gate оператор + включает явными эндпоинтами `POST /serial-gate/pause|resume`. - **`GET /metrics`** — машинный контракт для внешнего наблюдателя (версионированная схема): health, возраст последних событий, счётчики сбоев. - **`GET /health`** — живость процесса. diff --git a/docs/overview/tech-pipeline.md b/docs/overview/tech-pipeline.md index b7c678c..397891d 100644 --- a/docs/overview/tech-pipeline.md +++ b/docs/overview/tech-pipeline.md @@ -107,6 +107,13 @@ created → analysis → architecture → development → review → testing → прода после выкладки замораживает репозиторий (freeze) до ручного разбора — следующие задачи ждут. +У FIFO-порядка есть управляемое исключение — **пауза без блокировки**: оператор может явно +поставить более раннюю задачу на паузу (durable-сигнал `tasks.paused_at`), и тогда срочный +успешник её обгоняет, не дожидаясь завершения. Пауза — отдельная ось: она ≠ отмена (задача не +терминальна и возвращается в гейт обратной командой) и **не** обходит ни freeze, ни объявленные +зависимости. Свежесть базы возобновлённой задачи гарантируют те же механизмы (отложенный срез +ветки + ребейз на слиянии), что и для обычного FIFO. + ## Отмена: STOP → `cancelled` Перевод задачи в статус **STOP** останавливает агента, снимает job'ы с очереди, удаляет diff --git a/docs/work-items/ORCH-124/06-adr/ADR-001-serial-gate-pause-without-blocking.md b/docs/work-items/ORCH-124/06-adr/ADR-001-serial-gate-pause-without-blocking.md index 4b757b1..4d05d15 100644 --- a/docs/work-items/ORCH-124/06-adr/ADR-001-serial-gate-pause-without-blocking.md +++ b/docs/work-items/ORCH-124/06-adr/ADR-001-serial-gate-pause-without-blocking.md @@ -296,5 +296,3 @@ deferred-branch / merge-gate / схемы существующих таблиц - Базовые решения: adr-0017 (serial-gate ORCH-088), adr-0026 (терминал `{done,cancelled}` ORCH-090), adr-0015 (task-deps ORCH-026), adr-0027 (merge-актор rebase/retry ORCH-093), adr-0042 (merge-gate re-test ORCH-110) - - diff --git a/docs/work-items/ORCH-124/08-data-requirements.md b/docs/work-items/ORCH-124/08-data-requirements.md index d6d9fee..2dacc4d 100644 --- a/docs/work-items/ORCH-124/08-data-requirements.md +++ b/docs/work-items/ORCH-124/08-data-requirements.md @@ -51,4 +51,3 @@ Work Item: **ORCH-124** · Repo: **orchestrator** · Стадия: architecture и отсутствии паузнутых задач — нулевая регрессия для enduro (`paused_at` везде `NULL`). - **Откат:** колонка инертна при `ORCH_SERIAL_GATE_PAUSE_ENABLED=false` (pause-терм опускается из SQL). Колонку можно оставить (безвредна); деструктивный drop не требуется и не рекомендуется на прод-БД. - diff --git a/docs/work-items/ORCH-124/10-tech-risks.md b/docs/work-items/ORCH-124/10-tech-risks.md index 19d83f6..c3a130c 100644 --- a/docs/work-items/ORCH-124/10-tech-risks.md +++ b/docs/work-items/ORCH-124/10-tech-risks.md @@ -38,4 +38,3 @@ ORCH-088/090. Изменение **аддитивно, под независим правка планировщика внутри существующего компонента serial-gate). Возврат в анализ не требуется (ТЗ удовлетворяется без нарушения принципов архитектуры). Остаточный риск для прод-конвейера (self-hosting) — **низкий**: дефолтное поведение — истинный no-op до явной операторской паузы; полный откат — один env-флаг. -