12 KiB
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_*, строки ~392–442) + валидаторы |
Вариант A (часть флагов — и для B/C как декларация) |
src/main.py |
в lifespan — start()/stop() нового демона рядом с disk_watchdog.start()/stop() (строки ~113–120); в 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).