Artifact Storage Lifecycle¶

Test runs dashboard showing generated artifacts and execution history.
How Quorvex AI stores, archives, monitors, and deletes test run artifacts.
Why Artifact Storage Is Tiered¶
Generated tests produce useful but heavy artifacts: traces, screenshots, videos, reports, plan files, validation output, logs, and run metadata. Recent artifacts need fast local access for debugging. Older artifacts usually only need enough data for audit, trend analysis, or support.
Quorvex AI separates artifact metadata from artifact bytes. The database keeps run and artifact records; local storage and MinIO hold files according to retention age.
graph TD
A["Test run completes"] --> B["Artifacts written under runs/"]
B --> C["Hot tier: local files"]
C --> D["Archival job"]
D --> E["Warm tier: core files in MinIO"]
D --> F["Delete bulky local files"]
E --> G["Cold tier: delete artifact bytes"]
G --> H["Keep database metadata"] Storage Tiers¶
| Tier | Default age | Location | Contents |
|---|---|---|---|
| Hot | 0-30 days | Local runs/ directory | All artifacts |
| Warm | 30-90 days | MinIO artifacts bucket | Core artifacts such as plans, validation output, and reports |
| Cold | 90+ days | Database metadata only | Artifact files deleted |
The retention windows are controlled by ARCHIVE_HOT_DAYS, ARCHIVE_TOTAL_DAYS, and related archive settings.
Core Components¶
| Component | Source | Responsibility |
|---|---|---|
| Storage service | orchestrator/services/storage.py | MinIO connection, bucket operations, upload/download helpers |
| Archival service | orchestrator/services/archival.py | Retention policy, dry runs, archive jobs, local deletion |
| Health API | orchestrator/api/health.py | Database, local storage, MinIO, backup, Redis, alert checks |
| Artifact model | RunArtifact | Artifact path, storage type, size, archive time, expiry |
| Archive job model | ArchiveJob | One archival run and its processed/archive/delete counters |
| Storage stats model | StorageStats | Point-in-time storage health and size metrics |
Archival Flow¶
The archival service finds completed runs older than the hot retention window, classifies artifacts, and applies the retention policy:
- List local files for each eligible run.
- Preserve core artifacts by uploading them to MinIO.
- Create
RunArtifactrows for archived objects. - Delete bulky artifacts that are not preserved in warm storage.
- Find runs older than total retention and delete remaining artifact files.
- Record an
ArchiveJobsummary with counts, bytes, errors, and configuration.
Use dry-run mode before changing retention or running archival manually.
Health and Monitoring¶
GET /health/storage returns an aggregate health view:
| Area | Checks |
|---|---|
| Database | connectivity, size, run counts |
| MinIO | connection, bucket existence, object counts, object sizes |
| Local storage | runs/, specs, tests, disk usage |
| Backups | latest backup presence and age |
| Redis | queue backend health when configured |
| Alerts | derived warnings for unhealthy dependencies or large storage |
POST /health/storage/record records a StorageStats snapshot for trend analysis.
Operational Rules¶
- Treat local
runs/as hot operational storage, not permanent archival. - Keep MinIO credentials and buckets backed up with production configuration.
- Do not delete database run metadata when deleting old artifact bytes.
- Use
make archival-dry-runbefore changing retention windows. - Use
make storage-healthafter backup, restore, or MinIO configuration changes.