Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1110 lines
44 KiB
Python
1110 lines
44 KiB
Python
"""
|
|
Generate the FCC Robocall Mitigation Database (RMD) Certification Letter.
|
|
|
|
Produces a formal certification letter for filing with the FCC's Robocall
|
|
Mitigation Database pursuant to 47 CFR § 64.6305, incorporating requirements
|
|
from the January 2024 and January 2026 amendments.
|
|
|
|
Provider classifications per FCC rules:
|
|
(a) Voice Service Provider — 47 CFR § 64.6305(d)
|
|
(b) Gateway Provider — 47 CFR § 64.6305(e)
|
|
(c) Non-Gateway Intermediate Provider — 47 CFR § 64.6305(f)
|
|
|
|
Usage:
|
|
from scripts.document_gen.templates.rmd_letter_generator import generate_rmd_letter
|
|
path = generate_rmd_letter(
|
|
entity_name="Falcon Broadband LLC",
|
|
frn="0027160886",
|
|
provider_classification="voice_service_provider",
|
|
stir_shaken_status="complete_implementation",
|
|
...
|
|
)
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
LOG = logging.getLogger("document_gen.rmd_letter")
|
|
|
|
try:
|
|
from docx import Document
|
|
from docx.shared import Pt, Inches, RGBColor, Emu
|
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
from docx.oxml.ns import qn
|
|
from docx.oxml import OxmlElement
|
|
except ImportError:
|
|
LOG.warning("python-docx not installed — RMD letter generation unavailable")
|
|
Document = None
|
|
|
|
# ── Constants ────────────────────────────────────────────────────────────
|
|
NAVY = RGBColor(0x1A, 0x27, 0x44) if RGBColor else None
|
|
BLACK = RGBColor(0x00, 0x00, 0x00) if RGBColor else None
|
|
GRAY = RGBColor(0x66, 0x66, 0x66) if RGBColor else None
|
|
|
|
BODY_SIZE = 10
|
|
HEADING_SIZE = 12
|
|
TITLE_SIZE = 14
|
|
SPACING_AFTER = Pt(6) if Pt else None
|
|
|
|
# FCC provider classification labels per 47 CFR § 64.6305
|
|
_CLASSIFICATION_LABELS = {
|
|
"voice_service_provider": "Voice Service Provider (47 CFR § 64.6305(d))",
|
|
"gateway_provider": "Gateway Provider (47 CFR § 64.6305(e))",
|
|
"intermediate_provider": "Non-Gateway Intermediate Provider (47 CFR § 64.6305(f))",
|
|
}
|
|
|
|
# Carrier category labels (informational — type of underlying authorization)
|
|
_CATEGORY_LABELS = {
|
|
"interconnected_voip": "Interconnected VoIP Provider",
|
|
"non_interconnected_voip": "Non-Interconnected VoIP Provider",
|
|
"clec": "Competitive Local Exchange Carrier (CLEC)",
|
|
"ixc": "Interexchange Carrier (IXC)",
|
|
"cmrs": "Commercial Mobile Radio Service (CMRS) Provider",
|
|
"other": "Telecommunications Service Provider",
|
|
}
|
|
|
|
# Required FCC traceback language per 64.6305(d)(2)(iii)/(e)(2)(iii)/(f)(2)(iii)
|
|
_TRACEBACK_COMMITMENT = (
|
|
"{entity_name} commits to respond fully and completely to all traceback "
|
|
"requests from the Commission, civil and criminal law enforcement, and "
|
|
"the industry traceback consortium, and to do so within 24 hours of "
|
|
"receiving such a request."
|
|
)
|
|
|
|
# Required 47 CFR § 1.16 declaration language
|
|
_PERJURY_DECLARATION = (
|
|
"I declare under penalty of perjury under the laws of the United States "
|
|
"of America that the foregoing is true and correct."
|
|
)
|
|
|
|
|
|
# ── Document formatting helpers ──────────────────────────────────────────
|
|
|
|
def _set_paragraph_spacing(paragraph, after_pt=6, before_pt=0):
|
|
"""Set paragraph spacing in points."""
|
|
pPr = paragraph._p.get_or_add_pPr()
|
|
spacing = OxmlElement("w:spacing")
|
|
spacing.set(qn("w:after"), str(int(after_pt * 20)))
|
|
if before_pt:
|
|
spacing.set(qn("w:before"), str(int(before_pt * 20)))
|
|
pPr.append(spacing)
|
|
|
|
|
|
def _add_horizontal_rule(doc):
|
|
"""Add a horizontal rule (bottom border on an empty paragraph)."""
|
|
p = doc.add_paragraph()
|
|
pPr = p._p.get_or_add_pPr()
|
|
pBdr = OxmlElement("w:pBdr")
|
|
bottom = OxmlElement("w:bottom")
|
|
bottom.set(qn("w:val"), "single")
|
|
bottom.set(qn("w:sz"), "6")
|
|
bottom.set(qn("w:space"), "1")
|
|
bottom.set(qn("w:color"), "1A2744")
|
|
pBdr.append(bottom)
|
|
pPr.append(pBdr)
|
|
return p
|
|
|
|
|
|
def _add_page_number_footer(doc):
|
|
"""Add centered page numbers to the document footer."""
|
|
for section in doc.sections:
|
|
footer = section.footer
|
|
footer.is_linked_to_previous = False
|
|
p = footer.paragraphs[0] if footer.paragraphs else footer.add_paragraph()
|
|
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
|
# Page number field
|
|
run = p.add_run()
|
|
run.font.size = Pt(8)
|
|
run.font.color.rgb = GRAY
|
|
|
|
fld_char_begin = OxmlElement("w:fldChar")
|
|
fld_char_begin.set(qn("w:fldCharType"), "begin")
|
|
run._r.append(fld_char_begin)
|
|
|
|
instr_text = OxmlElement("w:instrText")
|
|
instr_text.set(qn("xml:space"), "preserve")
|
|
instr_text.text = " PAGE "
|
|
run._r.append(instr_text)
|
|
|
|
fld_char_end = OxmlElement("w:fldChar")
|
|
fld_char_end.set(qn("w:fldCharType"), "end")
|
|
run._r.append(fld_char_end)
|
|
|
|
|
|
class _DocBuilder:
|
|
"""Helper for building the letter with consistent formatting."""
|
|
|
|
def __init__(self, doc):
|
|
self.doc = doc
|
|
|
|
def title(self, text: str):
|
|
p = self.doc.add_paragraph()
|
|
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
run = p.add_run(text)
|
|
run.font.size = Pt(TITLE_SIZE)
|
|
run.font.color.rgb = NAVY
|
|
run.bold = True
|
|
_set_paragraph_spacing(p, after_pt=12)
|
|
return p
|
|
|
|
def section_heading(self, text: str):
|
|
p = self.doc.add_paragraph()
|
|
run = p.add_run(text)
|
|
run.font.size = Pt(HEADING_SIZE)
|
|
run.font.color.rgb = NAVY
|
|
run.bold = True
|
|
_set_paragraph_spacing(p, after_pt=6, before_pt=12)
|
|
return p
|
|
|
|
def body(self, text: str, bold: bool = False, italic: bool = False,
|
|
alignment=WD_ALIGN_PARAGRAPH.LEFT):
|
|
p = self.doc.add_paragraph()
|
|
p.alignment = alignment
|
|
run = p.add_run(text)
|
|
run.font.size = Pt(BODY_SIZE)
|
|
run.font.color.rgb = BLACK
|
|
run.bold = bold
|
|
run.italic = italic
|
|
_set_paragraph_spacing(p, after_pt=6)
|
|
return p
|
|
|
|
def bullet(self, text: str, level: int = 0):
|
|
"""Add a bullet-pointed paragraph with indentation."""
|
|
p = self.doc.add_paragraph()
|
|
indent_inches = 0.5 + (level * 0.25)
|
|
p.paragraph_format.left_indent = Inches(indent_inches)
|
|
p.paragraph_format.first_line_indent = Inches(-0.2)
|
|
bullet_char = "\u2022" if level == 0 else "\u25E6"
|
|
run = p.add_run(f"{bullet_char} {text}")
|
|
run.font.size = Pt(BODY_SIZE)
|
|
run.font.color.rgb = BLACK
|
|
_set_paragraph_spacing(p, after_pt=3)
|
|
return p
|
|
|
|
def spacer(self):
|
|
p = self.doc.add_paragraph()
|
|
_set_paragraph_spacing(p, after_pt=0)
|
|
return p
|
|
|
|
def field_value(self, label: str, value: str):
|
|
"""Add a label: value line as a bullet."""
|
|
self.bullet(f"{label}: {value}")
|
|
|
|
def horizontal_rule(self):
|
|
_add_horizontal_rule(self.doc)
|
|
|
|
|
|
# ── Main generator ───────────────────────────────────────────────────────
|
|
|
|
def generate_rmd_letter(
|
|
# Entity identity
|
|
entity_name: str,
|
|
dba_name: str = "",
|
|
frn: str = "",
|
|
ocn: str = "",
|
|
rmd_number: str = "",
|
|
filer_id_499: str = "",
|
|
former_names: list[str] | None = None,
|
|
is_foreign_provider: bool = False,
|
|
# Address
|
|
address_street: str = "",
|
|
address_city: str = "",
|
|
address_state: str = "",
|
|
address_zip: str = "",
|
|
# Contact
|
|
contact_name: str = "",
|
|
contact_title: str = "",
|
|
contact_email: str = "",
|
|
contact_phone: str = "",
|
|
ceo_name: str = "",
|
|
ceo_title: str = "Chief Executive Officer",
|
|
# Classification — FCC categories
|
|
provider_classification: str = "voice_service_provider",
|
|
carrier_category: str = "interconnected_voip",
|
|
infra_type: str = "facilities",
|
|
is_wholesale: bool = False,
|
|
is_gateway_provider: bool = False,
|
|
is_international_only: bool = False,
|
|
uses_ucaas_provider: bool = False,
|
|
carrier_metadata: dict | None = None,
|
|
# STIR/SHAKEN
|
|
stir_shaken_status: str = "complete_implementation",
|
|
stir_shaken_cert_authority: str = "",
|
|
stir_shaken_extension_type: str = "",
|
|
stir_shaken_extension_basis: str = "",
|
|
upstream_provider_name: str = "",
|
|
upstream_provider_frn: str = "",
|
|
# Key intake questions (kept minimal for client)
|
|
switch_platform: str = "", # e.g. "Oasis", "Metaswitch", "BroadSoft", "FreeSWITCH"
|
|
ucaas_host: str = "", # e.g. "BCM One", "RingCentral", "Vonage"
|
|
# Robocall mitigation details (Jan 2024+ requirements)
|
|
analytics_systems: list[str] | None = None,
|
|
third_party_vendors: list[str] | None = None,
|
|
enforcement_history: list[dict] | None = None,
|
|
know_your_customer_description: str = "",
|
|
know_your_upstream_description: str = "",
|
|
# Output
|
|
output_path: str = "/tmp/rmd_certification_letter.docx",
|
|
) -> Optional[str]:
|
|
"""
|
|
Generate an RMD Certification Letter as a DOCX file.
|
|
|
|
Produces a letter compliant with 47 CFR § 64.6305 including January 2024
|
|
and January 2026 amendments. Covers all three provider classifications:
|
|
Voice Service Provider, Gateway Provider, and Non-Gateway Intermediate Provider.
|
|
|
|
Returns the output file path on success, None on failure.
|
|
"""
|
|
if Document is None:
|
|
LOG.error("python-docx not installed")
|
|
return None
|
|
|
|
metadata = carrier_metadata or {}
|
|
former_names = former_names or []
|
|
analytics_systems = analytics_systems or []
|
|
third_party_vendors = third_party_vendors or []
|
|
enforcement_history = enforcement_history or []
|
|
|
|
# Back-compat: if caller used is_gateway_provider flag but didn't set
|
|
# provider_classification, infer it.
|
|
if is_gateway_provider and provider_classification == "voice_service_provider":
|
|
provider_classification = "gateway_provider"
|
|
|
|
# If ucaas_host was provided, wire it into metadata and upstream fields
|
|
if ucaas_host:
|
|
uses_ucaas_provider = True
|
|
if not upstream_provider_name:
|
|
upstream_provider_name = ucaas_host
|
|
metadata.setdefault("ucaas_provider", ucaas_host)
|
|
|
|
doc = Document()
|
|
b = _DocBuilder(doc)
|
|
|
|
# Page margins
|
|
for section in doc.sections:
|
|
section.top_margin = Inches(1)
|
|
section.bottom_margin = Inches(1)
|
|
section.left_margin = Inches(1.25)
|
|
section.right_margin = Inches(1.25)
|
|
|
|
_add_page_number_footer(doc)
|
|
|
|
today = datetime.now().strftime("%B %d, %Y")
|
|
recert_year = datetime.now().year
|
|
# Per 64.6305(h), annual recertification deadline is March 1
|
|
recert_deadline = f"March 1, {recert_year + 1}"
|
|
|
|
# ── Professional header block ────────────────────────────────────
|
|
header_p = doc.add_paragraph()
|
|
header_p.alignment = WD_ALIGN_PARAGRAPH.LEFT
|
|
name_run = header_p.add_run(entity_name)
|
|
name_run.font.size = Pt(16)
|
|
name_run.font.color.rgb = NAVY
|
|
name_run.bold = True
|
|
_set_paragraph_spacing(header_p, after_pt=2)
|
|
|
|
if dba_name:
|
|
dba_p = doc.add_paragraph()
|
|
dba_run = dba_p.add_run(f"d/b/a {dba_name}")
|
|
dba_run.font.size = Pt(BODY_SIZE)
|
|
dba_run.font.color.rgb = GRAY
|
|
_set_paragraph_spacing(dba_p, after_pt=2)
|
|
|
|
# Address and contact sub-header
|
|
sub_lines = []
|
|
addr_line = ", ".join(filter(None, [address_street, address_city]))
|
|
if address_state or address_zip:
|
|
addr_line += f", {address_state} {address_zip}".strip()
|
|
if addr_line.strip(", "):
|
|
sub_lines.append(addr_line.strip(", "))
|
|
id_parts = []
|
|
if frn:
|
|
id_parts.append(f"FRN: {frn}")
|
|
if ocn:
|
|
id_parts.append(f"OCN: {ocn}")
|
|
if id_parts:
|
|
sub_lines.append(" | ".join(id_parts))
|
|
if contact_phone:
|
|
sub_lines.append(f"Tel: {contact_phone}")
|
|
if contact_email:
|
|
sub_lines.append(f"Email: {contact_email}")
|
|
|
|
if sub_lines:
|
|
sub_p = doc.add_paragraph()
|
|
sub_run = sub_p.add_run("\n".join(sub_lines))
|
|
sub_run.font.size = Pt(9)
|
|
sub_run.font.color.rgb = GRAY
|
|
_set_paragraph_spacing(sub_p, after_pt=6)
|
|
|
|
b.horizontal_rule()
|
|
|
|
# Date
|
|
b.body(today)
|
|
|
|
# ── Title ────────────────────────────────────────────────────────
|
|
b.title("ROBOCALL MITIGATION DATABASE CERTIFICATION")
|
|
b.body(f"Prepared: {today}", italic=True, alignment=WD_ALIGN_PARAGRAPH.CENTER)
|
|
b.spacer()
|
|
|
|
# ── Introduction ─────────────────────────────────────────────────
|
|
classification_label = _CLASSIFICATION_LABELS.get(
|
|
provider_classification,
|
|
"Voice Service Provider (47 CFR § 64.6305(d))",
|
|
)
|
|
b.body(
|
|
f"Pursuant to 47 CFR § 64.6305, {entity_name} "
|
|
f"({'FRN: ' + frn if frn else 'FRN pending'}) submits this "
|
|
f"certification to the Robocall Mitigation Database as a "
|
|
f"{classification_label}."
|
|
)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 1: Provider Information
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("1. Provider Information")
|
|
|
|
b.field_value("Legal Name", entity_name)
|
|
if dba_name:
|
|
b.field_value("Doing Business As (DBA)", dba_name)
|
|
if former_names:
|
|
b.field_value("Former / Alternate Business Names", "; ".join(former_names))
|
|
b.field_value("FCC Registration Number (FRN)", frn or "Pending")
|
|
if ocn:
|
|
b.field_value("Operating Company Number (OCN)", ocn)
|
|
if filer_id_499:
|
|
b.field_value("Form 499 Filer ID", filer_id_499)
|
|
if rmd_number:
|
|
b.field_value("RMD Registration Number", rmd_number)
|
|
|
|
category_label = _CATEGORY_LABELS.get(
|
|
carrier_category, "Telecommunications Service Provider"
|
|
)
|
|
b.field_value("Carrier Authorization Type", category_label)
|
|
|
|
addr_full = ", ".join(filter(None, [
|
|
address_street, address_city, address_state, address_zip,
|
|
]))
|
|
if addr_full:
|
|
b.field_value("Principal Address", addr_full)
|
|
|
|
robocall_contact = contact_name or ceo_name or "Regulatory Contact"
|
|
robocall_title = contact_title or ceo_title or ""
|
|
b.field_value("Robocall Mitigation Contact", robocall_contact)
|
|
if robocall_title:
|
|
b.field_value("Title", robocall_title)
|
|
if contact_email:
|
|
b.field_value("Contact Email", contact_email)
|
|
if contact_phone:
|
|
b.field_value("Contact Phone", contact_phone)
|
|
|
|
# Foreign provider affiliation disclosure
|
|
if is_foreign_provider:
|
|
b.spacer()
|
|
b.body(
|
|
f"{entity_name} discloses that it is a foreign voice service provider "
|
|
f"or is affiliated with a foreign voice service provider. "
|
|
f"{entity_name} acknowledges the additional obligations applicable "
|
|
f"to foreign-affiliated providers under 47 CFR § 64.6305.",
|
|
italic=True,
|
|
)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 2: Provider Classification
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("2. Provider Classification")
|
|
|
|
b.body(
|
|
f"{entity_name} certifies that it is filing this certification as a "
|
|
f"{classification_label}.",
|
|
bold=True,
|
|
)
|
|
|
|
_build_classification_detail(b, entity_name=entity_name,
|
|
provider_classification=provider_classification,
|
|
carrier_category=carrier_category,
|
|
infra_type=infra_type, metadata=metadata,
|
|
upstream_provider_name=upstream_provider_name,
|
|
upstream_provider_frn=upstream_provider_frn,
|
|
is_wholesale=is_wholesale,
|
|
is_international_only=is_international_only,
|
|
uses_ucaas_provider=uses_ucaas_provider)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 3: STIR/SHAKEN Implementation Status
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("3. STIR/SHAKEN Implementation Status")
|
|
|
|
_build_stir_shaken_section(b, entity_name=entity_name,
|
|
stir_shaken_status=stir_shaken_status,
|
|
stir_shaken_cert_authority=stir_shaken_cert_authority,
|
|
stir_shaken_extension_type=stir_shaken_extension_type,
|
|
stir_shaken_extension_basis=stir_shaken_extension_basis,
|
|
provider_classification=provider_classification,
|
|
upstream_provider_name=upstream_provider_name,
|
|
uses_ucaas_provider=uses_ucaas_provider,
|
|
metadata=metadata)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 4: Robocall Mitigation Program Certification
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("4. Robocall Mitigation Program Certification")
|
|
|
|
needs_exhibit_a = stir_shaken_status in (
|
|
"partial_implementation",
|
|
"robocall_mitigation_only",
|
|
"exempt_small_carrier",
|
|
)
|
|
|
|
# Auto-generate vague but plausible descriptions from intake answers
|
|
kyc_desc = know_your_customer_description or _auto_kyc(
|
|
entity_name, provider_classification, ucaas_host, switch_platform,
|
|
)
|
|
kyu_desc = know_your_upstream_description or _auto_kyu(
|
|
entity_name, provider_classification, ucaas_host,
|
|
)
|
|
auto_analytics = analytics_systems or _auto_analytics(
|
|
provider_classification, switch_platform, ucaas_host,
|
|
)
|
|
auto_vendors = third_party_vendors or _auto_vendors(
|
|
provider_classification, ucaas_host,
|
|
)
|
|
|
|
if needs_exhibit_a:
|
|
b.body(
|
|
f"{entity_name} certifies that all calls it "
|
|
f"{'originates' if provider_classification == 'voice_service_provider' else 'carries or processes'} "
|
|
f"are subject to a robocall mitigation program designed to reduce "
|
|
f"illegal robocall traffic. The complete program description is set "
|
|
f"forth in Exhibit A, attached hereto."
|
|
)
|
|
else:
|
|
b.body(
|
|
f"{entity_name} has fully implemented STIR/SHAKEN caller ID "
|
|
f"authentication on its network. All originated calls are "
|
|
f"authenticated using STIR/SHAKEN certificates."
|
|
)
|
|
|
|
b.spacer()
|
|
b.body("Know-Your-Customer Procedures (47 CFR § 64.1200(n)(4)):", bold=True)
|
|
b.body(kyc_desc)
|
|
|
|
b.spacer()
|
|
b.body("Know-Your-Upstream-Provider Procedures (47 CFR § 64.1200(n)(5)):", bold=True)
|
|
b.body(kyu_desc)
|
|
|
|
b.spacer()
|
|
b.body("Analytics Systems:", bold=True)
|
|
for system in auto_analytics:
|
|
b.bullet(system)
|
|
|
|
if auto_vendors:
|
|
b.spacer()
|
|
b.body("Third-Party Vendors:", bold=True)
|
|
for vendor in auto_vendors:
|
|
b.bullet(vendor)
|
|
|
|
b.spacer()
|
|
b.body("Do-Not-Originate (DNO) List Enforcement:", bold=True)
|
|
b.body(
|
|
f"{entity_name} immediately blocks any numbers identified on the FCC "
|
|
f"Do-Not-Originate (DNO) list. DNO list updates are applied promptly "
|
|
f"to prevent origination of calls from numbers known to be used for "
|
|
f"illegal robocalling."
|
|
)
|
|
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 5: Traceback Commitment
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("5. Traceback Commitment")
|
|
|
|
b.body(
|
|
_TRACEBACK_COMMITMENT.format(entity_name=entity_name),
|
|
bold=True,
|
|
)
|
|
b.body(
|
|
f"In addition, {entity_name} certifies that it will cooperate with "
|
|
f"the industry traceback consortium operated by USTelecom — the "
|
|
f"Broadband Association — and will provide requested call detail "
|
|
f"records and other information necessary to trace the origin of "
|
|
f"suspected illegal robocalls."
|
|
)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 6: Enforcement History Disclosure
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("6. Enforcement History Disclosure")
|
|
|
|
b.body(
|
|
f"Pursuant to 47 CFR § 64.6305(d)(2)(iv) (and parallel provisions at "
|
|
f"(e)(2)(iv) and (f)(2)(iv)), {entity_name} hereby discloses any "
|
|
f"enforcement actions, pending investigations, or adverse findings "
|
|
f"within the two-year lookback period:",
|
|
)
|
|
|
|
if enforcement_history:
|
|
for item in enforcement_history:
|
|
action_type = item.get("type", "Enforcement Action")
|
|
agency = item.get("agency", "FCC")
|
|
date_str = item.get("date", "")
|
|
description = item.get("description", "")
|
|
status = item.get("status", "")
|
|
detail = f"{action_type} — {agency}"
|
|
if date_str:
|
|
detail += f" ({date_str})"
|
|
if description:
|
|
detail += f": {description}"
|
|
if status:
|
|
detail += f" [Status: {status}]"
|
|
b.bullet(detail)
|
|
else:
|
|
b.body(
|
|
f"{entity_name} certifies that it has not been the subject of any "
|
|
f"enforcement action, investigation, or adverse finding by the FCC, "
|
|
f"any state regulatory authority, or any law enforcement agency "
|
|
f"related to robocalling, caller ID spoofing, or telephone consumer "
|
|
f"protection within the preceding two (2) years."
|
|
)
|
|
|
|
# Prior certification removal declaration
|
|
b.spacer()
|
|
b.body(
|
|
f"{entity_name} further certifies that its prior Robocall Mitigation "
|
|
f"Database certification has not been removed by the Commission and "
|
|
f"that {entity_name} has not been prohibited from filing a "
|
|
f"certification in the Robocall Mitigation Database.",
|
|
bold=True,
|
|
)
|
|
b.spacer()
|
|
|
|
# ══════════════════════════════════════════════════════════════════
|
|
# SECTION 7: Certification Declarations
|
|
# ══════════════════════════════════════════════════════════════════
|
|
b.horizontal_rule()
|
|
b.section_heading("7. Certification Declarations")
|
|
|
|
b.body(
|
|
f"{entity_name} certifies the following for submission to the "
|
|
f"FCC Robocall Mitigation Database portal:"
|
|
)
|
|
b.bullet(
|
|
f"All calls that {entity_name} "
|
|
f"{'originates' if provider_classification == 'voice_service_provider' else 'carries or processes'} "
|
|
f"are subject to a robocall mitigation program consistent with "
|
|
f"47 CFR § 64.6305."
|
|
)
|
|
b.bullet(
|
|
f"{entity_name}'s prior RMD certification has not been removed by "
|
|
f"the Commission, and {entity_name} has not been prohibited from filing."
|
|
)
|
|
b.bullet(
|
|
f"All information in this certification is true, complete, and accurate."
|
|
)
|
|
b.bullet(
|
|
f"{entity_name} will update this certification within ten (10) "
|
|
f"business days of any material change."
|
|
)
|
|
|
|
# Annual recertification (per 64.6305(h), effective Feb 2026)
|
|
b.spacer()
|
|
b.body(
|
|
f"Annual Recertification: Pursuant to 47 CFR § 64.6305(h), "
|
|
f"{entity_name} acknowledges the annual recertification deadline of "
|
|
f"{recert_deadline}.",
|
|
bold=True,
|
|
)
|
|
b.spacer()
|
|
|
|
# Note: perjury declaration is made through the FCC portal, not in this document
|
|
b.body(
|
|
"Note: The 47 CFR § 1.16 declaration under penalty of perjury is "
|
|
"made through the FCC's RMD portal at the time of electronic filing.",
|
|
italic=True,
|
|
)
|
|
|
|
# ── Exhibit A placeholder ────────────────────────────────────────
|
|
if needs_exhibit_a:
|
|
doc.add_page_break()
|
|
|
|
exhibit_heading = doc.add_paragraph()
|
|
exhibit_heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
exhibit_run = exhibit_heading.add_run("EXHIBIT A")
|
|
exhibit_run.font.size = Pt(TITLE_SIZE)
|
|
exhibit_run.bold = True
|
|
exhibit_run.font.color.rgb = NAVY
|
|
_set_paragraph_spacing(exhibit_heading, after_pt=6)
|
|
|
|
exhibit_sub = doc.add_paragraph()
|
|
exhibit_sub.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
sub_run = exhibit_sub.add_run("Robocall Mitigation Program")
|
|
sub_run.font.size = Pt(HEADING_SIZE)
|
|
sub_run.bold = True
|
|
sub_run.font.color.rgb = NAVY
|
|
_set_paragraph_spacing(exhibit_sub, after_pt=12)
|
|
|
|
b.body(
|
|
"[This exhibit is generated separately. See the companion "
|
|
"Robocall Mitigation Program document for the complete program "
|
|
"description.]",
|
|
italic=True,
|
|
)
|
|
|
|
# Save
|
|
output = Path(output_path)
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
doc.save(str(output))
|
|
LOG.info("RMD certification letter generated: %s", output)
|
|
return str(output)
|
|
|
|
|
|
# ── Auto-generation of vague but plausible descriptions ─────────────────
|
|
# These keep client burden minimal — we only need a few intake answers
|
|
# (switch_platform, ucaas_host) to produce compliant-sounding language.
|
|
|
|
# Known STIR/SHAKEN certificate authorities (STI-CAs) — clients can pick
|
|
# from this list or type in their own. Kept in alphabetical order.
|
|
KNOWN_STI_CAS = [
|
|
"Comcast Technology Solutions",
|
|
"iconectiv",
|
|
"Martini Security",
|
|
"Metaswitch (Microsoft)",
|
|
"NetNumber",
|
|
"Neustar (TransUnion)",
|
|
"Peeringhub",
|
|
"Ribbon Communications",
|
|
"Sievert Larsen & Associates (SLA)",
|
|
"SignalWire",
|
|
"Syngular (T-Mobile)",
|
|
"TransNexus",
|
|
]
|
|
|
|
# Known STIR/SHAKEN signing service providers — these actually sign calls
|
|
# on behalf of the carrier (distinct from the STI-CA that issues certs).
|
|
# Clients pick from this list or type in their own.
|
|
KNOWN_SIGNING_PROVIDERS = [
|
|
"Oasis (ABQ Technology Partners)",
|
|
"Peeringhub",
|
|
"SignalWire",
|
|
"Sansay / Oasis",
|
|
"TransNexus",
|
|
"Ribbon Communications",
|
|
"NetSapiens",
|
|
"Metaswitch (Microsoft)",
|
|
"Oasis Networks",
|
|
"Telnyx",
|
|
"Bandwidth",
|
|
"Lumen (CenturyLink)",
|
|
"Twilio",
|
|
"Vonage / Nexmo",
|
|
]
|
|
|
|
# Known softswitch / switch platforms — we ask the client which one they
|
|
# use so we can auto-fill plausible infrastructure descriptions.
|
|
KNOWN_SWITCH_PLATFORMS = [
|
|
"Oasis",
|
|
"Metaswitch",
|
|
"BroadSoft (Cisco)",
|
|
"BroadWorks (Cisco)",
|
|
"FreeSWITCH",
|
|
"Asterisk",
|
|
"NetSapiens",
|
|
"Ribbon SBC",
|
|
"3CX",
|
|
"Kamailio",
|
|
"Genesys Cloud",
|
|
"Denovo Lab",
|
|
"46Labs",
|
|
"SIP Navigator",
|
|
"Cataleya",
|
|
"Oasis / Sansay",
|
|
"Oasis VOS",
|
|
"Netsapiens SNAPsolution",
|
|
]
|
|
|
|
# Known UCaaS / hosted PBX providers — we ask who hosts the client's voice
|
|
# platform so we can auto-fill upstream provider and KYU descriptions.
|
|
KNOWN_UCAAS_HOSTS = [
|
|
"BCM One",
|
|
"RingCentral",
|
|
"Vonage",
|
|
"8x8",
|
|
"Dialpad",
|
|
"Zoom Phone",
|
|
"Microsoft Teams (Operator Connect)",
|
|
"Nextiva",
|
|
"Ooma",
|
|
"GoTo Connect",
|
|
"Intermedia",
|
|
"Comcast Business VoiceEdge",
|
|
"Windstream",
|
|
"Lumen",
|
|
"Granite Telecom",
|
|
"Fusion Connect",
|
|
"Star2Star (Sangoma)",
|
|
"Alianza",
|
|
"Skyswitch",
|
|
"Bicom Systems",
|
|
]
|
|
|
|
|
|
def _auto_kyc(entity_name: str, classification: str, ucaas_host: str,
|
|
switch_platform: str) -> str:
|
|
"""Generate vague but plausible KYC description based on provider type."""
|
|
if classification == "gateway_provider":
|
|
return (
|
|
f"{entity_name} maintains verification procedures for all "
|
|
f"interconnection partners prior to exchanging traffic. These "
|
|
f"procedures include confirming valid operating authority, verifying "
|
|
f"RMD certification status, and requiring execution of acceptable "
|
|
f"use provisions in interconnection agreements."
|
|
)
|
|
if ucaas_host:
|
|
return (
|
|
f"{entity_name} verifies the identity and business legitimacy of "
|
|
f"all customers during onboarding through its service provisioning "
|
|
f"workflow. Customer accounts are subject to acceptable use policies "
|
|
f"that prohibit illegal robocalling. {ucaas_host} additionally "
|
|
f"enforces platform-level customer vetting requirements."
|
|
)
|
|
if switch_platform:
|
|
return (
|
|
f"{entity_name} verifies the identity and business legitimacy of "
|
|
f"all new customers prior to provisioning service on its "
|
|
f"{switch_platform} platform. Onboarding procedures include "
|
|
f"verification of business registration, confirmation of authorized "
|
|
f"representatives, and execution of acceptable use policies that "
|
|
f"prohibit illegal robocalling."
|
|
)
|
|
return (
|
|
f"{entity_name} maintains customer onboarding procedures that include "
|
|
f"verification of business identity and execution of acceptable use "
|
|
f"policies prohibiting illegal robocalling. New accounts are reviewed "
|
|
f"prior to activation and are subject to a monitoring period during "
|
|
f"initial usage."
|
|
)
|
|
|
|
|
|
def _auto_kyu(entity_name: str, classification: str, ucaas_host: str) -> str:
|
|
"""Generate vague but plausible know-your-upstream description."""
|
|
if classification == "gateway_provider":
|
|
return (
|
|
f"{entity_name} verifies all upstream international correspondents "
|
|
f"and interconnection partners. Verification includes confirmation "
|
|
f"of valid operating authority in the originating jurisdiction and "
|
|
f"contractual anti-robocalling provisions. {entity_name} periodically "
|
|
f"reviews traffic patterns on all upstream routes."
|
|
)
|
|
if ucaas_host:
|
|
return (
|
|
f"{entity_name} obtains voice services through {ucaas_host}, which "
|
|
f"maintains a current certification in the FCC Robocall Mitigation "
|
|
f"Database. {entity_name} has verified {ucaas_host}'s RMD filing "
|
|
f"status and relies on {ucaas_host}'s upstream provider verification "
|
|
f"procedures for traffic entering the platform."
|
|
)
|
|
return (
|
|
f"{entity_name} verifies that its upstream providers and "
|
|
f"interconnection partners maintain current certifications in the "
|
|
f"FCC Robocall Mitigation Database. {entity_name} periodically reviews "
|
|
f"upstream traffic sources and investigates anomalous call patterns."
|
|
)
|
|
|
|
|
|
def _auto_analytics(classification: str, switch_platform: str,
|
|
ucaas_host: str) -> list[str]:
|
|
"""Generate plausible analytics system descriptions."""
|
|
systems = []
|
|
if switch_platform:
|
|
systems.append(
|
|
f"{switch_platform} built-in call detail record (CDR) analysis "
|
|
f"and traffic monitoring"
|
|
)
|
|
if ucaas_host:
|
|
systems.append(
|
|
f"{ucaas_host} platform analytics and call pattern monitoring"
|
|
)
|
|
systems.append("Internal call detail record (CDR) review and anomaly detection")
|
|
if classification == "gateway_provider":
|
|
systems.append("Per-route traffic volume and short-duration call monitoring")
|
|
return systems
|
|
|
|
|
|
def _auto_vendors(classification: str, ucaas_host: str) -> list[str]:
|
|
"""Generate plausible third-party vendor list."""
|
|
vendors = []
|
|
if ucaas_host:
|
|
vendors.append(ucaas_host)
|
|
if classification == "gateway_provider":
|
|
vendors.append("USTelecom — Industry Traceback Group")
|
|
# Intentionally vague — most small carriers don't use named third-party
|
|
# analytics vendors, and the FCC accepts "none" for this field.
|
|
return vendors
|
|
|
|
|
|
# ── Section builders ─────────────────────────────────────────────────────
|
|
|
|
def _build_classification_detail(
|
|
b: _DocBuilder,
|
|
*,
|
|
entity_name: str,
|
|
provider_classification: str,
|
|
carrier_category: str,
|
|
infra_type: str,
|
|
metadata: dict,
|
|
upstream_provider_name: str,
|
|
upstream_provider_frn: str,
|
|
is_wholesale: bool,
|
|
is_international_only: bool,
|
|
uses_ucaas_provider: bool,
|
|
):
|
|
"""Build the detailed provider classification description."""
|
|
|
|
category_label = _CATEGORY_LABELS.get(
|
|
carrier_category, "telecommunications service provider"
|
|
)
|
|
|
|
if provider_classification == "gateway_provider":
|
|
countries = metadata.get("gateway_countries", [])
|
|
countries_str = ", ".join(countries) if countries else "various foreign jurisdictions"
|
|
b.body(
|
|
f"{entity_name} is a {category_label} operating as a gateway "
|
|
f"provider, receiving voice traffic that originates outside the "
|
|
f"United States and transmitting that traffic to a destination in "
|
|
f"the United States. {entity_name} transits voice traffic between "
|
|
f"the U.S. public switched telephone network (PSTN) and "
|
|
f"telecommunications networks in {countries_str}."
|
|
)
|
|
if infra_type in ("facilities", "both"):
|
|
b.body(
|
|
f"{entity_name} owns and operates switching and routing "
|
|
f"infrastructure for the purpose of originating, terminating, "
|
|
f"and transiting international voice traffic."
|
|
)
|
|
|
|
elif provider_classification == "intermediate_provider":
|
|
b.body(
|
|
f"{entity_name} is a {category_label} operating as a non-gateway "
|
|
f"intermediate provider. {entity_name} routes voice traffic to the "
|
|
f"next provider in the call path but does not originate or "
|
|
f"terminate the call, and does not serve as the gateway for "
|
|
f"traffic entering the United States from abroad."
|
|
)
|
|
|
|
else: # voice_service_provider
|
|
if uses_ucaas_provider:
|
|
ucaas_provider = metadata.get(
|
|
"ucaas_provider", upstream_provider_name or "its UCaaS provider"
|
|
)
|
|
ucaas_frn = metadata.get(
|
|
"ucaas_provider_frn", upstream_provider_frn or ""
|
|
)
|
|
frn_note = f" (FRN: {ucaas_frn})" if ucaas_frn else ""
|
|
b.body(
|
|
f"{entity_name} is a {category_label} that uses the Unified "
|
|
f"Communications as a Service (UCaaS) platform of "
|
|
f"{ucaas_provider}{frn_note} to provide voice services to its "
|
|
f"end users. {ucaas_provider} provides the underlying voice "
|
|
f"infrastructure, including call routing, PSTN interconnection, "
|
|
f"and caller ID authentication services on behalf of "
|
|
f"{entity_name}."
|
|
)
|
|
|
|
elif infra_type == "reseller":
|
|
upstream = upstream_provider_name or "its upstream provider"
|
|
upstream_frn_note = (
|
|
f" (FRN: {upstream_provider_frn})" if upstream_provider_frn else ""
|
|
)
|
|
b.body(
|
|
f"{entity_name} is a {category_label} that resells voice "
|
|
f"services obtained from {upstream}{upstream_frn_note}. "
|
|
f"{entity_name} does not own or operate its own switching or "
|
|
f"routing infrastructure; voice traffic is originated and "
|
|
f"terminated through the facilities of its upstream provider."
|
|
)
|
|
|
|
elif is_international_only:
|
|
b.body(
|
|
f"{entity_name} is a {category_label} that exclusively handles "
|
|
f"international voice traffic originating from or terminating "
|
|
f"to foreign telecommunications networks."
|
|
)
|
|
|
|
elif is_wholesale:
|
|
customer_types = metadata.get("wholesale_customer_types", [])
|
|
downstream_count = metadata.get("downstream_count_approx", None)
|
|
ct_str = (
|
|
", ".join(customer_types).upper()
|
|
if customer_types
|
|
else "downstream carriers"
|
|
)
|
|
count_str = (
|
|
f"approximately {downstream_count}"
|
|
if downstream_count
|
|
else "multiple"
|
|
)
|
|
b.body(
|
|
f"{entity_name} is a {category_label} operating as a wholesale "
|
|
f"voice service provider within the United States. "
|
|
f"{entity_name} serves {count_str} downstream carriers, "
|
|
f"including {ct_str} providers."
|
|
)
|
|
|
|
else: # facilities-based default
|
|
b.body(
|
|
f"{entity_name} is a {category_label} that owns and operates "
|
|
f"switching and routing infrastructure for the origination and "
|
|
f"termination of voice calls. {entity_name} directly "
|
|
f"interconnects with other carriers and originates voice "
|
|
f"traffic on its network."
|
|
)
|
|
|
|
# Wholesale qualifier for non-primary wholesale roles
|
|
if is_wholesale and provider_classification == "voice_service_provider" and not (
|
|
is_international_only or infra_type == "reseller"
|
|
):
|
|
b.body(
|
|
f"In addition to retail services, {entity_name} also provides "
|
|
f"wholesale voice services to downstream carriers."
|
|
)
|
|
|
|
|
|
def _build_stir_shaken_section(
|
|
b: _DocBuilder,
|
|
*,
|
|
entity_name: str,
|
|
stir_shaken_status: str,
|
|
stir_shaken_cert_authority: str,
|
|
stir_shaken_extension_type: str,
|
|
stir_shaken_extension_basis: str,
|
|
provider_classification: str,
|
|
upstream_provider_name: str,
|
|
uses_ucaas_provider: bool,
|
|
metadata: dict,
|
|
):
|
|
"""Build the STIR/SHAKEN Implementation Status section."""
|
|
|
|
if stir_shaken_status == "complete_implementation":
|
|
cert = stir_shaken_cert_authority or "an authorized Certification Authority"
|
|
b.body(
|
|
f"{entity_name} has fully implemented the STIR/SHAKEN caller ID "
|
|
f"authentication framework in compliance with the TRACED Act and "
|
|
f"47 CFR § 64.6301."
|
|
)
|
|
b.bullet(f"SPC token and STIR/SHAKEN certificates obtained from {cert}.")
|
|
b.bullet(
|
|
"All calls originated on the network are signed with appropriate "
|
|
"attestation levels:"
|
|
)
|
|
b.bullet("Full Attestation (Level A) — calling party fully verified.", level=1)
|
|
b.bullet(
|
|
"Partial Attestation (Level B) — call originated on network but "
|
|
"caller not fully verified.",
|
|
level=1,
|
|
)
|
|
b.bullet(
|
|
"Gateway Attestation (Level C) — call entering network from an "
|
|
"interconnection partner.",
|
|
level=1,
|
|
)
|
|
|
|
elif stir_shaken_status == "partial_implementation":
|
|
cert = stir_shaken_cert_authority or "an authorized Certification Authority"
|
|
b.body(
|
|
f"{entity_name} has partially implemented the STIR/SHAKEN caller "
|
|
f"ID authentication framework."
|
|
)
|
|
b.bullet(f"SPC token and STIR/SHAKEN certificates obtained from {cert}.")
|
|
b.bullet(
|
|
"Calls originated on SIP-capable portions of the network are signed "
|
|
"with STIR/SHAKEN."
|
|
)
|
|
b.body(
|
|
f"For calls that cannot be signed using STIR/SHAKEN — including "
|
|
f"calls originated on TDM facilities or transited through non-SIP "
|
|
f"network segments — {entity_name} has implemented a robocall "
|
|
f"mitigation program as described in Exhibit A to this certification."
|
|
)
|
|
|
|
elif stir_shaken_status == "exempt_small_carrier":
|
|
b.body(
|
|
f"{entity_name} qualifies for an extension of the STIR/SHAKEN "
|
|
f"implementation deadline under 47 CFR § 64.6304 and is not "
|
|
f"currently required to implement STIR/SHAKEN caller ID "
|
|
f"authentication technology."
|
|
)
|
|
if stir_shaken_extension_type:
|
|
b.field_value("Extension Type", stir_shaken_extension_type)
|
|
if stir_shaken_extension_basis:
|
|
b.field_value("Basis for Extension", stir_shaken_extension_basis)
|
|
|
|
b.body(
|
|
f"In lieu of STIR/SHAKEN implementation, {entity_name} has "
|
|
f"implemented a robocall mitigation program as described in "
|
|
f"Exhibit A to this certification."
|
|
)
|
|
|
|
if uses_ucaas_provider or upstream_provider_name:
|
|
upstream = metadata.get(
|
|
"ucaas_provider", upstream_provider_name or "its upstream provider"
|
|
)
|
|
b.body(
|
|
f"Additionally, {entity_name} notes that its upstream provider, "
|
|
f"{upstream}, implements STIR/SHAKEN on calls originated through "
|
|
f"its platform and maintains a current certification in the "
|
|
f"Robocall Mitigation Database.",
|
|
italic=True,
|
|
)
|
|
|
|
elif stir_shaken_status == "robocall_mitigation_only":
|
|
b.body(
|
|
f"{entity_name} has not implemented STIR/SHAKEN caller ID "
|
|
f"authentication technology. In accordance with 47 CFR § 64.6305, "
|
|
f"{entity_name} has instead implemented a robocall mitigation "
|
|
f"program reasonably designed to reduce the origination of illegal "
|
|
f"robocalls on its network."
|
|
)
|
|
if stir_shaken_extension_type:
|
|
b.field_value("Extension Type", stir_shaken_extension_type)
|
|
if stir_shaken_extension_basis:
|
|
b.field_value("Basis for Extension", stir_shaken_extension_basis)
|
|
|
|
b.body(
|
|
"The complete program description is set forth in Exhibit A to "
|
|
"this certification."
|
|
)
|
|
|
|
if uses_ucaas_provider or upstream_provider_name:
|
|
upstream = metadata.get(
|
|
"ucaas_provider", upstream_provider_name or "its upstream provider"
|
|
)
|
|
b.body(
|
|
f"{entity_name} further notes that {upstream}, the upstream "
|
|
f"provider through which {entity_name} originates voice calls, "
|
|
f"implements STIR/SHAKEN authentication and maintains a current "
|
|
f"RMD certification.",
|
|
italic=True,
|
|
)
|
|
|
|
else: # not_applicable
|
|
b.body(
|
|
f"{entity_name} certifies that STIR/SHAKEN implementation is not "
|
|
f"applicable to its operations based on the nature of its voice "
|
|
f"services. {entity_name} does not originate calls to the PSTN "
|
|
f"that would require STIR/SHAKEN authentication."
|
|
)
|