architect(ET): auto-commit from architect run_id=436

This commit is contained in:
2026-06-09 10:52:01 +03:00
committed by stream
parent b478b38df5
commit 4597a8471d
6 changed files with 417 additions and 1 deletions

View File

@@ -92,6 +92,39 @@ Self-hosting зацикливался на `deploy-staging`: `scripts/staging_ch
Подробнее: [adr-0015](adr/adr-0015-task-deps-and-merge-serialization.md), детально — `docs/work-items/ORCH-026/06-adr/ADR-001-merge-serialization-and-task-deps.md`.
### Per-repo serial gate: пакетный автономный режим (ORCH-088 — design)
Эпик «1020 задач за ночь», Этап 1 (serial e2e). Закрывает **stale-анализ**: ветка задачи N+1
срезалась на входе в анализ (`start_pipeline._create_gitea_branch`) от `main`, ещё не содержащего код
предшественника N (физическое код-затирание уже закрыто ORCH-026; ORCH-088 — **логический** разрыв).
Новая задача репо не входит в `analysis` (не режет ветку, не запускает analyst), пока в том же репо
есть незавершённая задача (`stage != 'done'`) или репо заморожен. Аддитивно, под kill-switch, область
репо, never-raise, restart-safe; `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*`**без изменений**.
- **Gate-в-claim** (`db.claim_next_job`) — analyst-job (`jobs.agent='analyst'`) применимого репо не
выбирается, если `EXISTS` другая незавершённая задача репо (`t2.id != jobs.task_id` — rework-analyst
не блокирует себя) ИЛИ активна строка `repo_freeze`. По образцу `task_deps` `NOT EXISTS` (ORCH-026);
только локальная БД (offline hot-path, NFR-2). Job'ы уже активной задачи проходят свободно.
- **Отложенный срез ветки (анти-stale-base, AC-6):** для применимого репо `start_pipeline` создаёт
task-row + enqueue analyst, но **не** создаёт Gitea-ветку/docs; срез релоцируется на момент claim
analyst-job (launcher), когда `origin/main` уже содержит предшественника (`done` ⇔ SHA-в-main,
ORCH-071/073). `ensure_worktree` режет от свежего `origin/main` ⇒ AC-6 структурно. Идемпотентно
(`_create_gitea_branch` 409 = no-op).
- **Durable per-repo freeze** (новая аддитивная таблица `repo_freeze`, `cleared_at IS NULL` = активен) —
post-deploy `DEGRADED`/rollback (ORCH-021) → `set_repo_freeze` + Telegram-алерт; gate закрыт
безусловно до **ручного** снятия (`POST /serial-gate/unfreeze`). Деградировавшая задача уже `done`
(BR-7) ⇒ отдельный сигнал, независимый от `stage`.
- **Согласование NFR-1:** hot-claim тотальный сбой построения gate-фрагмента → **fail-open** (не
заклинить очередь всех проектов, AC-8); freeze в Python-слое (`is_repo_frozen`) → **fail-closed**
(безопасность прода, AC-9).
- Чистая логика — leaf `src/serial_gate.py` (never-raise). Флаги `serial_gate_enabled` (kill-switch),
`serial_gate_repos` (CSV; **пусто ⇒ все репо**, в отличие от self-hosting-only ORCH-35/43/58),
`serial_gate_freeze_enabled`. Наблюдаемость — аддитивный блок `serial_gate` в `GET /queue`
(per-repo `active_task` / `waiting` / `frozen`). Cross-repo параллелизм сохранён (FR-3); при
выключенном флаге — нулевая регрессия (enduro не затронут).
Подробнее: [adr-0017](adr/adr-0017-serial-gate.md), детально —
`docs/work-items/ORCH-088/06-adr/ADR-001-serial-gate.md`,
`docs/work-items/ORCH-088/08-data-requirements.md`.
### Исполняемый самодеплой стадии `deploy` (ORCH-36)
`deploy` перестаёт быть «бумажной»: для self-hosting (`is_self_hosting_repo`) стадия
РЕАЛЬНО деплоит прод (8500) через хост-хук `scripts/orchestrator-deploy-hook.sh`,