Compliance Gates

Every outbound SMS and inbound reply in the acquisitions pipeline passes through a 5-gate compliance stack before any message is sent or response generated. This hub documents each gate, its enforcement point, the 10DLC campaign-ID status (B14 blocker), and the failure behavior for any gate that trips. Read this hub first before working on outreach-stage1, followup-stages-2-3-4, or buyer-blast. Owner: acquisitions agent + Aurora.

⚠️ A2P 10DLC repeat-denial active — TCPA risk uncapped, gates ALL SMS tiers. 10DLC campaign resubmission is tracked in osil-twilio-10dlc-resubmission-2026-05-03 (B14, pending B14a Henry signoff). Additional gates required once B14 resolves: BVP verified, EIN matched, opt-in documented, 6-element CTIA disclosure present. Until B14 resolves, all live sends carry elevated TCPA exposure.

Quick reference

FieldValue
StagesPre-send qualification → Gate pass → Send → Post-send audit
Primary agent_summary
Supporting agents_summary, _summary
Agent handoff chaingate-computer → compliance-gate → blast-safety → thread-context → response-generator
Compliance gates listgate-computer, compliance-gate, blast-safety, thread-context, response-generator
Skills invokedacquisitions-outreach, acquisitions-followup, messaging-compliance-gate
Success metricsZero TCPA violations; gate-pass rate logged to openphone_events; suppression list maintained
Cost per stage~$0.002 LLM tokens per gate evaluation; SMS send cost per carrier
Throughput~50-200 deals/day evaluated; rate capped at 1 send/CH/24h
Last run resultSee openphone_events Supabase table — most recent created_at
Failure modesGate trips → no send, logged; 10DLC denial → uncapped TCPA risk; suppression miss → duplicate send

The 5 compliance gates

Every outbound send (Stage 1 through Stage 4) runs these 5 gates in order. All 5 must pass. First failure = no send, error logged.

Gate 1: gate-computer.js

What it checks: 5-gate qualification progression state for this deal. Evaluates what data is still needed from the contract holder and selects the appropriate SMS template scenario.

Gate states:

GateNameData required
1Identity & InterestFull address + asking price
2Visual & AccessPhotos or access scheduled
3Vacancy & PossessionOccupancy status
4Condition AssessmentRepair scope + known issues
5Full QualificationPrice, timeline, urgency, access all confirmed

Thread-context aware: if prior thread already covers a gate item, that gate is skipped via acquisitions-outreach thread-context.js.

Code: workspace/scripts/lib/gate-computer.js


Gate 2: compliance-gate.js (TCPA / quiet hours)

What it checks:

  • Quiet hours: 8am–9pm local time in the contract holder’s state TZ
  • Max 1 send per CH per 24-hour window
  • Max 1 send per deal per send-window
  • Dup content: same template not resent if last send <72h
  • Thread hygiene: no interrupt on human-active thread

TCPA exposure: Until osil-twilio-10dlc-resubmission-2026-05-03 B14 resolves (campaign ID approved by carrier), quiet-hours enforcement is the primary TCPA guard. Do NOT disable this gate.

Code: workspace/scripts/lib/compliance-gate.js


Gate 3: blast-safety.js

What it checks:

  • Cross-deal dedup: same CH receiving messages for multiple deals in same window
  • Silence penalty: CH who replied “STOP” within last 30 days
  • Line saturation: OpenPhone per-line daily send cap

Suppression table: messaging_suppression in Supabase CCP (svueekfvfrvhylxygktb). STOP replies persist across all deals for this CH.

Code: workspace/scripts/lib/blast-safety.js


Gate 4: thread-context.js

What it checks:

  • Prior message history for this CH/deal combination
  • If a human is actively mid-conversation, blocks automated send
  • Injects conversation history into LLM context for response generation
  • Resolves conversationId from fromNumberlineId (fail-closed: if lineId can’t be resolved, no send, per feedback_quo_lineid_required)

Code: workspace/scripts/lib/thread-context.js


Gate 5: response-generator.js

