fix(tradein/scrapers): диагноз блока терялся при схлопывании, а в алерт шла непроверенная причина #3183

Merged
bot-backend merged 1 commit from fix/3178-honest-ban-kind into main 2026-08-28 17:15:03 +00:00
Collaborator

Суть

Прогоны 5140-5190 писали ban_kind=unknown, хотя причина во всех была одна и та же — она всё это время лежала в error_text:

5190 unknown  blocked=5  AvitoBlockedError: firewall/soft-block (browser-mode)  (4 из 5)
5120 platform blocked=5  AvitoBlockedError: firewall/soft-block (browser-mode)  (5 из 5)

Разница между unknown и platformодин нетипичный блок из пяти. Правило схлопывания требовало ровно одного вида, и явное большинство пропадало вместе с редким.

Что изменено

  • mark_backfill_finished принимает перепись диагнозов (Counter), кладёт её в counters["ban_kinds"] и выбирает диагноз через новую чистую функцию _dominant_ban_kind — строгое большинство (count > total / 2).
  • Замысел #2764 сохранён: пустая перепись и настоящая ничья (2 из 4) по-прежнему дают unknown. Диагноз не назначается там, где его не видели — ослаблено ровно то, что теряло большинство.
  • Убраны захардкоженные причины из ABORT-логов: "IP rate-limited" (Авито) и "QRATOR reputation likely burned for the session/proxy" (Домклик). Ни одна не проверялась кодом. Первая скрывала настоящий диагноз, лежавший рядом.
  • Авито пишет измеренную подпись отказа (_top_failure(failure_census)); Домклик — «причина не определена»: там failure_census нет вовсе, и подставлять вместо него выдуманное измерение было бы тем же дефектом.

Обратная совместимость

Counter(ban_kinds) одинаково принимает и старый Collection[str], и новый Mapping[str, int]. Для старого вызова каждый вид получает count=1, и 1 > n/2 истинно только при n=1 — то есть поведение в точности старое. Из четырёх вызывающих ban_kinds передаёт только Авито; остальные идут на дефолт.

Тесты

7 новых:

  • 4 из 5 platform + 1 infraplatform (регрессия этого тикета)
  • 2 + 2 → unknown (ничья честно неизвестна)
  • 5 из 5 → тот же вид
  • перепись доезжает в counters["ban_kinds"]
  • сквозной census с кратностями через реальный run_avito_detail_backfill
  • в ABORT-логе Авито нет строки IP rate-limited
  • в ABORT-логе Домклика нет QRATOR-литерала

ruff чист по всем шести файлам. Ревью пройдено, замечаний нет.

Test plan

  • Затронутые тесты зелёные локально
  • CI зелёный
  • После деплоя: у следующего забаненного прогона ban_kind не unknown, а в counters появилась перепись

Closes #3178

## Суть Прогоны 5140-5190 писали `ban_kind=unknown`, хотя причина во всех была одна и та же — она всё это время лежала в `error_text`: ``` 5190 unknown blocked=5 AvitoBlockedError: firewall/soft-block (browser-mode) (4 из 5) 5120 platform blocked=5 AvitoBlockedError: firewall/soft-block (browser-mode) (5 из 5) ``` Разница между `unknown` и `platform` — **один нетипичный блок из пяти**. Правило схлопывания требовало ровно одного вида, и явное большинство пропадало вместе с редким. ## Что изменено - `mark_backfill_finished` принимает перепись диагнозов (`Counter`), кладёт её в `counters["ban_kinds"]` и выбирает диагноз через новую чистую функцию `_dominant_ban_kind` — строгое большинство (`count > total / 2`). - Замысел #2764 сохранён: пустая перепись и настоящая ничья (2 из 4) по-прежнему дают `unknown`. Диагноз не назначается там, где его не видели — ослаблено ровно то, что теряло большинство. - Убраны захардкоженные причины из ABORT-логов: `"IP rate-limited"` (Авито) и `"QRATOR reputation likely burned for the session/proxy"` (Домклик). Ни одна не проверялась кодом. Первая скрывала настоящий диагноз, лежавший рядом. - Авито пишет измеренную подпись отказа (`_top_failure(failure_census)`); Домклик — «причина не определена»: там `failure_census` нет вовсе, и подставлять вместо него выдуманное измерение было бы тем же дефектом. ## Обратная совместимость `Counter(ban_kinds)` одинаково принимает и старый `Collection[str]`, и новый `Mapping[str, int]`. Для старого вызова каждый вид получает count=1, и `1 > n/2` истинно только при n=1 — то есть поведение в точности старое. Из четырёх вызывающих `ban_kinds` передаёт только Авито; остальные идут на дефолт. ## Тесты 7 новых: - 4 из 5 `platform` + 1 `infra` → `platform` (регрессия этого тикета) - 2 + 2 → `unknown` (ничья честно неизвестна) - 5 из 5 → тот же вид - перепись доезжает в `counters["ban_kinds"]` - сквозной census с кратностями через реальный `run_avito_detail_backfill` - в ABORT-логе Авито нет строки `IP rate-limited` - в ABORT-логе Домклика нет QRATOR-литерала `ruff` чист по всем шести файлам. Ревью пройдено, замечаний нет. ## Test plan - [x] Затронутые тесты зелёные локально - [x] CI зелёный - [ ] После деплоя: у следующего забаненного прогона `ban_kind` не `unknown`, а в `counters` появилась перепись Closes #3178
bot-backend added 1 commit 2026-08-28 17:09:12 +00:00
fix(tradein/scrapers): диагноз блока терялся при схлопывании, а в алерт шла непроверенная причина
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m47s
4adde9d7fb
Прогоны 5140-5190 писали ban_kind=unknown при том, что причина была
одна и та же во всех: AvitoBlockedError, firewall/soft-block (browser-mode).
Диагноз обнулял один нетипичный блок из пяти — правило схлопывания
требовало РОВНО одного вида, иначе unknown. Явное большинство (4 из 5)
пропадало вместе с редким.

Теперь mark_backfill_finished принимает перепись диагнозов, кладёт её
в counters["ban_kinds"] и выбирает по строгому большинству. Замысел
#2764 сохранён: пустая перепись и настоящая ничья по-прежнему дают
unknown — диагноз не назначается там, где его не видели.

Заодно убраны захардкоженные причины из ABORT-логов: "IP rate-limited"
у Авито и "QRATOR reputation likely burned" у Домклика. Ни одна из них
не проверялась кодом, и первая скрывала настоящий диагноз, лежавший
рядом в error_text прогона. Авито теперь пишет измеренную подпись
отказа, Домклик — "причина не определена": там нет failure_census,
и выдумывать измерение вместо него нечестно.

Refs #3178
bot-backend merged commit e685f96107 into main 2026-08-28 17:15:03 +00:00
bot-backend deleted branch fix/3178-honest-ban-kind 2026-08-28 17:15:03 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3183
No description provided.