Reshape the salvage of #114461 (@whyyagswhy) so the reasoning-field
rejection matcher lives once, in agent.error_classifier, and both the
auxiliary retry ladder and the main conversation loop consume it:
- UNSUPPORTED_PARAM_MARKERS is the single marker tuple (was duplicated
between auxiliary_client._is_unsupported_parameter_error and the new
classifier helper); is_reasoning_field_rejection() replaces
is_reasoning_disable_rejected() with the same token gate and a
symmetric "unsupported" window so both word orders match
("unsupported reasoning_effort", "reasoning_effort 'none' unsupported").
- Main loop: the reasoning_mandatory rung message no longer claims the
model "requires reasoning" (a chat-only relay does not); a second
reasoning-field rejection in the same turn is treated as spent and
takes the fallback chain instead of replaying the identical request
max_retries times (mirrors image_too_large's shrink_spent).
- Tests trimmed to invariants (one per surface) plus the spent path;
docs mention the reversed wording and the main-loop recovery.
Live against a stand-in replaying the Otari gateway's documented 400:
before, title generation failed and the thinking-only continuation died
with "Non-retryable client error"; after, both retry once without
reasoning_effort and complete.