Skip to main content

Compliance Layer — Epics & User Stories

Last updated: 2026-04-18 Story point scale: 1 (trivial) · 2 (small) · 3 (medium) · 5 (large) · 8 (XL) · 13 (epic-sized) For Jira import: see JIRA_IMPORT.csv in this directory — ready to upload via Jira's CSV import.


Summary

Epic IDEpic NameStoriesPoints
EP-CE-01Compliance Layer — Service Foundation413
EP-CE-02Compliance Layer — Rule Engine Core947
EP-CE-03Compliance Layer — Hold Queue & Manual Review516
EP-CE-04Compliance Layer — Rule & Blocklist Management API416
EP-CE-05Compliance Layer — Tenant Scoring & Risk Tiering314
EP-CE-06Compliance Layer — Reporting & Audit211
EP-CE-07Compliance Layer — Observability & Production Hardening516
EP-CE-08Compliance Layer — Async Pipeline Integration521
EP-CE-09Compliance Layer — Local LLM Platform421
EP-CE-10Compliance Layer — Tenant-Facing Web Portal Integration416
Total45191

EP-CE-01: Compliance Layer — Service Foundation

Description: Bootstrap the NestJS gRPC + HTTP service, database schema, mTLS, and baseline observability.


US-CE-001 — Scaffold NestJS application with dual transport

As a platform engineer, I want a NestJS app bootstrapped with gRPC (port 50052) and HTTP (port 3002) transports so that the Compliance Layer exposes both the evaluation API and the admin REST API.

Acceptance Criteria:

  • main.ts bootstraps both gRPC microservice and HTTP app
  • src/proto/compliance.proto matches SYNC_CONTRACT definition
  • TypeScript types generated from proto
  • grpcurl returns valid mock response from local service
  • ESLint + TypeScript compile with 0 errors

Story Points: 3 · Priority: High


US-CE-002 — Create compliance PostgreSQL schema and all tables via Prisma migrations

As a platform engineer, I want the full database schema defined as Prisma migrations so that the schema is reproducible across environments.

Acceptance Criteria:

  • Migration creates schema and all enum types
  • Partitioned tables (evaluation_log, score_history) have initial monthly partitions
  • RLS policies on hold_queue, evaluation_log, tenant_compliance_scores verified via integration test
  • Audit log immutability rules tested — UPDATE/DELETE silently discarded

Story Points: 5 · Priority: High


US-CE-003 — Implement mTLS for gRPC transport

As a security engineer, I want gRPC connections to require mutual TLS so that only sms-orchestrator can invoke EvaluateCompliance.

Acceptance Criteria:

  • gRPC server rejects connections without valid client certificate
  • Cert paths read from env vars TLS_CERT_PATH, TLS_KEY_PATH, TLS_CA_PATH
  • Local dev bypass via GRPC_TLS_ENABLED=false
  • Integration test verifies TLS rejection with self-signed cert

Story Points: 3 · Priority: High


US-CE-004 — Health, readiness, and metrics HTTP endpoints

As a platform engineer, I want /health, /ready, and /metrics endpoints so that Kubernetes probes and Prometheus scraping work correctly.

Acceptance Criteria:

  • GET /health returns 200 without dependency checks
  • GET /ready returns 200 when PostgreSQL + Redis + NATS reachable; 503 otherwise
  • GET /metrics returns valid Prometheus text format
  • Kubernetes liveness/readiness probes pass in staging

Story Points: 2 · Priority: High


EP-CE-02: Compliance Layer — Rule Engine Core

Description: Implement all 10 rule type evaluators, rule loading/caching, and the EvaluateCompliance gRPC handler.


US-CE-005 — Implement KEYWORD rule evaluator with in-memory keyword sets

As a compliance engineer, I want KEYWORD rules to match keyword lists against message bodies.

Acceptance Criteria:

  • Keyword lists loaded into process memory at startup, refreshed every 5 min
  • Case-insensitive by default; caseSensitive flag supported
  • Multi-language (English, Dari/Farsi, Pashto seed lists)
  • matchAll flag — require all vs any keyword
  • Returns evidence field with redacted match preview
  • 15+ unit tests

Story Points: 5 · Priority: High


