{
  "id": "OPS-384",
  "slug": "ops-384",
  "title": "Nothing goes out before the opt-in",
  "statement": "Messages may be sent only after the consumer has opted in; the single opt-out acknowledgement is the only permitted exception.",
  "rationale": "This is the obligation the whole framework exists to enforce, and it is worth stating separately because the failure is rarely a decision to send unsolicited messages — it is a list imported without provenance, a form that wrote consent before the box was ticked, or a test send to a colleague's number that went to the whole file. The consequence does not scale with the intent.",
  "layer": "OPERATIONAL",
  "layerSlug": "operational",
  "object": "send-time consent check",
  "severity": "BLOCKING",
  "detectability": [
    "UNDETECTABLE_PRE_SUBMISSION"
  ],
  "failureClass": "HARD_STOP",
  "authorities": [
    "CTIA",
    "FCC",
    "all MNOs"
  ],
  "applicabilityText": "Applies to every 10DLC registration.",
  "universal": true,
  "remediation": "Check consent at send time against a per-number record, never against list membership, and make an unconsented number impossible to include rather than unlikely.",
  "notes": "The runtime form of everything the CONSENT_FLOW layer checks at registration. What the user has to verify is that their send path reads a consent record rather than a segment — segments are built by people and consent records are not.",
  "phase": "post",
  "automated": false,
  "attestation": {
    "question": "Does your send path check a per-number consent record, or does it check list membership?",
    "howToCheck": [
      "Trace one send to the thing it actually reads. Segments are built by people; consent records are not.",
      "Make an unconsented number impossible to include rather than unlikely.",
      "The single opt-out acknowledgement is the only message permitted without a prior opt-in."
    ],
    "failureLooksLike": "A list imported without provenance, a form that wrote consent before the box was ticked, or a test send to a colleague that went to the whole file. The consequence does not scale with the intent."
  },
  "url": "https://ekas.io/rules/10dlc/operational/ops-384/",
  "markdown": "https://ekas.io/rules/10dlc/operational/ops-384.md",
  "registry": "https://ekas.io/rules/10dlc/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/"
}
