Skip to main content

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_diversity scoring 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 — distinct source, case-insensitive (two pulls from one provider count once).
  • attribute_verification_statusverified iff independent sources ≥ min_independent (default 2), else insufficient_sources with blocking=True.
  • evaluate_profile_gates — evaluates every GATED attribute; a gated-but-absent attribute is itself a blocking gap (zero sources). Exposes blocking_gaps / all_verified for the approval-block rule (#36).
  • min_independent + gated_attributes are 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_gaps signal.

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.