check / check (push) Successful in 30s
Add src/library/content.ts: a ContentCache keyed by fileID under cacheDirectory (flat originals/ and thumbnails/, 0700/0600), fetching through the request pools (#45) and the streaming decrypt / atomic writer (#40) so present-means-complete. One shared pool set serves both this cache and the ML-data fetch. Photo.original and thumbnail return {path,bytes}, skipped when present; lib.thumbnails.ensure drives the thumbnail pool with priority, dedup, and abort. Integrity rests on the streaming decrypt (every chunk authenticated, renamed in only on TAG_FINAL) plus a non-empty check. The stored-hash / size compare is deferred (tracked in #68): the only in-repo hash fixture is a placeholder, and the stored size is the encrypted object size, not the decrypted length. Judgement call: three thumbnail priorities map onto two tiers. Model: opus-4-8