US-CE-006 — Implement REGEX rule evaluator with ReDoS protection

As a security engineer, I want REGEX rules evaluated with a linear-time engine so malicious patterns cannot DoS.

Acceptance Criteria:

  • Uses re2 (or equivalent linear-time engine)
  • Regex validated at save time; invalid or oversized patterns rejected (max 500 chars)
  • Hard 10 ms timeout per regex evaluation
  • negate flag inverts result
  • 15+ unit tests including known ReDoS patterns

Story Points: 5 · Priority: High


US-CE-007 — Implement AI_CLASSIFICATION rule evaluator with caching

As a compliance engineer, I want AI-powered content classification so sophisticated spam, phishing, and fraud can be detected.

Acceptance Criteria:

  • LLM provider abstraction (LocalLLMClient / ClaudeClient / OpenAIClient / MockClient)
  • Provider selection via AI_PROVIDER env; default local
  • Body anonymisation pre-processor when ANONYMIZE_BODY_BEFORE_AI=true
  • Redis cache with 24 h TTL keyed by {modelVersion}:{sha256(anonymisedBody)}
  • Categories returned as confidence scores 0.0–1.0
  • minConfidence threshold check
  • fallbackAction applied when LLM unavailable (default HOLD — fail-closed)
  • Circuit breaker on LLM client
  • Per-provider latency and error metrics
  • 10+ unit tests with mocked LLM client

Story Points: 8 · Priority: High


US-CE-008 — Implement RATE_VOLUME rule with Redis sliding window

As a platform engineer, I want RATE_VOLUME rules to enforce per-account/sender/recipient frequency thresholds.

Acceptance Criteria:

  • Redis sorted-set sliding window (ZADD + ZCOUNT)
  • Configurable windowSeconds, maxMessages, scope
  • Independent counters per scope
  • Graceful degradation to HOLD when Redis unavailable (fail-closed)
  • 10+ unit tests

Story Points: 5 · Priority: High


US-CE-009 — Implement DLR_ABUSE rule with sliding-window stats

As a compliance engineer, I want DLR_ABUSE rules to detect tenants with high DLR failure rates.

Acceptance Criteria:

  • NATS consumer for sms.dlr.inbound maintains compliance.dlr_stats
  • Three window types: 1h, 24h, 7d
  • Rule evaluates against latest window with minSampleSize guard
  • failureRateThreshold comparison
  • 10+ unit tests

Story Points: 5 · Priority: Medium


US-CE-010 — Implement GEO_RESTRICTION and TEMPORAL rule evaluators

As a platform engineer, I want GEO and TEMPORAL rules to restrict messages by destination country and time-of-day.

Acceptance Criteria:

  • GEO: longest-prefix match to ISO 3166-1 country code
  • GEO: ALLOW_ONLY and BLOCK modes
  • TEMPORAL: evaluation in configured IANA timezone
  • TEMPORAL: allowedHours, allowedDaysOfWeek
  • 15+ unit tests across both types

Story Points: 3 · Priority: Medium


US-CE-011 — Implement SENDER_ID and RECIPIENT rule evaluators

As a compliance engineer, I want rules for sender ID patterns and recipient-specific checks.

Acceptance Criteria:

  • SENDER_ID: whitelist, blacklist, regex pattern matching
  • RECIPIENT: exact/prefix/regex blocklist matching
  • Blocklists loaded from compliance.blocklist_entries with Redis cache
  • 10+ unit tests

Story Points: 3 · Priority: High


US-CE-012 — Implement COMPOSITE rule evaluator with cycle detection

As a compliance engineer, I want COMPOSITE rules that combine other rules with AND/OR/NOT logic.

Acceptance Criteria:

  • AND / OR / NOT operators
  • Max depth 5 enforced at eval time
  • Cycle detection at save time (422)
  • Runtime visited: Set<ruleId> prevents infinite loops
  • 10+ unit tests including cycle cases

Story Points: 5 · Priority: Medium


US-CE-013 — Implement full EvaluateCompliance gRPC handler

As sms-orchestrator NATS consumer, I want to call EvaluateCompliance and receive a verdict within 500 ms P95.

