Сайдкар с #3304 честно опознаёт бан-страницу и поднимает AvitoBlockedError, но
реакция на неё оставалась прежней: один bare-сброс контекста за прогон и дальше
попытки с ТОГО ЖЕ exit-IP, который площадка уже отвергла. Ротация была только
плановой, по счётчику попыток, и до конца прогона могла не наступить ни разу.
Теперь бан — самостоятельный триггер смены адреса, но с потолком, потому что
безоглядный сброс контекста на каждый блок даёт самоподдерживающийся каскад
(#3251/#3212): он выбрасывает пройденный QRATOR PoW, а адрес остаётся тем же.
Здесь этого не происходит — новый IP физически не несёт сожжённый PoW старого.
- avito_detail_backfill_rotate_on_ban_max=2, ..._min_gap=10 (карточек между
ротациями). max=0 возвращает прежнее поведение байт-в-байт.
- Бюджет тратится и на ОТКАЗАВШЕЙ ротации — иначе отказавший rotate_proxy
дёргался бы на каждом следующем бане до конца прогона.
- context_reset_used выставляется только по факту успеха: при тихом отказе
rotate_proxy (исчерпан лимит, нет rotate_url, сеть) сброса внутри не было, и
съесть им одноразовый bare-reset значило бы остаться и без адреса, и без сброса.
- Логи _rotate_current_proxy получили ярлык триггера: rotate-on-ban против
rotate-by-attempts, иначе разбор прод-логов по факту бана вводит в заблуждение.
Тесты: 5 на ban-ветку, включая падение ротации → откат на bare-reset.