33c8e8274b
The per-call reasoning tier never reached the cache key, and the model fingerprint could not stand in for it: the fingerprint is computed once at assembly time, so two calls on the same client asking for low and max looked identical to it. Same messages, different tiers, one shared entry -- the verbatim replay of issue #4's five seeds all hitting the same response. Source-level tiers join the fingerprint under the same rule enable_thinking already follows (appended only when the source takes a position), and the filter that decides which sources enter the mark set is widened to match -- without that, a source configured with nothing but REASONING_EFFORT would never reach _fingerprint_mark at all. None (no opinion) and Effort.NONE (asked not to reason) stay distinct keys. Sources that opine on neither keep byte-identical keys and fingerprints, so nothing existing cold-starts.