Acceptance Criteria:

  • Input validation with gRPC INVALID_ARGUMENT on malformed fields
  • Evaluation result dedup cache (5 min, fingerprint-keyed)
  • Tenant risk state loaded from Redis cache
  • Rule set loaded from Redis cache (300 s TTL); DB fallback
  • ALLOW rules evaluated first (whitelist fast-path)
  • SUSPENDED tenant → auto-HOLD
  • BLOCK/HOLD/FLAG rules evaluated in priority order
  • Budget enforcement (450 ms internal cap)
  • Async side-effects (eval log write, hold queue insert, NATS publish)
  • P95 latency ≤ 500 ms verified via ghz load test at 200 RPS

Story Points: 8 · Priority: High


EP-CE-03: Compliance Layer — Hold Queue & Manual Review

Description: Hold queue lifecycle — insertion, review, release, rejection, auto-expiry — plus admin REST API.


US-CE-014 — Hold queue insertion with original payload preservation

As a compliance reviewer, I want held messages stored with full original payload so I can review and release them intact.

Acceptance Criteria:

  • hold_queue row inserted atomically with evaluation log row
  • payload JSONB contains full original message
  • review_priority computed per APPLICATION_LOGIC §3
  • auto_expires_at set to 24 h from creation
  • NATS compliance.message.held event published

Story Points: 3 · Priority: High


US-CE-015 — REST endpoints for hold queue listing and detail retrieval

As a platform admin, I want REST endpoints to list and inspect held messages.

Acceptance Criteria:

  • GET /compliance/hold-queue with pagination, filtering
  • GET /compliance/hold-queue/:holdId returns full record
  • Role-based body redaction (body visible only to platform.compliance.admin)
  • JWT validation + RBAC enforcement

Story Points: 3 · Priority: High


US-CE-016 — Review action (RELEASE / REJECT) with message re-injection

As a compliance reviewer, I want to release or reject held messages.

Acceptance Criteria:

  • POST /compliance/hold-queue/:holdId/review with action: RELEASE | REJECT
  • RELEASE: publishes sms.outbound.retry with skipCompliance: true; sms-orchestrator routes without re-evaluation
  • REJECT: status → REVIEWED_REJECTED; sms_messages → BLOCKED (terminal)
  • Audit log entry with before/after, actor, IP, UA
  • Optimistic lock prevents double-review
  • NATS compliance.message.released / rejected event published

Story Points: 5 · Priority: High


US-CE-017 — Hold queue auto-expiry background worker

As a platform SRE, I want held messages past TTL auto-expired so the queue cannot grow unbounded.

Acceptance Criteria:

  • Cron runs every 5 min with Redis distributed lock
  • Selects PENDING holds where auto_expires_at <= now()
  • Updates status to AUTO_EXPIRED
  • sms_messages state → AUTO_EXPIRED (terminal)
  • Publishes compliance.message.expired NATS event (notification-service alerts tenant)
  • Writes audit log entry
  • Emits metric

Story Points: 2 · Priority: Medium


US-CE-018 — Bulk-review endpoint for platform admins

As a platform admin, I want to bulk-reject held messages filtered by tenant/rule so I can clear the queue during mass-abuse incidents.

Acceptance Criteria:

  • POST /compliance/hold-queue/bulk-review with filter + action
  • Hard limit 10,000 rows per call
  • Single audit log entry summarising bulk action
  • Role gated to platform.compliance.admin

Story Points: 3 · Priority: Medium


EP-CE-04: Compliance Layer — Rule & Blocklist Management API

Description: CRUD APIs for platform admins to author rules, manage rule sets, and maintain blocklists/keyword lists.


US-CE-019 — Rule CRUD endpoints with versioning

As a compliance admin, I want to create, update, and delete rules via REST.

Acceptance Criteria:

  • POST /compliance/rules with schema validation per rule type
  • PUT /compliance/rules/:id increments version, creates rule_versions snapshot
  • DELETE /compliance/rules/:id soft-delete only
  • COMPOSITE cycle check at save
  • REGEX validation at save (compile + ReDoS screen)
  • Redis cache invalidation on change
  • NATS compliance.rule.changed event published
  • Audit log entry per action

Story Points: 5 · Priority: High


