Files
orchestrator/docs/work-items/ORCH-062/02-trz.md

12 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-062 analysis analyst ready-for-review 2026-06-09 claude-opus-4-8

02 — ТЗ (TRZ): ORCH-062 — INFRA: авто-prune docker build cache на mva154

Work Item: ORCH-062 · Repo: orchestrator · Стадия: analysis

ТЗ описывает требуемое поведение и точки изменения, выведенные из BRD и фактического кода. Выбор механизма реализации — за архитектором (06-adr). Запрещено комментировать ТЗ задним числом: если требование не годится — вернуть в Анализ.

1. Сводка изменения

Ввести автоматическое периодическое освобождение docker build cache на хосте mva154, чтобы build cache не мог дорасти до заполнения диска (корень инцидента 07.06.2026, ≈11 ГБ → диск 100% → падение CI+Gitea+конвейера всех проектов). Это комплемент к disk-watchdog (ORCH-063, «только сигнал»): watchdog предупреждает, pruner убирает. Требование — безопасно для self-hosting (только build cache, без рестарта прода, never-raise), обратимо (kill-switch), наблюдаемо (GET /queue) и конфигурируемо.

Развилка реализации (решает архитектор, фиксируется в 06-adr + 07-infra-requirements.md):

  • Вариант A — heartbeat-демон в приложении: новый leaf-модуль, фоновый threading.Thread(daemon=True), моделируемый 1:1 на src/disk_watchdog.py (start()/stop()/status(), threading.Event, per-tick never-raise, kill-switch, блок в GET /queue), который периодически вызывает docker builder prune через docker.sock.
  • Вариант B — host-уровень daemon.json builder.gc.defaultKeepStorage: конфигурация garbage-collection BuildKit на хосте (инфра-процедура Owner, без кода приложения).
  • Вариант C — host-cron docker builder prune -af --filter until=24h (инфра-процедура Owner).

