From 5a3063ecb34201baa8fcd3a1427cc445c0fbd4d0 Mon Sep 17 00:00:00 2001 From: justin Date: Mon, 22 Jun 2026 07:35:22 -0500 Subject: [PATCH] campaigns: MAIN_EXCLUDE_OPERATORS override + Gmail-only exclusion for post-DKIM re-send After the Jun 2026 no-DKIM incident (campaign mail went out unsigned -> junked/blocked, ~23% delivery), DKIM is fixed and we must re-send to the now-signed audience. The builder previously held Google AND Microsoft AND consumer-MX out until warmup day 30; that blocks the re-send of the Microsoft- hosted business domains that are most of the list. Add MAIN_EXCLUDE_OPERATORS (comma-separated mx_provider labels) to override WARMUP_EXCLUDE_OPERATORS. Set it to 'google' in the workers env so we send to everything EXCEPT Google's consumer inboxes (still recovering reputation), including Microsoft/Hotmail. Drives both the SQL exclude and the per-operator daily cap consistently. Unset => prior default; '' => exclude nobody. --- docker-compose.yml | 8 ++++++++ scripts/build_trucking_campaigns.py | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 91e7f97..f26532a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -125,6 +125,14 @@ services: - DMARC_IMAP_USER=${DMARC_IMAP_USER:-dmarc@performancewest.net} - DMARC_IMAP_PASS=${DMARC_IMAP_PASS} - FROM_EMAIL=Performance West + # Cold-campaign operator exclusion (scripts.build_trucking_campaigns). + # After the Jun 2026 no-DKIM incident (campaign mail went out unsigned and + # was junked/blocked) DKIM is fixed, so we re-send to the whole now-signed + # audience but still hold Google's consumer inboxes back while their + # reputation recovers. Empty list ("") => exclude nobody; unset => default + # warmup exclusion (Google+Microsoft+consumer MX). Microsoft/Hotmail and the + # long tail are intentionally INCLUDED here. + - MAIN_EXCLUDE_OPERATORS=google - CRYPTO_SWEEP_ADMIN_EMAIL=${ADMIN_EMAIL:-ops@performancewest.net} - USAC_USERNAME=${USAC_USERNAME} - USAC_PASSWORD=${USAC_PASSWORD} diff --git a/scripts/build_trucking_campaigns.py b/scripts/build_trucking_campaigns.py index a2c6bbb..a78c997 100644 --- a/scripts/build_trucking_campaigns.py +++ b/scripts/build_trucking_campaigns.py @@ -327,7 +327,21 @@ CONSUMER_MX_OPERATORS = ( ) # Everything held out of the warmup pool entirely until MAIN_BIG_MX_EXCLUDE_UNTIL_DAY, # then re-introduced gradually via mx_daily_caps(). -WARMUP_EXCLUDE_OPERATORS = BIG_MX_OPERATORS + CONSUMER_MX_OPERATORS +# +# MAIN_EXCLUDE_OPERATORS (comma-separated mx_provider labels) OVERRIDES this set +# when present. Use it to send to everything EXCEPT a specific operator without +# waiting for the calendar ramp -- e.g. after the Jun 2026 no-DKIM incident we +# re-send to the whole (now-signed) audience but still hold Google's consumer +# inboxes back while their reputation recovers: +# MAIN_EXCLUDE_OPERATORS="google" +# An empty string ("MAIN_EXCLUDE_OPERATORS=") means exclude NOBODY by operator. +_excl_override = os.getenv("MAIN_EXCLUDE_OPERATORS") +if _excl_override is None: + WARMUP_EXCLUDE_OPERATORS = BIG_MX_OPERATORS + CONSUMER_MX_OPERATORS +else: + WARMUP_EXCLUDE_OPERATORS = tuple( + o.strip().lower() for o in _excl_override.split(",") if o.strip() + ) MAIN_WARMUP_START_FILE = os.getenv("MTA_WARMUP_START_FILE", "/etc/postfix/pw-warmup-start") # How many days to EXCLUDE the big operators entirely. The Jun 13-14 block storm # means reputation is NOT yet established despite a high calendar day count, so we