US-CE-020 — Rule set management and tenant assignment

As a compliance admin, I want to group rules into rule sets and assign to tenants.

Acceptance Criteria:

  • Full CRUD on rule_sets
  • Exactly one is_default = true rule set (unique constraint)
  • Tenant assignment endpoint
  • Rule set loading merges tenant-specific + default

Story Points: 3 · Priority: High


US-CE-021 — Blocklist management (sender/recipient/keyword/regex/country)

As a compliance admin, I want to maintain blocklists for various entity types.

Acceptance Criteria:

  • CRUD endpoints for blocklists and blocklist_entries
  • Bulk-add endpoint (up to 10,000 entries per call)
  • Per-entry TTL support
  • Pattern types: EXACT, REGEX, PREFIX, CONTAINS, SUFFIX
  • Redis cache for fast lookup at evaluation time

Story Points: 5 · Priority: High


US-CE-022 — Keyword list management with multi-language support

As a compliance admin, I want to manage keyword lists per language and category.

Acceptance Criteria:

  • CRUD on keyword_lists and keyword_entries
  • Bulk import/export (CSV/JSON)
  • Language field (ISO 639-1)
  • Per-entry weight for weighted scoring
  • In-process cache reload on change

Story Points: 3 · Priority: High


EP-CE-05: Compliance Layer — Tenant Scoring & Risk Tiering

Description: Continuous tenant compliance scoring, risk tier transitions, enforcement.


US-CE-023 — Tenant scoring background worker

As a platform admin, I want tenant compliance scores computed every 15 min.

Acceptance Criteria:

  • Cron runs every 15 min with Redis distributed lock
  • Aggregates metrics from evaluation_log, dlr_stats
  • Computes 6 score dimensions per DOMAIN_MODEL §5
  • Determines risk tier from overall score
  • Detects tier transitions; emits compliance.tenant.tier.changed
  • Upserts tenant_compliance_scores; inserts score_history
  • Updates Redis tenant:risk:{tenantId} cache

Story Points: 8 · Priority: High


US-CE-024 — Tenant score REST endpoints

As a platform admin, I want REST endpoints for tenant ranking and score detail.

Acceptance Criteria:

  • GET /compliance/tenants returns ranked list
  • GET /compliance/tenants/:id/score returns detailed breakdown
  • GET /compliance/tenants/:id/score/history returns time-series
  • GET /compliance/tenants/:id/violations returns violation log

Story Points: 3 · Priority: Medium


US-CE-025 — Manual tenant tier override endpoint

As a platform admin, I want to manually override a tenant's risk tier.

Acceptance Criteria:

  • POST /compliance/tenants/:id/tier-override with tier + reason + optional expiry
  • Requires platform.compliance.admin
  • Writes audit log entry
  • Overrides recorded separately from scoring cycle
  • NATS event published

Story Points: 3 · Priority: Medium


EP-CE-06: Compliance Layer — Reporting & Audit


US-CE-026 — Compliance report generation

As a platform auditor, I want to generate compliance reports on demand or on schedule.

Acceptance Criteria:

  • POST /compliance/reports with report type + date range
  • Async generation with polling endpoint GET /compliance/reports/:id
  • Report types: TENANT_RANKING, VIOLATION_SUMMARY, HOLD_QUEUE_SUMMARY, TIER_TRANSITIONS, TOP_TRIGGERED_RULES, TENANT_AUDIT
  • Output: JSON, CSV (PDF future)
  • Daily scheduled generation at 02:00 UTC

Story Points: 8 · Priority: Medium


US-CE-027 — Audit log query endpoint

As a platform auditor, I want to query the audit log by actor, entity, date range.

Acceptance Criteria:

  • GET /compliance/audit-log with filters
  • Cursor-based pagination
  • Role-gated to platform.auditor and platform.compliance.admin
  • Read-only

Story Points: 3 · Priority: Medium


EP-CE-07: Compliance Layer — Observability & Production Hardening


US-CE-028 — Complete Prometheus metrics instrumentation

As a platform engineer, I want all metrics from OBSERVABILITY.md emitting correctly.

Acceptance Criteria:

  • All 30+ metrics registered and emitting
  • Histogram buckets match the observability spec
  • Grafana dashboard compliance-engine.json committed
  • Verified in staging Prometheus scrape

