ADR-0057: Min-2-independent-source verification gate (gate, not score)
Status: Accepted Date: 2026-06-15 Supersedes: none Superseded by: none Deciders: Adrian (Soft4U), Claude Opus 4.8
Decision context:
- Latency: none — pure in-memory rule over the #37 model.
- Dependency surface: no new packages. Adds
verification_gate.py+ two result models. - Debuggability: each result carries
independent_sources,required,sources,blocking— a blocked attribute self-explains. - Reversibility: branch revert; additive (new module + models).
- Blast radius: additive;
compute_source_diversityscoring is untouched (complementary). - Alternative considered: raise the diversity score weight (rejected — a low score still passes; only a gate blocks).
Context
AMLR §6 mandates ≥2 independent verifications for high-importance attributes (UBO/subject identity). The
existing compute_source_diversity (confidence_engine.py:108) only scores diversity — a single-source
attribute passes silently with a lower score. There was no >= 2 enforcement.
Decision
Enforce a gate, not a score, over the #37 PersonVerificationProfile. verification_gate.py:
count_independent_sources— distinctsource, case-insensitive (two pulls from one provider count once).attribute_verification_status—verifiediff independent sources ≥min_independent(default 2), elseinsufficient_sourceswithblocking=True.evaluate_profile_gates— evaluates every GATED attribute; a gated-but-absent attribute is itself a blocking gap (zero sources). Exposesblocking_gaps/all_verifiedfor the approval-block rule (#36).min_independent+gated_attributesare configurable (AMLR-baseline defaults), pluggable into the risk-config/segment layer (ADR-0031) later.
Consequences
Positive
- Single-source UBO/identity is a blocking gap, not a quiet score deduction — AMLR multi-source mandate
enforced. #36 gets a ready
all_verified/blocking_gapssignal.
Negative
- Stricter: attributes with one source won't reach
verified(correct per AMLR).
Neutral
- Pure rule; wiring the gate into persisted verified-status + dashboard is incremental (pairs with #36).
Alternatives Considered
Alternative 1: Keep scoring, raise the diversity weight
Rejected — a low score still passes onward; the AMLR mandate is a hard minimum, which only a gate expresses.
Alternative 2: Count records, not distinct sources
Rejected — two pulls from the same provider are not two independent verifications; independence must be by distinct source.