Seven independent gates decide whether an automated outbound action may fire — and every one of them fails closed.
When software sends on its own — a message, a notification, an outreach touch — the expensive failure modes are the silent ones: a send that goes out at 3am local time, to someone who already opted out, twice, with no legal footer, because some check was unavailable and the code "defaulted to allowed". outbound-preflight-gates makes that impossible. A candidate action is run through seven gates, and any gate that cannot prove the action is safe returns a block or a defer — never a pass.
The seven gates:
| # | Gate | Checks | Failure |
|---|---|---|---|
| 1 | format |
sender + recipient addresses are well-formed | block |
| 2 | legal_footer |
the caller's required legal footer is in the body | block |
| 3 | send_window |
local time is inside the configured window | defer |
| 4 | do_not_contact |
the entity/recipient is not on the suppression list | block / defer |
| 5 | recipient_issue |
the recipient has no known delivery issue | block |
| 6 | cadence |
the minimum gap since the last action is honored | defer |
| 7 | idempotency |
the action is not a duplicate | block |
Each gate returns a structured GateResult — {passed, gate, reason, disposition} — and the engine returns the first failing one.
from datetime import date, datetime, timezone
from outbound_preflight_gates import PreflightEngine, PreflightPolicy, DoNotContactList
engine = PreflightEngine(
PreflightPolicy(
legal_name="Acme Holdings, Inc.",
timezone_name="America/New_York",
send_window_start_hour=6, send_window_end_hour=15, # 6am–3pm local
min_cadence_days=7,
),
dnc_check=DoNotContactList(suppressed_statuses={"existing_relationship"}).evaluate,
)
result = engine.preflight({
"sender_address": "sender@example.com",
"recipient_address": "recipient@example.org",
"body": "<p>…</p><hr/><p>Acme Holdings, Inc.<br/>123 Main St<br/>reply unsubscribe</p>",
"entity": {"status": "prospect"},
"last_action_date": None, # never contacted -> cadence passes
})
# -> GateResult(passed=True, ...) or the first failing gate's verdictThe hard-to-fake part is the fail-closed default on the three gates where the safe answer is not obvious. Naive preflight code treats missing evidence as permission: if the timezone lookup throws, assume we're in the window; if the do-not-contact service is down, assume the recipient is fine; if nobody hydrated the contact history, assume this is the first touch. Every one of those defaults sends a message that should not have gone out, and you only discover the hole during an incident. This library inverts all three:
- Send window — if the timezone library or the timezone name is unavailable, the action is treated as outside the window (defer). An infrastructure error can never read as "go".
- Do-not-contact — if no check is wired, or the check raises, the entity is treated as suppressed (defer). The recipient is never assumed contactable by default.
- Cadence — if the caller did not provide a last-action date (or explicitly assert they checked cross-channel history), the gate defers rather than assuming "never contacted before". You have to prove the gap, you don't get it for free.
That fail-closed posture is the whole point, and it is preserved byte-for-byte from a production send engine — including the address regex, the statutory-window comparisons, and the "evidence not hydrated" defer. The block/defer split is part of the value: a block means "fix the action", a defer means "retry later", and routing them differently is what keeps a queue moving without ever sending something unsafe. See docs/MOAT.md.
pip install -e .Zero runtime dependencies — pure standard library, Python 3.9+ (zoneinfo ships with 3.9). There is no network I/O: the do-not-contact check and the clock are injectable seams, so the whole engine runs in-process and offline.
PreflightEngine+PreflightPolicy— the configured seven-gate chokepoint; callpreflight(action)per candidate.gate_format,gate_legal_footer,gate_send_window,gate_do_not_contact,gate_recipient_issue,gate_cadence,gate_idempotency— the seven gates, each independently usable.GateResult— the frozen{passed, gate, reason, disposition}verdict;DISPOSITION_BLOCK/DISPOSITION_DEFER/DISPOSITION_PASS.DoNotContactList— a config-driven suppression evaluator (status / segment / flag rules + the universal recipient-issue layer).outbound_preflight_gates.channels— optional per-channel statutory gates: quiet-hours, a 24h customer-care window, a cadence cap, and per-platform daily anti-spam caps. Generic channel names (linkedin/whatsapp/sms/social); tunable window constants.
Full reference: docs/API.md. How to wire it into your system: docs/FORKING.md.
MIT — see LICENSE.
Powerweave Skunkworks is the AI R&D division of Powerweave Software Services — a rapid-innovation lab that turns real-world product feedback into working, reusable, open-source building blocks. Working in parallel to the main engineering backlog, a lean, cross-functional team of product and technology specialists (UX, data, software engineering, and AI) fast-tracks high-priority ideas into validated modules ready for full-scale build-out.
outbound-preflight-gates is one such building block — a de-domained, MIT-licensed, dependency-light component extracted from Powerweave's internal R&D and engineered to be forked into any SaaS or enterprise product.
- 🧪 Powerweave Skunkworks on GitHub — https://github.com/skunkworks-powerweave
- 🌐 Powerweave — https://powerweave.com
- 💼 Powerweave on LinkedIn — https://www.linkedin.com/company/powerweave
Powerweave Software Services Pvt. Ltd. is a digital-transformation company founded in 2001 and headquartered in Mumbai, India. With 25+ years of experience, 1,700+ professionals, and 350+ global customers, Powerweave builds platforms, processes, and teams across enterprise eCommerce, AI-powered procurement, Microsoft Dynamics ERP, business services, and sustainability — with a strong focus on cutting-edge AI automation that streamlines workflows, reduces manual errors, and accelerates decision-making. Powerweave is ISO 27001:2013 certified.
Explore Powerweave
- 🌐 Website — https://powerweave.com
- 💼 LinkedIn — https://www.linkedin.com/company/powerweave
- 𝕏 Twitter / X — https://twitter.com/powerweave
▶️ YouTube — https://www.youtube.com/channel/UCE1t_rg38z4n5BAg29PDZFA- 📘 Facebook — https://www.facebook.com/PowerweaveSoftwareSolutions/
- 🛒 Enterprise eCommerce — https://www.powerweave.com/solutions/enterprise-ecommerce/
- 📦 AI-Powered Procurement — https://www.powerweave.com/solutions/procurement/
- 🧮 Microsoft Dynamics ERP — https://www.powerweave.com/solutions/microsoft-dynamics-erp/
- 🌱 Snowkap — Sustainability — https://www.snowkap.com/
- 🎨 Powerweave Studio — https://www.powerweavestudio.com/
- 🧑💼 About Us & Leadership — https://www.powerweave.com/about-us/
- 🚀 Careers — https://www.powerweave.com/careers/
Keywords: preflight · outbound · compliance · fail-closed · rate-limit · cadence · do-not-contact · safety · Powerweave · Powerweave Skunkworks · AI R&D · open source · MIT · Python · forkable.