Story Points: 5 · Priority: High


US-CE-029 — Structured JSON logging with PII masking

As a security engineer, I want all logs structured JSON with PII masked.

Acceptance Criteria:

  • All log output valid JSON (Pino)
  • to masked as +CCNNN***
  • Body never logged
  • traceId + spanId propagated from gRPC metadata
  • Log level via LOG_LEVEL env

Story Points: 2 · Priority: High


US-CE-030 — OpenTelemetry distributed tracing

As a platform engineer, I want compliance evaluations to produce OTel traces.

Acceptance Criteria:

  • Parent span compliance-engine.EvaluateCompliance
  • Child spans for cache check, rule load, rules evaluate, AI classify, hold insert
  • Trace context via W3C Trace Context
  • Traces visible in staging tracing backend

Story Points: 3 · Priority: Medium


US-CE-031 — Alert rules and runbook

As a platform SRE, I want alerts configured for key failure modes with a runbook.

Acceptance Criteria:

  • All alerts from OBSERVABILITY.md configured in Alertmanager
  • Runbook entry per alert
  • Routing configured (Slack + PagerDuty for HIGH/CRITICAL)
  • Chaos test: induce each alert, verify paging

Story Points: 3 · Priority: High


US-CE-032 — Kubernetes deployment with HPA and rolling updates

As a platform SRE, I want compliance-engine deployed with 3+ replicas, HPA, zero-downtime rolling updates.

Acceptance Criteria:

  • Deployment min 3, HPA scales to 20
  • HPA on CPU + P95 latency custom metric
  • PodDisruptionBudget minAvailable = 2
  • NetworkPolicy restricts ingress/egress
  • Graceful shutdown (SIGTERM drains in-flight gRPC calls)
  • ghz load test during rolling update — zero dropped calls

Story Points: 3 · Priority: High


EP-CE-08: Compliance Layer — Async Pipeline Integration

Description: Integrate the Compliance Layer into the sms-orchestrator NATS consumer pipeline with fail-closed semantics.


US-CE-033 — sms-orchestrator ComplianceClient gRPC stub

As sms-orchestrator, I want a ComplianceClient module wrapping the Compliance Layer gRPC with retries, timeouts, mTLS.

Acceptance Criteria:

  • gRPC stub generated from compliance.proto
  • mTLS client certs loaded from mounted secrets
  • 1 s deadline per call
  • Structured logging of all calls with correlation IDs
  • Metrics: call duration, error rate

Story Points: 3 · Priority: High


US-CE-034 — sms-orchestrator NATS consumer compliance integration

As sms-orchestrator, I want the NATS consumer to call the Compliance Layer between dequeue and routing.

Acceptance Criteria:

  • Consumer updates message to EVALUATING before compliance call
  • On ALLOW / FLAG: proceed to routing
  • On BLOCK: update to BLOCKED; do not route
  • On HOLD: update to ON_HOLD with holdId; do not route
  • Fail-closed: on error/timeout, message is NOT acked; NATS redelivers
  • After max redeliveries, message moves to sms.outbound.deadletter
  • New sms_messages status values: EVALUATING, BLOCKED, ON_HOLD, AUTO_EXPIRED
  • Integration tests cover all four verdicts and fail-closed path

Story Points: 8 · Priority: High


US-CE-035 — sms-orchestrator release flow (skipCompliance flag)

As sms-orchestrator, I want to handle re-published released messages without re-evaluating compliance.

Acceptance Criteria:

  • sms.outbound.retry messages with skipCompliance: true bypass compliance
  • Routing proceeds directly
  • complianceOverride recorded in message metadata and audit trail
  • Prevents release → re-hold loop

Story Points: 3 · Priority: High


US-CE-036 — billing-service integration with compliance verdicts

As billing-service, I want to skip billing for blocked/rejected messages and defer billing for held messages.

Acceptance Criteria:

  • Consumes compliance.message.blocked — emits billing.waive for messageId
  • Consumes compliance.message.rejected — same as above
  • Consumes compliance.message.expired — same as above
  • Consumes compliance.message.released — bills normally on subsequent DLR
  • Idempotent handling

