setPrimary(id, 'face-ref') ran two sequential setPrimaryInTx writes on
the same row — one for face-ref, then a "silent twin" for avatar. But
primaryFor is a single-value column, so the second write clobbered
the first. Every fresh face upload ended up with primaryFor='avatar'
and useImageByPrimary('face-ref') returned null forever: wardrobe's
try-on banner stayed, TryOn was hard-blocked, picture's reference
picker showed nothing. Latent since M2.5 (e2b5ac38c).
Drop the silent twin. Keep face-ref as the single source of truth for
both the reference-face used by generators and the avatar that syncs
to Better-Auth. syncAvatarToAuth now reads face-ref first and falls
back to the legacy primaryFor='avatar' row (written by
migrateLegacyAvatarIfNeeded for pre-M2.5 users). deleteMeImage's
avatar-relevance check widens the same way.
Plus a one-shot repair bootstrap for users (incl. local dev sessions)
whose Dexie already carries silent-twin-victim rows. Runs on mount of
wardrobe/ListView AND profile/MeImagesView, guarded by a
per-user localStorage flag. Distinguishes legitimate legacy-avatar
rows (mediaId 'legacy-avatar:<uid>') from victims (any other mediaId)
and flips the newest victim back to primaryFor='face-ref', clearing
any older duplicates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>