Skip to main content

consent-ledger-service — Migration Plan

Version: 1.0 Status: Draft Owner: Trust and Safety + Platform Engineering Last Updated: 2026-04-21 References: SERVICE_OVERVIEW.md, _report.md, SERVICE_READINESS.md

This document describes how existing tenants, legacy opt-in data, and the platform itself migrate into consent-ledger-service. The service is greenfield — there is no predecessor to replace — but the national-backbone go-live introduces a significant behavioural change: consent becomes an enforced gate rather than a recommendation. That change must be staged to avoid national-scale disruption.


1. What Is Migrating

InputSourceVolume (estimate)Notes
Existing tenant opt-in listsTenant legacy systems (CSV, DB exports)5 – 50 M records across early adoptersBulk-imported via US-CONS-018; audit tags source.type = "BULK_IMPORT"
STOP history (opt-outs)Tenant legacy systems (if available)Partial; many tenants do not retain thisWhere available, imported as consent.records.status = OPT_OUT
National DND listATRA (primary), failing that Ghasi-seeded from platform STOP events~10 M MSISDNs (upper bound)Sync worker US-CONS-001; adapter pattern
Tenant STOP-keyword customisationsTenant product teams, through platform onboarding~20 per tenant tierAdmin-console (US-CONS-009)
Approved scope definitions (per tenant)Platform product team4 defaults + tenant-specific extensionsSeeded at onboarding

Not migrating: there is no external opt-in database of national scope in Afghanistan to adopt. All input comes from tenants.


2. Migration Phases

Phase 0 — Pre-migration (Weeks -4 to 0)

StepOwnerOutput
Tenant onboarding CSV template publishedDevRelTemplate + validator
Legal review of bulk-import consent provenanceLegalPer-tenant attestation form
Pilot tenant selected (target: 1 bank, 1 ministry, 1 e-commerce)ProductMoU signed
Service deployed to stagingSREStaging environment green

Phase 1 — Shadow Mode (14 days)

StepOwnerOutput
CheckConsent returns allowed=true for all requestsServiceZero enforcement; full audit
Per-message audit row captures the hypothetical verdict (what it would have been if enforced)ServiceShadow verdict distribution
Daily report compares shadow-verdict-blocks vs. real trafficTrust & SafetyFalse-positive-rate projection
Regulator Liaison review if projection > 2%Regulator LiaisonGo/no-go for Phase 2

Exit criteria: projected FP rate < 1%; 14 consecutive days of metrics parity; no critical bugs in verifier.

Phase 2 — Enforcement: MARKETING scope only (7 days)

StepOwnerOutput
consent.policy.enforcement.marketing = trueSREEnforcement live for marketing scope
TRANSACTIONAL / OTP / EMERGENCY scopes remain shadowServiceHot paths unaffected
Tenant-portal banners explaining enforcement liveFrontendTenant awareness
Daily tenant-impact reportTrust & SafetyEscalation triage

Exit criteria: < 10 tenant escalations per day; no OTP/transactional regression.

Phase 3 — Full Enforcement (ongoing)

StepOwnerOutput
All scopes enforcedSREFull national consent gate
Citizen-portal live (/consent/{msisdn})FrontendSelf-service consent inspection
STOP-keyword processor live on all inbound MOServiceReal-time revocation
ATRA National DND sync active (if available)ServiceNational DND honoured
Post-launch review at +30 dPlatformLessons learned

Rollback at any phase. Feature flags:

  • CONSENT_ENFORCEMENT_MARKETING — toggle Phase 2.
  • CONSENT_ENFORCEMENT_ALL — toggle Phase 3.
  • Reverting to false restores previous behaviour (implicit last-mile veto via routing-engine).

3. Bulk-Import Workflow for Existing Tenant Data

3.1 Input format (CSV, UTF-8)

msisdn,scope,source_type,source_ref,captured_at,notes
+93701234567,MARKETING,WEB_FORM,www.bank.af/signup,2024-11-01T09:00:00Z,"Double opt-in completed"
+93701234568,TRANSACTIONAL,ACCOUNT_CREATION,bank-crm-id-4857,2024-11-02T10:00:00Z,

3.2 Validation

RuleAction on failure
MSISDN is valid E.164Row rejected, logged to tenant report
scope is in enumRow rejected
source_type is in enum {WEB_FORM, DOUBLE_OPT_IN, ACCOUNT_CREATION, BULK_IMPORT_LEGACY, OTHER}Row rejected
captured_at is ISO 8601 and not in the futureRow rejected
National DND matchRow marked OPT_OUT (defensive)
Duplicate within same fileRow deduplicated (latest wins)