Story Points: 5 · Priority: Medium


US-CE-037 — Phase 1 observation-mode rollout

As a platform engineer, I want the initial production rollout to use observation-only rules so that we validate the layer without affecting traffic.

Acceptance Criteria:

  • Seed rule set configured with all rules action=FLAG
  • 7-day observation window executed in production
  • Trust & Safety signs off on rule-tuning report
  • Exit criteria (P95 latency, error rate, consumer lag) met

Story Points: 2 · Priority: High


EP-CE-09: Compliance Layer — Local LLM Platform

Description: Provision and operate the self-hosted local LLM service that powers AI_CLASSIFICATION rules.


US-CE-038 — Deploy local LLM service with vLLM + Llama-3.1-8B-AWQ

As a platform engineer, I want a self-hosted LLM service deployed on GPU nodes with an OpenAI-compatible API.

Acceptance Criteria:

  • vLLM deployment manifest with GPU node selector
  • Model: Llama-3.1-8B-Instruct-AWQ (or equivalent)
  • OpenAI-compatible API on port 8000
  • 2 replicas minimum with PDB minAvailable = 1
  • Liveness/readiness probes
  • Service reachable from compliance-engine pods only (NetworkPolicy)

Story Points: 5 · Priority: High


US-CE-039 — Provider abstraction for LLMs (local + external failover)

As a compliance engineer, I want a provider-abstracted LLM client so the Compliance Layer can swap between local and external LLMs.

Acceptance Criteria:

  • LLMClient interface
  • LocalLLMClient, ClaudeClient, OpenAIClient, MockClient implementations
  • LLMRouter with primary + failover chain based on env config
  • Circuit breaker per provider
  • Grammar-constrained decoding for local LLM (guaranteed JSON output)
  • Unit tests per client + router

Story Points: 5 · Priority: High


US-CE-040 — Local LLM cost and performance monitoring

As a platform engineer, I want metrics and dashboards for local LLM operations.

Acceptance Criteria:

  • GPU utilisation exported via DCGM exporter
  • LLM request/response latency histogram
  • Cache hit rate gauge (from compliance-engine side)
  • Token throughput metric
  • Grafana dashboard local-llm.json

Story Points: 3 · Priority: Medium


US-CE-041 — Classification accuracy evaluation harness

As a trust & safety engineer, I want an evaluation harness to measure classification accuracy against a labelled SMS dataset.

Acceptance Criteria:

  • Curated labelled dataset of ~1000 SMS bodies per category
  • Eval script computes precision, recall, F1 per category
  • Results stored and comparable across model versions
  • Quarterly re-run scheduled
  • Alert if any category precision drops > 5 pts month-over-month

Story Points: 8 · Priority: Medium


EP-CE-10: Compliance Layer — Tenant-Facing Web Portal Integration

Description: Surface compliance state to tenants via the customer web portal so they can see holds, blocks, and compliance status without relying on synchronous API responses.


US-CE-042 — Display message states BLOCKED / ON_HOLD / AUTO_EXPIRED in portal

As a tenant, I want to see which of my messages were blocked, held, or expired so I know why they were not delivered.

Acceptance Criteria:

  • Message list in portal shows new states
  • Filter by compliance state
  • Per-message detail view shows triggered rule(s) and rationale
  • payload.body not revealed — only redacted summary
  • State changes update in near-real-time via WebSocket or polling

Story Points: 5 · Priority: High


US-CE-043 — In-portal notifications for compliance events

As a tenant, I want to receive notifications when my messages are held, blocked, or my tenant tier changes.

Acceptance Criteria:

  • notification-service consumes compliance.message.* and compliance.tenant.tier.changed events
  • Notification delivered to portal notification centre
  • Optional email notification (configurable per tenant)
  • Notification links to affected message / tenant settings

Story Points: 5 · Priority: High


US-CE-044 — Tenant-visible compliance score and tier

As a tenant admin, I want to see my compliance score and risk tier so I understand my standing on the platform.

Acceptance Criteria:

  • GET /portal/compliance/score (tenant-scoped) returns own score + tier
  • Score history chart (last 30 days)
  • Explanation of tier implications (e.g. "RESTRICTED: bulk sends > 500/hr are held")
  • Guidance copy: "How to improve your score"

