{
  "id": "OPS-056",
  "slug": "ops-056",
  "title": "Opt-out records must keep the words the consumer actually sent",
  "statement": "Every opt-out transaction must be recorded with the raw inbound text, the channel it arrived on, and the normalisation that was applied to it.",
  "rationale": "The hard opt-out cases are never \"STOP\". They are \"stop texting me\", a reply on the wrong keyword, a revocation left on a voicemail — and whether each was honoured turns on what the handler did with the exact words. A record keeping only \"opted out: true\" cannot show that a borderline message was read correctly, and cannot show that a missed one was missed, which is the same as having no answer when a regulator asks how revocations are recognised.",
  "layer": "OPERATIONAL",
  "layerSlug": "operational",
  "object": "campaign.message_flow + privacy policy",
  "severity": "BLOCKING",
  "detectability": [
    "AI_FORM"
  ],
  "failureClass": "RETRY_FIELD",
  "authorities": [
    "CTIA",
    "FCC"
  ],
  "applicabilityText": "Applies to every 10DLC registration.",
  "universal": true,
  "remediation": "Store three things per revocation: the inbound text verbatim, the channel it arrived on (SMS, call, email, agent), and the keyword or intent it was matched to. Done when you can list last month's opt-outs and read what each consumer actually wrote.",
  "example": "Opt-out records store: received_at, channel=SMS, raw_text=\"please stop texting me\", matched=STOP (natural-language), phone number.",
  "pitfalls": [
    "Recording the normalised keyword only (\"STOP\") loses exactly the evidence the rule exists for — the raw text is what shows a variant was understood."
  ],
  "notes": "Absorbs OPS-220, which names the channel field this record must carry. Registration-side twin: the handler behaviour itself is not observable before traffic, but whether the programme has decided to keep the evidence is.",
  "catalogIds": [
    "OPS-220"
  ],
  "phase": "approval",
  "automated": true,
  "url": "https://ekas.io/rules/10dlc/operational/ops-056/",
  "markdown": "https://ekas.io/rules/10dlc/operational/ops-056.md",
  "registry": "https://ekas.io/rules/10dlc/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/"
}
