9cd0338688
The sole-credential cooldown sized the bench from the raw HTTP status, but 403 is overloaded: error_classifier maps OpenRouter's "key limit exceeded" and xAI's spending-limit block to FailoverReason.billing, while an edge throttle with the same status is transient. Only 402 was excluded from the short cooldown, so a spent account on a single key retried every 60 seconds and re-failed forever. Thread the classified reason from recover_with_credential_pool through mark_exhausted_and_rotate to _exhausted_ttl. Billing keeps the full bench regardless of status; everything else transient still recovers in 60s. The verdict is stored on the entry (_EXTRA_KEYS, so it persists to auth.json) — without that a restart would re-read a bare 403 and downgrade the bench. Tests: sole billing-403 stays benched, survives reload, unclassified 403 still recovers; call-site coverage that the reason actually reaches the pool. Three existing kwargs assertions updated for the new argument.