diff --git a/scripts/build_trucking_campaigns.py b/scripts/build_trucking_campaigns.py index fd74906..2ac7084 100644 --- a/scripts/build_trucking_campaigns.py +++ b/scripts/build_trucking_campaigns.py @@ -612,11 +612,16 @@ CATCH_ALL_RESULTS = ["catch_all_domain", "catch_all_detected"] # lands on Google/Microsoft is still held out by big_mx_exclude until day 30. CATCH_ALL_MIN_WARMUP_DAY = int(os.getenv("CAMPAIGN_CATCH_ALL_MIN_DAY", "21")) # Recent-window bounce-rate ceiling (percent). At/above this, catch-all stays OFF -# and an already-on rollout auto-reverts. A SHORT window is deliberate: a -# historical disaster (e.g. the Jun-16 ~45% 7-day rate) must NOT block the -# rollout forever, and a fresh spike must trip it fast. +# and an already-on rollout auto-reverts. The window is kept short enough that a +# historical disaster (e.g. the Jun-16 ~45% 7-day rate) does NOT block the +# rollout forever, but long enough that a single bad daily batch cannot whipsaw +# the whole program: a 2-day window let one 10.75% day (Jun-24, 465 sent) flip +# catch-all OFF and starve volume to ~200/day, which then could not reach the +# min-sent sample to ever re-enable -- a self-reinforcing trap. A 5-day window +# smooths that same period to a true ~3.8% (7,995 sent / 303 bounced) and keeps +# steady ~3k/day flowing, while still tripping fast on a sustained real spike. CATCH_ALL_MAX_BOUNCE_PCT = float(os.getenv("CAMPAIGN_CATCH_ALL_MAX_BOUNCE_PCT", "8")) -CATCH_ALL_BOUNCE_WINDOW_DAYS = int(os.getenv("CAMPAIGN_CATCH_ALL_BOUNCE_WINDOW_DAYS", "2")) +CATCH_ALL_BOUNCE_WINDOW_DAYS = int(os.getenv("CAMPAIGN_CATCH_ALL_BOUNCE_WINDOW_DAYS", "5")) # Minimum sent volume required in the window before the rate is trusted (else a # tiny sample like 9 sent / 1 bounce = 11% would wrongly gate the decision). CATCH_ALL_BOUNCE_MIN_SENT = int(os.getenv("CAMPAIGN_CATCH_ALL_BOUNCE_MIN_SENT", "300"))