ADR 0026: политики последних N, квоты и диагностика
Статус: принято. Дата: 2026-09-25.
Нужны гибкие правила автоочистки, предсказуемые квоты при параллельном приёме больших файлов и безопасный журнал проблем. Автоматизация не должна обходить текущую авторизацию или существующие references/history pins.
Решение: чистая доменная модель StoragePolicy; application-сценарий RepositoryStorage с узким портом; PostgreSQL адаптер ранжирует зарегистрированные UPack-билды и повторно применяет безопасное логическое удаление под существующим repository gate. Группировка выбирается явно: пакет/канал, пакет или репозиторий. Билд сохраняется при попадании хотя бы в одну корзину последних N. Порции и фоновые циклы ограничены. Настройки имеют CAS-ревизию; расписание и authorizing key ID сохраняются в БД. Отзыв ключа останавливает автоматические действия. Секрет в расписании отсутствует.
Квота проверяется при резервировании upload под той же глобальной reservation-блокировкой, которую получает изменение лимита. Не reclaimed записи, включая отменённые и удалённые, учитываются до физического GC. UI и API различают published, pending и retired, чтобы не обещать уже освобождённый диск.
Не добавляем второй scheduler-процесс к single-writer профилю. Минутный цикл writer управляет ограниченным числом due-политик и мониторингом квот; reader обслуживает только чтение. PostgreSQL таймауты ограничивают транзакции; у автоматических ошибок есть задержка повторения и событие. Масштабирование и HA остаются отдельными deployment-решениями.
Диагностика использует JSON stdout с allowlist полей и bounded PostgreSQL-журналом для UI/API. Диагностический backpressure не накапливает память и не должен блокировать файловые потоки. Возможны явные пропуски best-effort логов; неизменяемый artifact deletion audit отделён и фиксируется атомарно с tombstone. Email/webhooks не реализуются неявно.
UPack custom metadata разрешена спецификацией; подготовка корневого upack.json выполняется до упаковки. Опубликованный blob остаётся неизменяемым. Online GC не включается: для него нужны reader leases и самостоятельная приёмка сетевых/процессных отказов. Подробный контракт и эксплуатационные ограничения: STORAGE_POLICIES.