What it checks / produces:

  • Selects mentor voice for touch count (Mike Ferry T1-2 → Mandeep Damji T3-6 → David Norton T7-13 → Grant Cardone T14-20 → Sean Terry T21+)
  • Generates message via v3 Dispo Conversion Agent (5,138-msg trained)
  • One question per send (Mike Ferry rule — enforced here)
  • No em-dashes in outbound copy (per feedback_no_em_dash)
  • No pass-and-pivot (per feedback_acq_no_pass_and_pivot)
  • Message length: ≤160 chars per SMS segment for 10DLC campaigns

Code: workspace/scripts/lib/response-generator.js


10DLC campaign gates (B14 — pending)

Once osil-twilio-10dlc-resubmission-2026-05-03 B14a is approved by Henry and campaign registered:

Additional gateDescription
BVP verifiedBusiness verification profile confirmed at carrier
EIN matchedEIN in campaign registration matches IRS filing
Opt-in documentedCTIA-compliant opt-in proof on record per CH
6-element CTIA disclosureProgram name, message frequency, help/stop instructions, terms URL, privacy URL, carrier disclaimer in initial message
Campaign ID routingEvery send tagged with approved 10DLC campaign ID (A2P)

These 5 gates are additive to the existing 5 — all 10 must pass post-B14.

Related plan: osil-twilio-10dlc-resubmission-2026-05-03

Components

  • workspace/scripts/lib/gate-computer.js — 5-gate qualification progression
  • workspace/scripts/lib/compliance-gate.js — TCPA, quiet hours, 24h dedup
  • workspace/scripts/lib/blast-safety.js — cross-deal dedup, suppression, line saturation
  • workspace/scripts/lib/thread-context.js — prior message history, lineId resolution
  • workspace/scripts/lib/response-generator.js — v3 Dispo Conversion Agent, mentor voice
  • workspace/scripts/lib/mentor-voice.js — touch→mentor cadence mapping
  • workspace/knowledge-base/openphone/OUTREACH-RULES.md — 10 compliance rules
  • workspace/knowledge-base/twilio/WEBHOOKS.md — carrier-level compliance

How it’s used

  • Trigger: every outbound send from acquisitions-outreach or acquisitions-followup passes all 5 gates before a message leaves
  • Workflow: unified-outreach-engine.jsgate-computer.jscompliance-gate.jsblast-safety.jsthread-context.jsresponse-generator.jsopenphone-sms.js OR dispo-send.js
  • Agents involved: _summary (primary), _summary (inbound), _summary (oversight)
  • Failure mode: any gate returning falseno send, error reason logged to openphone_events, deal status unchanged
  • Success criteria: gate-pass events in openphone_events with event_type='outbound_sms'; zero entries with event_type='compliance_block' in alert window

Agents that touch this

  • _summary — primary sender; gates enforced on every dispatch
  • _summary — inbound reply routing; also compliance-checked
  • _summary — oversight, compliance audit view
  • _summary — Solara variant follow-up also routes through these gates

Skills that invoke this

Plans that govern this

Feedback rules

KB / source docs

  • README — OpenPhone API + compliance rules
  • README — Twilio A2P/10DLC carrier compliance
  • README — SalesMsg API quirks (query-param token, NOT HMAC)

System maps

This hub is the cluster anchor for SMS/carrier compliance. All SMS-sending hubs link here.

HubRole in cluster
twilio10DLC registration, A2P campaign, carrier gateway
salesmsgSalesMsg send path (query-param auth); P0 security note
openphone-quoOpenPhone send + inbound webhook (:18792)
outreach-stage1Stage 1 initial send — all 5 gates required
followup-stages-2-3-4Stage 2-4 follow-up — same gates
buyer-blast4-channel buyer blast — compliance-gate + blast-safety

B14 blocker cross-link (10DLC): osil-twilio-10dlc-resubmission-2026-05-03

Open issues / TODOs

  • B14: 10DLC campaign resubmission pending Henry signoff (B14a) — adds 5 additional gates post-approval. Until resolved, TCPA risk is uncapped.
  • Suppression list export/sync between OpenPhone and SalesMsg paths not yet unified — possible duplicate suppression entries.
  • compliance-gate.js quiet-hours logic uses hardcoded state TZ map — verify against current DST rules.
  • Gate 5 mentor voice: touch counter persists in acquisition_deals.touch_count but not currently validated against openphone_events actual send count — drift risk.

Recent activity

  • 2026-05-03: hub created (W1-S8)