Two fixes to the simulator's media handling, both surfaced by the cosmos clip swap.
1. Permanent cache-bust via content hash. New `GET /api/media-versions` returns a
short sha1 token per served file (clip bases + ring transitions + reverses),
cached by (mtime, size) so a re-bake is picked up without a restart. The client
fetches it at boot and appends `?v=<hash>` to every /media URL, so a clip
re-baked under the same path (e.g. a re-sourced cosmos base) gets a fresh URL
the browser can't serve stale — fixing the recurring stale-clip problem at the
root (supersedes the `cache: "reload"` belt-and-suspenders, which stays).
2. Fade the pool-landing swap. The baked ring transition zooms into the scale
PRIMARY, but the rotating pool picks a random member on landing — so a
non-primary pick hard-cut from the primary to the chosen clip (e.g. coast
birdrock -> surfgrass, the artifact the operator saw). On landing, when the pick
differs from the primary, mask the swap behind a short fade through the existing
#black overlay (CSS opacity transition); same-clip landings still do a plain
(re)load. General across all pooled scales.
271 passed, 2 skipped (+2: media-version content-hash + absent-file omission).
app.js syntax-checked; endpoint verified live (29 files; token matches a manual
sha1 of the bytes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>