Anthropic credential routing matches on the display name
The Anthropic provider resolves credentials with model.name(), which returns display_name when one is set rather than the served model id. The call sites are start_query, chat_completion_stream, and both advance and advance_for_rebuild in the stream (crates/jp_llm/src/provider/anthropic.rs, around lines 338, 435, 533, 611, 614).
That string reaches scope_covers in crates/jp_credentials/src/store.rs, which checks model.contains(family) case-sensitively. map_model sets display_name from the API listing for every listed model, so the string compared is something like "Claude Opus 4.5", and "Claude Opus 4.5".contains("opus") is false. A family-scoped cooldown (seven_day_opus) is therefore missed: a profile whose Opus window is spent is tried again instead of the chain falling through to the next credential. Account-wide cooldowns are unaffected, since they cover every model.
I have not confirmed the exact display-name string the API returns; the code path is unambiguous either way.
Fix
Pass model.id.name to credential resolution and fallback at those call sites, and keep name() for presentation and logging.
Test
Record a seven_day_opus cooldown on a profile, resolve a model whose details carry a display name such as "Claude Opus 4.5", and assert the profile is skipped.
Found while reviewing RFD 125.