stat-index.json keyed entries by absolute path and never pruned, so a
moved/cloned corpus got 0% cache hits and the index grew unbounded. Keys
are now stored root-relative and re-anchored on load (mirroring the
manifest.json portability fix), and dead-file entries are pruned on flush.
save_semantic_cache also normalizes source_file to root-relative before
persisting so an absolute/backslash fragment can't poison later updates.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>