Compliance

Cabinet Resolution 56/2024, enforced in SQL, not in the prompt.

Compliant AI outbound to property owners is the whole reason this product exists. Every guardrail below is a database constraint, a locked prompt section, or a compiler invariant with a failing test if it's ever removed. Prompts drift. SQL doesn't.

Controls in force

Law / RuleWhat it requiresHow EstateCaller enforces it
TDRA calling window09:00–18:00 GST only, no calls on public holidays.Database check constraint on campaigns. Dialer refuses to dial outside window; queues for the next open slot.
TDRA Do-Not-Call Registry (DNCR)Numbers on the DNCR must never be dialled.Suppression list scrubbed at claim time, dropped rows are audit-logged, never even attempted.
PDPL, Federal Decree-Law No. 45 of 2021Data subject must be notified of recording before processing begins. Purpose disclosed at point of collection.Recording notice + purpose statement in the locked opening. Compiler invariant INV-1b blocks a build without them.
PDPL, Right to be forgotten'Remove me' must halt processing across the controller, immediately.Owner-triggered removal writes to suppression, cascades workspace-wide. Any future campaign in the workspace skips that owner. No override in the UI.
RERA / Dubai Law 85 of 2006Brokerage must disclose registered name (and BRN on request).Company name enforced in the identity section. ORN pulled from the workspace, said on request.
TDRA cadence rulesNo more than one call per owner per 20 hours across all campaigns.`claim_due_calls()` SQL function joins across campaigns before releasing a number. Enforced at the row-lock level, not the app layer.
'Are you AI?' honestyDenying AI when asked is misrepresentation under UAE fair-dealing rules.Verbatim locked response: 'I am, I'm an AI assistant for {company}.' Compiler invariant INV-8. Cannot be edited or removed.

Enforcement

Four layers, one direction: down into SQL.

Layer

Database

Check constraints on campaigns, RLS by org_id, atomic `claim_due_calls` with FOR UPDATE SKIP LOCKED, suppression trigger.

Layer

Compiler

Locked prompt sections (recording notice, remove-me, are-you-AI, data-source) with test-enforced invariants. speakable=false knowledge (prices, rents, service charges) never reaches the voice provider.

Layer

Runtime

Every webhook signature verified on raw body. Every dial checked against calling window, DNCR, whitelist, and 20-hour cap in order.

Layer

Audit

Every state change written to audit log with actor, before/after, timestamp. Downloadable per campaign.