Story Points: 3 · Priority: Medium


US-CE-045 — Appeal / dispute submission for blocked or held messages

As a tenant, I want to appeal a block/hold decision so I can request human review of a disputed case.

Acceptance Criteria:

  • Appeal button on blocked/held message detail view
  • Appeal form captures reason and context
  • Appeal creates a support ticket tagged compliance-appeal
  • Platform compliance team SLA: initial response within 1 business day
  • Tenant sees appeal status in portal

Story Points: 3 · Priority: Medium


EP-CE-11 · National Default Rule-Sets (regulator-required)

Context: ATRA and the broader Afghan regulatory environment require certain rules apply to every tenant by default (no opt-out): national keyword blocklist, marketing quiet windows (e.g., 22:00–06:00 Asia/Kabul), restricted sender-IDs, and certain temporal restrictions during religious or national observances. These must ship as a national_defaults rule-set that is non-disable-able and version-controlled.

US-CE-046 · National default rule-set (non-disable-able)

Type: Feature | Points: 5

Description: As a compliance officer, I need a national_defaults rule-set that is automatically merged into every tenant's evaluation context with non_disable=true so that no tenant can bypass national rules even via admin override.

Acceptance Criteria:

  • Rule-set national_defaults seeded at first migration; version-tracked
  • Cannot be soft-deleted; cannot be excluded from any tenant assignment
  • Admin UI shows rules read-only with "Cannot disable — national mandate"
  • Schema field compliance.rule_sets.is_national_default boolean enforces single national-default row

US-CE-047 · National keyword blocklist (Pashto/Dari/English)

Type: Feature | Points: 5

Description: As a compliance officer, I need a curated national-keyword blocklist covering hate speech, anti-state content, weapons trafficking terms, and known scam keywords across Pashto, Dari, and English so that the platform is regulator-defensible.

Acceptance Criteria:

  • Initial seed: ≥ 200 keywords per language, classified by category (HATE, EXTREMISM, WEAPONS, FRAUD)
  • Per-keyword: language, category, severity (BLOCK/HOLD/FLAG), regulator reference (ATRA letter ID)
  • Updates require dual-control approval (compliance lead + legal)
  • Quarterly review cron creates ticket for compliance team

US-CE-048 · Marketing quiet windows (national time-of-day rules)

Type: Feature | Points: 3

Description: As a compliance officer, I need national TEMPORAL rules that block lane=P3 marketing traffic during 22:00–06:00 Asia/Kabul on standard days, plus configurable extra quiet windows for religious/national days.

Acceptance Criteria:

  • TEMPORAL rule pre-loaded; lane=P3 only; timezone Asia/Kabul
  • compliance.national_calendar table for special days (Ramadan night quiet, Independence Day, etc.)
  • Calendar maintained yearly by compliance team
  • Verdict for matching messages: HOLD with auto-release at next allowed window

US-CE-049 · Restricted-sender-ID enforcement

Type: Feature | Points: 3

Description: As a compliance officer, I need a SENDER_ID rule that blocks any message using sender-IDs from the national restricted list (impersonation of government, banks, MNOs).

Acceptance Criteria:

  • Rule consumes sender-id-registry-service restricted-set (cached 5 min)
  • Verdict: BLOCK with reason RESTRICTED_SENDER_ID
  • Tenant can request exception (KYC + regulator letter required) via sender-id-registry workflow
  • Audit log entry includes restricted sender-ID category

US-CE-050 · National rule-set version control + change broadcast

Type: Feature | Points: 3

Description: As an auditor, I need the national rule-set versioned with regulatory references so I can answer "what rules were in force on date X".

Acceptance Criteria:

  • Each rule-set version stored in compliance.rule_set_versions with snapshot, regulator ref, effective date
  • On change, compliance.national_rules.changed.v1 event published; consumed by notification-service to email all tenants
  • Audit query: "rules in effect at timestamp T" returns the snapshot

EP-CE-12 · External-LLM Hard Default-Off + Per-Tenant Opt-In with DPIA Acknowledgement

