a028af4bc8
Экстрактор кода страницы ловил любые 11 цифр (7/8 + телефонная группировка) без проверки, что это настоящий российский номер — со страниц-агрегаторов пролезал мусор с несуществующими кодами (227/303/453/613/761) и подписывался «городской». PhoneValidityGate между CandidateBuilder и SourceAggregator: - слой 1 (бесплатно, всегда): реестр Россвязи (phone_ranges) — нет в реестре → выкидываем; - слой 2 (платно, за флагом autopodbor.phone_dadata_enabled, по умолчанию ВЫКЛ): DaDataValidityLayer перепроверяет прошедшие реестр номера, снимает qc 2/7, под дневным бюджетом + кэш вердикта; платим только за выживших (мусор отсекается ДО ДаДаты). - fail-open при пустом реестре / сбое БД (иначе внешний catch в SiteOpener съел бы все номера); - короткие/uncertain номера не трогаем (нельзя сверить). Закрыты ОБА пути шага 2: обычный (RealCompetitorAgent) и глубокий (SiteOpener). Миграций нет — реестр уже на проде (453k диапазонов). Тесты: PhoneValidityGateTest (7), DaDataValidityLayerTest (6), SiteOpenerValidityTest (1); весь набор автоподбора 519 зелёных, Pint + Larastan чисто. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>