ТЗ ниже формулирует требования инвариантно к выбору; колонка «применимость» в §2 помечает, что именно затрагивается при code-пути (Вариант A). Если архитектор выбирает чистый инфра-путь (B/C), изменения src/** не требуются, а предметом становятся 07-infra-requirements.md + INFRA.md + host-процедура (см. §7, §5 теста).

2. Задействованные модули / пути

Путь Действие Применимость
src/build_cache_pruner.py (новый leaf) создать: фоновый демон-pruner по образцу src/disk_watchdog.py Вариант A
src/config.py добавить флаги kill-switch/период/политика хранения (блок рядом с disk_monitor_*, строки ~392442) + валидаторы Вариант A (часть флагов — и для B/C как декларация)
src/main.py в lifespanstart()/stop() нового демона рядом с disk_watchdog.start()/stop() (строки ~113120); в GET /queue — блок наблюдаемости рядом с "disk_monitor": disk_watchdog.status() (строка ~186) Вариант A
.env.example задокументировать новые env-переменные (канон) A / B / C (декларация)
docs/operations/INFRA.md секция «авто-prune build cache» + переменные в карте env; уточнить, что освобождение build cache теперь автоматизировано (ORCH-063 говорил «ручная операция») A / B / C (обязательно)
docs/work-items/ORCH-062/06-adr/ADR-001-*.md решение по выбору механизма + параметрам (архитектор) A / B / C
docs/work-items/ORCH-062/07-infra-requirements.md host-prerequisites/процедура (docker.sock / daemon.json / cron) (архитектор) A / B / C
tests/test_build_cache_pruner.py (новый) unit/integration по 04-test-plan.yaml Вариант A
CHANGELOG.md запись в ## [Unreleased] A / B / C

Модуль-pruner должен быть leaf (как disk_watchdog.py, serial_gate.py, task_deps.py): без обратных зависимостей на stage_engine/stages/qg, чтобы не задевать конвейер.

3. Функциональные требования

FR-1 — периодическая авто-уборка build cache (BR-1)

Build cache очищается автоматически по расписанию/периодически без участия оператора. Для code-пути (A): фоновый поток с периодом prune_interval_s (порядка часов) вызывает уборку каждый тик. Для инфра-пути (B/C): garbage-collection BuildKit / cron обеспечивают эквивалентную периодичность. Привязка: BR-1.

FR-2 — политика удержания тёплого кэша (BR-2)

Уборка по умолчанию удаляет старый build cache, удерживая свежий. Ориентир из бизнес-запроса — возрастной фильтр --filter until=24h (для пути A: команда вида docker builder prune -f --filter until=<retention>), либо порог объёма builder.gc.defaultKeepStorage (для пути B). Параметры удержания конфигурируемы (см. §ниже). Флаг -a/--all применять только в сочетании с возрастным фильтром/политикой удержания, не как «снести весь кэш». Привязка: BR-2.

FR-3 — self-hosting-безопасность операции (BR-3, NFR-2)

  • Уборка затрагивает исключительно build cache — команда строго docker builder prune (BuildKit GC). Запрещены docker image prune, docker system prune, любое удаление образов запущенных сервисов и любая остановка/рестарт контейнеров.
  • Операция никогда не рестартит и не роняет прод-контейнер orchestrator (групповой риск self-hosting).
  • Для пути A: вызов docker — неблокирующий конвейер, с таймаутом; недоступность docker.sock → пропуск тика (never-raise).
  • Привязка: BR-3, NFR-1, NFR-2.

FR-4 — наблюдаемость (BR-4)

Состояние авто-prune доступно оператору. Для пути A — блок в GET /queue (как disk_monitor): enabled, interval_s, retention, last_run_ts, и (best-effort) результат последней уборки (освобождено байт / текущий объём build cache, если доступно из docker builder prune/du). Опционально — Telegram-сообщение при значимом освобождении (как recovery-сообщение watchdog'а). Для пути B/C — наблюдаемость через хост (docker system df), описанная в INFRA.md. Привязка: BR-4.

FR-5 — kill-switch + конфигурируемость (BR-5, BR-6, NFR-3)

  • *_enabled (kill-switch, дефолт безопасный): выключено → демон не стартует (путь A) / процедура неактивна; поведение 1:1 как до задачи (NFR-3).
  • Конфигурируемые: период (*_interval_s), политика удержания (возраст until и/или объём keep_storage), опц. порог запуска. Невалидные значения → лог-warning + дефолт (как валидаторы disk_monitor_interval_s/disk_monitor_threshold_pct в config.py).
  • Область раската — безопасная: операция привязана к хосту mva154; не вводит per-repo гейтов.
  • Привязка: BR-5, BR-6.

FR-6 — never-raise на всех уровнях (NFR-1)

Любая ошибка (subprocess-сбой, ненулевой rc, таймаут, недоступность docker.sock, parsing-ошибка вывода) логируется и проглатывается; фоновый цикл/процедура продолжает жить и не влияет на конвейер. Для пути A — try/except per-tick и per-команда, как _run/tick/_send в disk_watchdog.py. Привязка: NFR-1, NFR-5.

4. Изменения API

Внешних HTTP-эндпоинтов оркестратора (src/main.py) НЕ добавлять и не менять контрактно. Допустимо (путь A): GET /queue дополнить read-only блоком build_cache_pruner/аналогичным ключом (наблюдаемость, не источник истины) — по образцу блока disk_monitor. Внутренний контракт нового модуля (путь A) — start() / stop(timeout) / status() -> dict, 1:1 как DiskWatchdog.

5. Изменения схемы БД

Нет. Схема БД (src/db.py) не трогается. Учёт «времени последней уборки» — in-memory / best-effort (NFR-5), новой миграции не требуется (как анти-спам-состояние disk-watchdog).

6. Требования к новым/изменённым QG checks

Нет. QG_CHECKS / check_* / _parse_* / STAGE_TRANSITIONS / src/stage_engine.py не изменяются. Авто-prune — операционный фоновый демон/процедура (категория reconciler / job_reaper / disk_watchdog), не элемент реестра Quality Gate.

7. Совместимость / регресс · артефакты pipeline

  • Обратная совместимость / обратимость: kill-switch (FR-5) выключает фичу в 1:1-исходное состояние; никаких изменений поведения для enduro-trails и для конвейера (демон ортогонален).
  • Область раската: только хост mva154 / self-hosting инстанс; фича не вводит per-repo гейтов и не меняет рёбер конвейера.
  • Артефакты pipeline, которые должны быть созданы/обновлены:
    • 06-adr/ADR-001-*.md — выбор механизма (A/B/C) + параметры удержания/периода (архитектор).
    • 07-infra-requirements.md — host-процедура: доступ к docker.sock (A) / правка daemon.json + окно рестарта docker daemon (B) / cron-юнит (C) (архитектор).
    • 10-tech-risks.md — детализация R-1…R-4 из BRD (архитектор).
    • docs/operations/INFRA.md — секция авто-prune + карта env; снять формулировку ORCH-063 «освобождение места — ручная операция» в части build cache.
    • .env.example — новые переменные.
    • CHANGELOG.md## [Unreleased].
    • 12-review.md, 13-test-report.md, 14-deploy-log.md, 15-staging-log.md — по ходу конвейера.
    • tests/ — реализовать тесты из 04-test-plan.yaml (путь A).