const MIGRATION_023: &str = r#"
ALTER TABLE downloads ADD COLUMN expires_at TEXT;
-- Reclaim scans filter on expiry among 'auto' rows; index both so the sweep
-- stays cheap as the cache tier grows.
CREATE INDEX IF NOT EXISTS idx_downloads_expiry
ON downloads(download_source, expires_at);
"#;Expand description
Give temporary downloads a life limit.
A cache entry is not a different kind of object from a download — it is a
download with a shorter life. Modelling it as one downloads row with an
expiry (rather than a parallel cache store) means there is a single storage
accounting, a single eviction path, and no way for a cache and a download
library to disagree about what is on disk.
expires_at is NULL for permanent rows, which is every row that exists
today: download_source defaults to 'user', and a user’s own download
never expires. Only 'auto' rows get a timestamp, and they are reclaimed by
whichever comes first — the expiry passing, or LRU eviction under space
pressure (DR-126).
TRACES: UR-071 | DR-127