feat: retry queue carries attempts/classification across runs
RetryQueue now stores per-asset entries with classification, attempts,
firstFailedAt, lastFailedAt, and lastMessage. Merging across runs
preserves firstFailedAt and bumps attempts, so the UI can surface how
long an asset has been stuck.
Legacy `failedUUIDs: [String]` payloads decode transparently — existing
retry-queue files are upgraded on next write.
Also normalize PhotoKit's full-path identifiers (UUID/L0/001) to bare
UUIDs when appending to report.errors, so the retry-first partitioning
actually matches on the next run.