ab1c47ebcc
asdict keeps the enum and json.dumps writes it as a string because StrEnum is a str subclass, but nothing turns it back on the way in, so a cache hit returned a plain str where the annotation promised an enum. Verified end to end rather than assumed from the subclass relation. A value outside the domain now raises inside the existing guard and the call falls back to source, which is the right direction for a poisoned or stale cache entry. Entries written before this column existed still replay: the guard checks for the key first, and a test pins that, since turning it into an unconditional conversion would quietly turn every pre-upgrade entry into a permanent miss.