Context: Per ADR-0004 and SCT-001, sending message bodies to external LLMs (cloud APIs) for AI classification is a sovereignty/PII risk. Default behaviour must be on-prem-only; external LLM is opt-in per tenant with explicit DPIA acknowledgement.

US-CE-051 · External LLM default-off enforcement

Type: Feature | Points: 3

Description: As a security engineer, I need the AI classification provider to default to local for every tenant; external LLM access requires explicit feature flag + tenant opt-in.

Acceptance Criteria:

  • Default AI_PROVIDER=local cannot be overridden by env alone
  • Per-tenant compliance.tenant_ai_config.allow_external_llm = false default
  • Local LLM unavailable → fail-closed HOLD (do NOT silently fail-over to external)
  • Migration: existing tenants set to false regardless of prior config

US-CE-052 · Per-tenant DPIA acknowledgement and opt-in

Type: Feature | Points: 5

Description: As a tenant admin, I want to opt-in to external LLM classification only after acknowledging a DPIA (Data Protection Impact Assessment) document.

Acceptance Criteria:

  • Customer-portal page /compliance/ai-providers shows current provider + DPIA toggle
  • Toggle to external requires uploading signed DPIA acknowledgement PDF (template provided)
  • Audit event compliance.tenant_ai.optin.v1 includes signer, IP, timestamp, DPIA hash
  • Opt-in expires after 12 months; renewal required

US-CE-053 · External LLM call audit and PII tokenisation

Type: Feature | Points: 5

Description: Every external LLM call must be audit-logged with the (tokenised) payload sent, model used, and latency. PII must be tokenised before transmission.

Acceptance Criteria:

  • Pre-send: PII fields tokenised via FF1 (HSM-held key); to, sender names replaced with stable tokens
  • Audit row in compliance.external_llm_audit with model, tokenised body, latency, verdict
  • Daily report to compliance team summarising volume per tenant, per model
  • Alert if any PII detected in outbound payload (regex check) → emergency disable + page security

EP-CE-13 · Trusted-Tenant Template Approval Workflow

Context: Pairs with EP-PLAT-NB-08 (trusted-tenant fast-path) and EP-ORCH-07. Trusted tenants pre-register templates; compliance reviewers approve them once; orchestrator then verifies fingerprint at submit and short-circuits compliance.

US-CE-054 · Template registration API

Type: Feature | Points: 5

Description: As a trusted tenant admin, I need to register a template with a fingerprint pattern and variable schema.

Acceptance Criteria:

  • POST /v1/compliance/templates accepts { name, body, variableSchema, lane }
  • System computes fingerprint_pattern (regex with variable spans masked)
  • Stores in compliance.approved_templates with status PENDING
  • Cannot be used by orchestrator until status = APPROVED

US-CE-055 · Template approval workflow (compliance reviewer)

Type: Feature | Points: 5

Description: A compliance reviewer must approve, reject, or request-info on a template before it becomes usable.

Acceptance Criteria:

  • Admin UI lists pending templates per tenant with risk score (rule-engine pre-evaluates a sample render)
  • APPROVE / REJECT / REQUEST_INFO actions; reason mandatory
  • APPROVED → emit compliance.template.approved.v1; orchestrator can use it
  • Approval expires after 12 months; re-approval required

US-CE-056 · Template tenant grant (multi-tenant template sharing)

Type: Feature | Points: 3

Description: A platform-owned template (e.g., government emergency template) can be granted to multiple tenants without per-tenant re-approval.

Acceptance Criteria:

  • compliance.template_tenant_grants (templateId, tenantId, grantedBy, expiresAt)
  • Grant requires platform-admin role
  • Revocation propagates to orchestrator within 30 s

US-CE-057 · Template drift monitoring (1-in-1000 sample)

Type: Feature | Points: 3

Description: 1-in-1000 fast-path messages are re-evaluated in blocking mode; if verdict ≠ ALLOW, alert fires and template is auto-suspended.

Acceptance Criteria:

  • Sampling deterministic (hash of messageId mod 1000 == 0)
  • Drift verdict logged in compliance.template_drift_audit
  • If drift rate > 0.5% over 1h → template auto-suspended; tenant notified
  • Alert ComplianceFastpathDrift paged to T&S team