release / govulncheck (push) Successful in 16s
release / web (push) Successful in 1m25s
release / go (push) Successful in 1m43s
release / integration (push) Successful in 5m15s
release / android (push) Successful in 5m23s
release / Build signed APK (releases and dev) (push) Successful in 5m33s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 14s
release / Verify release artifacts (tag releases only) (push) Skipped
SimpleCache ran one LRU evictor at the rolling cap, so liked audio was dropped like anything else and the offline Liked pool shrank as other music played. TwoBucketCacheEvictor replaces it: - a span counts against Liked when its track is liked, else Recently played; a liked track that is also played is charged to Liked only; - each budget has its own cap (0 = unlimited) and drops its own least-recently-used audio first; - CacheBudgetSync feeds it the signed-in user's liked ids and the Storage caps, so a like, an unlike or a cap change applies at once; - nothing is evicted until the liked set is known, so startup never trims liked audio as Recently played. The decisions live in a Media3-free BucketLedger with unit tests. CacheConfig and PlayerModule, which only snapshotted the caps at launch, are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>