3.3 Import steps (tenant-self-service via customer portal or admin API)

  1. Tenant uploads CSV (max 10 M rows per file; larger split by platform admin).
  2. File stored in s3://ghasi-consent-imports/{tenantId}/{importId}/{uploadedAt}.csv; SHA-256 hash recorded.
  3. Background job validates + inserts; progress polled via GET /v1/consent/bulk-import/:importId.
  4. Report generated: accepted count, rejected count, per-reason breakdown, sample rejected rows.
  5. Tenant reviews report, optionally re-uploads corrected file.
  6. On approval (tenant + Trust & Safety dual-sign for > 1 M rows), rows are committed.
  7. consent.granted.v1 batch-published (up to 10 000 per NATS message).
  8. Audit rows include source.type = "BULK_IMPORT" and reference to the CSV hash.

3.4 Post-import tenant attestation

Tenant digitally signs an attestation form (stored in consent.tenant_attestations) stating:

"All opt-in records bulk-imported under {importId} were obtained through a lawful consent mechanism consistent with Afghan law and our privacy policy. We accept liability for any complaints stemming from invalid consent claims."

This shifts legal risk to the tenant and is required before Phase 2 enforcement begins.


4. Cross-Region Bootstrap

Because consent.records is control-plane data replicated multi-master (ADR-0004 §14):

  1. Initial write happens in the tenant's home region.
  2. Logical replication mirrors to peer region within 60 s.
  3. Bulk-imports execute in the home region only; peer region observes via replication.
  4. Reconciliation cron hourly verifies row-count parity; divergence > 0.01% triggers alert.

5. National DND Bootstrap

Two-path strategy depending on ATRA readiness:

5.1 Path A — ATRA publishes a DND registry

  • Sync worker pulls daily per US-CONS-001.
  • First full sync on Day 0 populates consent.dnd_registry.
  • Subsequent daily deltas.

5.2 Path B — ATRA has no registry at launch

  • Ghasi seeds a de-facto National DND from platform-wide STOP events over 30 days (aggregated from consent.revoked.v1).
  • consent.dnd_registry populated as source = "GHASI_SEED".
  • When ATRA delivers their registry, merge strategy: ATRA rows are authoritative; Ghasi-seed rows remain if not contradicted.
  • Ghasi offers the seed to ATRA for ratification.

6. Downstream Consumer Migration

ConsumerChangeTiming
compliance-engineNew CONSENT rule type (EP-CE-14) enabled per tenantPhase 2
routing-engineLast-mile veto now delegates to consent-ledger-servicePhase 2
sms-firewall-serviceInbound/transit MT consult CheckConsentPhase 2
channel-router-serviceSTOP MO emission to sms.mo.inbound NATS subject formalisedPhase 0
regulator-portal-serviceconsent.* SIEM stream activatedPhase 3
admin-dashboardConsent admin + STOP-keyword catalog UIPhase 0
customer-portalTenant consent admin + opt-in history visualisationPhase 2

7. Rollback Plan

7.1 During Phase 1 (Shadow)

  • Action: feature-flag CONSENT_SHADOW_ENABLED = false.
  • Effect: no consent records written; audit stops.
  • Data loss: none.

7.2 During Phase 2 (Marketing enforcement)

  • Action: CONSENT_ENFORCEMENT_MARKETING = false.
  • Effect: enforcement reverts; audit continues.
  • Tenant impact: reverts to previous (implicit) behaviour.
  • Data loss: none.

7.3 During Phase 3 (Full enforcement)

  • Action: CONSENT_ENFORCEMENT_ALL = false AND CONSENT_ENFORCEMENT_MARKETING = false.
  • Effect: all scopes shadow.
  • Tenant impact: consent gate off platform-wide; regulator exposure until re-enabled.
  • Data loss: none.

7.4 Catastrophic (schema / chain corruption)

  • Action: fall back to last-known-good Postgres backup (hourly) and replay consent.* events from NATS (7-day retention).
  • Tenant impact: possible < 1 h consent-state gap.
  • Escalation: CTO + CISO + Regulator Liaison triad.

8. Success Metrics for Migration

MetricTargetMeasurement
Tenants with ≥ 1 consent record by Phase 2 exit≥ 95% of active tenantsDaily count
Bulk-import CSV accept rate≥ 98% of submitted rowsImport reports
Tenant escalations per day (Phase 2)< 10Zendesk tag consent-escalation
Hash-chain integrity breaks0Daily verifier
Phase-transition duration vs. plan±3 daysProject tracker
Post-launch consent-revocation rate at +30 d< 1% of active consentsconsent.revoked.v1 rate

9. Dependencies for Migration

  • ATRA relationship (for DND Path A) — owned by Regulator Liaison.
  • HSM provisioned for erasure tokenisation — owned by Security (ADR-0004 §11).
  • Multi-region logical replication configured — owned by SRE (ADR-0004 §14).
  • Design-partner tenants identified and onboarded — owned by Product.
  • Legal sign-off on tenant attestation form — owned by Legal.

Without any of these, migration is blocked at the phase in which it is first required (called out in the phase tables above).