FCA Consumer Duty Compliance¶
The FCA Consumer Duty (effective July 2023) requires firms to deliver good outcomes for retail customers. This applies to all AI systems that interact with or affect customer outcomes.
Executive Summary¶
The Consumer Duty¶
The FCA Consumer Duty establishes:
- Consumer Principle - Act to deliver good outcomes for retail customers
- Cross-cutting Rules - Act in good faith, avoid foreseeable harm, enable pursuit of financial objectives
- Four Outcomes - Products/services, price/value, consumer understanding, consumer support
OxideShield Coverage¶
| FCA Requirement | OxideShield Feature | Coverage |
|---|---|---|
| Act in good faith | DarkPatternGuard | ✅ 95% |
| Avoid foreseeable harm | Wellbeing guards | ✅ 90% |
| Support customer understanding | Explainability | ⚠️ 70% |
| Vulnerability identification | PsychologicalSafetyGuard | ✅ 95% |
| Fair value | Under development | ❌ Gap |
Consumer Duty Outcomes¶
Outcome 1: Products & Services¶
Products and services must be designed to meet customer needs.
| Requirement | OxideShield Feature | Implementation |
|---|---|---|
| Appropriate for target market | Policy engine | Use case restrictions |
| No harmful features | DarkPatternGuard | Manipulation detection |
| Ongoing monitoring | Telemetry | Performance metrics |
Implementation:
# Ensure AI products are appropriate for target market
policy:
name: retail-investment-ai
target_market:
sophistication: retail
age_range: 18+
risk_tolerance: low-medium
guards:
- name: suitability
type: PatternGuard
config:
patterns:
- "high risk"
- "speculative"
- "leveraged"
action: block
reason: "Not suitable for retail investors"
- name: dark_patterns
type: DarkPatternGuard
config:
categories: all
action: block
Outcome 2: Price & Value¶
Customers must receive fair value.
| Requirement | OxideShield Feature | Status |
|---|---|---|
| Fair pricing | Not implemented | ❌ Gap |
| Value communication | Explainability | ⚠️ Partial |
| No hidden costs | PatternGuard | ✅ |
Current Implementation:
from oxideshield import pattern_guard
# Detect hidden costs or misleading pricing
value_guard = pattern_guard(
name="fair-value",
patterns=[
# Hidden costs
"additional fees may apply",
"subject to charges",
"minimum investment required",
# Misleading value
"guaranteed returns",
"risk-free",
"no fees ever",
],
action="review"
)
Outcome 3: Consumer Understanding¶
Customers must be given information they can understand.
| Requirement | OxideShield Feature | Status |
|---|---|---|
| Clear communication | ToxicityGuard | ✅ |
| Jargon detection | PatternGuard | ✅ |
| Risk warnings | Policy engine | ✅ |
| Explanation of AI | AutonomyGuard | ✅ |
Implementation:
from oxideshield import pattern_guard, toxicity_guard
class ConsumerUnderstandingPipeline:
"""Ensure AI communications are understandable."""
def __init__(self):
# Detect jargon and complexity
self.jargon_guard = pattern_guard(
patterns=[
"basis points",
"derivative exposure",
"counterparty risk",
"collateralized",
],
action="flag"
)
# Detect confusing or misleading content
self.clarity_guard = toxicity_guard(
categories=["misleading"]
)
def validate_response(self, ai_response: str) -> dict:
"""Ensure response is understandable."""
# Check for jargon
jargon_result = self.jargon_guard.check(ai_response)
if jargon_result.detected:
return {
"action": "SIMPLIFY",
"jargon_found": jargon_result.patterns,
"suggestion": "Replace with plain English"
}
# Check for clarity
clarity_result = self.clarity_guard.check(ai_response)
if clarity_result.detected:
return {
"action": "REWRITE",
"reason": "potentially_misleading"
}
return {"action": "ALLOW"}
Outcome 4: Consumer Support¶
Customers must receive adequate support.
| Requirement | OxideShield Feature | Coverage |
|---|---|---|
| Vulnerability identification | PsychologicalSafetyGuard | ✅ 95% |
| Crisis support | Crisis resources | ✅ |
| Friction-free disengagement | AutonomyGuard | ✅ 95% |
| Human escalation | Alert system | ✅ |
| Accessibility | Under development | ❌ Gap |
Implementation:
from oxideshield import (
psychological_safety_guard,
autonomy_guard,
dependency_guard,
)
class VulnerableCustomerSupport:
"""FCA Consumer Duty vulnerable customer handling."""
VULNERABILITY_INDICATORS = [
"health", "financial_difficulty", "life_events", "capability"
]
def __init__(self):
self.psych = psychological_safety_guard()
self.autonomy = autonomy_guard()
self.dependency = dependency_guard("session")
def assess_customer(self, customer_message: str) -> dict:
"""Assess customer vulnerability for FCA purposes."""
# Check for crisis indicators
psych_result = self.psych.check_user_input(customer_message)
if psych_result.immediate_intervention:
return {
"vulnerability_level": "CRITICAL",
"action": "IMMEDIATE_HUMAN_HANDOFF",
"reason": psych_result.indicators,
"fca_requirement": "Consumer Support"
}
if psych_result.concerns_detected:
return {
"vulnerability_level": "HIGH",
"action": "SPECIALIST_SUPPORT",
"indicators": psych_result.indicators,
"recommended_team": "vulnerable_customer_team"
}
return {"vulnerability_level": "NORMAL"}
def validate_ai_response(self, ai_response: str) -> dict:
"""Ensure AI response supports vulnerable customers."""
# Check for autonomy violations
autonomy_result = self.autonomy.check_output(ai_response)
if autonomy_result.violations_detected:
return {
"approved": False,
"reason": "May not support customer effectively",
"violations": autonomy_result.violations
}
return {"approved": True}
Cross-Cutting Rules¶
Rule 1: Act in Good Faith¶
| Requirement | OxideShield Feature | Implementation |
|---|---|---|
| No manipulation | DarkPatternGuard | Full coverage |
| Honest communication | ToxicityGuard | Misleading detection |
| Fair treatment | AutonomyGuard | Agency protection |
from oxideshield import dark_pattern_guard
# Good faith compliance
good_faith_guard = dark_pattern_guard(
categories=[
"sycophancy", # Don't tell customers what they want to hear
"user_retention", # Don't manipulate to keep engagement
"sneaking", # Don't subtly alter meaning
],
action="block",
severity="critical"
)
Rule 2: Avoid Foreseeable Harm¶
| Requirement | OxideShield Feature | Implementation |
|---|---|---|
| Psychological harm | PsychologicalSafetyGuard | Crisis detection |
| Financial harm | PatternGuard | Misleading advice |
| Dependency harm | DependencyGuard | Engagement monitoring |
from oxideshield import (
psychological_safety_guard,
dependency_guard,
pattern_guard,
)
class ForeseeableHarmPrevention:
"""Prevent foreseeable harm per FCA rules."""
def __init__(self):
self.psych = psychological_safety_guard()
self.dependency = dependency_guard("session")
self.financial = pattern_guard(
patterns=[
"invest all your savings",
"borrow to invest",
"guaranteed returns",
"can't lose",
],
action="block"
)
def check_for_harm(self, message: str, is_ai: bool) -> dict:
"""Check for foreseeable harm indicators."""
harms = []
# Psychological harm
psych = self.psych.check_user_input(message) if not is_ai \
else self.psych.check_ai_output(message)
if psych.concerns_detected:
harms.append({"type": "psychological", "indicators": psych.indicators})
# Financial harm
if is_ai:
fin = self.financial.check(message)
if fin.detected:
harms.append({"type": "financial", "patterns": fin.patterns})
return {
"foreseeable_harm_detected": len(harms) > 0,
"harms": harms
}
Rule 3: Enable Pursuit of Financial Objectives¶
| Requirement | OxideShield Feature | Status |
|---|---|---|
| Support decision-making | AutonomyGuard | ✅ |
| Provide accurate info | ToxicityGuard | ✅ |
| Respect customer choices | AutonomyGuard | ✅ |
| Clear exit paths | AutonomyGuard | ✅ |
Vulnerability Framework¶
The FCA defines vulnerability across four drivers:
1. Health¶
Physical or mental health conditions affecting financial decisions.
# Health vulnerability detection
health_indicators = [
"chronic illness",
"mental health",
"cognitive impairment",
"addiction",
"disability",
]
2. Life Events¶
Major events impacting financial capability.
# Life event detection
life_event_indicators = [
"bereavement",
"divorce",
"job loss",
"retirement",
"caring responsibilities",
]
3. Resilience¶
Low ability to withstand financial shocks.
# Resilience indicators
resilience_indicators = [
"no savings",
"debt problems",
"low income",
"benefits dependent",
]
4. Capability¶
Low knowledge or confidence in financial matters.
# Capability indicators
capability_indicators = [
"don't understand",
"confused by",
"never done this before",
"not good with numbers",
]
Audit Trail for FCA¶
Consumer Duty Evidence¶
from oxideshield import ComplianceReporter
# Generate FCA Consumer Duty evidence package
reporter = ComplianceReporter(framework="fca_consumer_duty")
evidence = reporter.generate_evidence_package(
period="2025-Q1",
outcomes=[
"products_and_services",
"price_and_value",
"consumer_understanding",
"consumer_support",
],
include=[
"vulnerability_stats",
"harm_prevention_metrics",
"customer_outcome_tracking",
"complaint_analysis",
]
)
evidence.export("fca-consumer-duty-q1-2025.pdf")
Board Reporting¶
# Generate board report for Consumer Duty compliance
board_report = reporter.generate_board_report(
period="2025-Q1",
kpis=[
"vulnerability_identification_rate",
"harm_prevention_rate",
"customer_satisfaction",
"complaint_resolution_time",
]
)
References¶
- FCA Consumer Duty (FG22/5)
- Final guidance on the duty
-
https://www.fca.org.uk/publications/finalised-guidance/fg22-5-final-non-handbook-guidance-firms-consumer-duty
-
FCA Vulnerable Customer Guidance (FG21/1)
- Vulnerability framework
-
https://www.fca.org.uk/publications/finalised-guidance/guidance-firms-fair-treatment-vulnerable-customers
-
PS22/9 Consumer Duty Implementation
- Implementation requirements
- Board oversight expectations