The 0.88-0.93 cosine between "cancel my subscription" and "reactivate my subscription" is a perfect example of why raw similarity is a blunt cache key: opposite intent, near-identical vector. Two-stage retrieval with a cross-encoder is what fixed the same false-hit problem for me. The staleness half is harder though: how are you invalidating a cached answer when the underlying source changes but the query text stays identical?