PROOViD AML Docs
Transparency & defensibility

Decision rules — how a screen resolves to Pass / Review / Fail

This is the one authoritative page for the rules that turn a set of real watchlist matches into a final Pass / Review / Fail decision: the decision priority ladder, the full decision matrix, the named rules DM-1 / DM-2 / DM-3, the floors and policy modifiers layered on top, the Enhanced Due Diligence escalation, and every tenant knob. Nothing here is a black box — each rule is drawn straight from the decision engine. For the companion 0–100 risk score that bands a result, and a worked example you can reproduce with two curl calls, see Score & decision. Deeper engineering notes live in docs/decision-matrix.md, docs/decision-priority.md and docs/decision-criteria.md, which this page consolidates.

One rule governs everything: the STRONGEST outcome wins. A screen's decision is the highest-severity base decision across every real match — precedence is always Fail > Review > Pass (the Decision enum is ordered Pass = 0 < Review = 1 < Fail = 2). A subject is cleared to Pass only when every real match resolves to Pass. Adding more matches can only hold or raise the outcome, never soften it.

1 · Where a decision comes from — four layers

🔴 What changed on 2026-08-23. The owner re-answered four decisioning questions. The direction of travel is consistent: an automatic Fail is reserved for evidence that actually identifies the person, and everything short of that is routed to a human instead of being auto-blocked or auto-cleared.
#ChangeWasNow
Q5What name counts as "exact" — and therefore what may auto-blockscore ≥ 0.97100% identical after normalisation (1.00), tenant-configurable; enforced as a third structural invariant, a Fail requires an exact name (§3)
Q6Two full DoBs that differ but stay within tolerancefolded into the exact-DoB / no-DoB tiersa fifth tier, ExactNameDobNearMatch, Review in every category (§3)
Q4sanctions × exact name, no DoBFail (DM-1)the tenant's unconfirmed posture — Review by default (§4)
Q7adverse_media × exact name + exact DoBFail (DM-2)Review (§4)
Q3Which PEP classes EDD escalatesclass 4 onlya graduated ladder from the most sensitive class down to a tenant ceiling, default class 1 (§6)
Every softened cell remains a tenant override away from Fail — nothing here removes a tenant's ability to run the stricter posture. The two existing structural invariants (§3) are untouched; Q5 adds a third — a Fail requires an exact name — which is the one change a tenant override cannot reverse. A tenant that wants the previous blocking behaviour moves the bar (ExactNameSimilarity, §7), which is theirs to set, rather than overriding the invariant, which is not.

A decision is assembled in four ordered layers. The matrix owns only the base per-match decision; the aggregate, the floors, and the priority ladder sit on top of it.

1 · BaseEach real, enabled match → a matrix cell (category × tier × multiplicity), or its per-warning-type override → Pass / Review / Fail. Either way a Fail must clear the exact-name invariant (§3).
2 · AggregateThe strongest base decision across all matches (Fail > Review > Pass).
3 · Floors & policyPEP floor, unconfirmed-watchlist floor, band policy, EDD escalation.
4 · PrimaryThe priority ladder names the decisive match — presentation only, never the outcome.

2 · The decision priority ladder

When a subject matches several categories at once (say sanctions and PEP), the ladder decides which match is the primary (decisive) one — the headline "this is why". It never changes the outcome (that stays the strongest decision); it only names the primary factor. The shipped default order (highest → lowest), straight from the DecisionPriority enum:

RankPriorityMeaning
0SanctionsA sanctions-list hit — highest priority.
1CriminalA criminal / terrorism hit.
2ExportControlAn export-control-only listing (Taiwan SHTC, a Commerce row or a State export-control row of the US Consolidated Screening List). Keeps the sanctions outcome and codes; the reason says “export-control list”. A CSL row re-published from a Treasury (OFAC) list, or a State Department nonproliferation (ISN) row, stays Sanctions. Tenant token sanctions.export_control.
3PepTier1NationalClass 1 — National: heads of state/government, ministers, national parliaments, supreme courts, central-bank governors, senior armed forces/police/intelligence (most senior PEP class).
4PepTier2RegionalClass 2 — Regional: regional government and judiciary, senior international-organisation officials, ambassadors and consuls.
5PepTier3LocalAndEnterpriseClass 3 — Local and enterprise: SOE boards, public-sector directors, local/regional agency leaders.
6PepTier4LocalGovernmentAndAssociatesClass 4 — Local government and associates: mayors, local assemblies/courts, relatives and close associates.
7AdverseMediaAdverse media.
99UnmappedAny signal with no ladder slot — defensive catch-all.
  • Per-tenant reorderable. A tenant may supply its own order via RiskProfile.DecisionPriorityOrderJson. A partial order is completed automatically — the tenant's listed priorities first (in the order given, duplicates ignored), then every omitted priority in default order — so the ranking is always total and gap-free.
  • Outcome-neutral by construction. The priority resolver reads the same per-factor decision the aggregate used, so the named primary can never disagree with the decision.

3 · The decision matrix

Each real, enabled match gets a base decision from an explicit matrix addressed by three axes — category × evidence tier × multiplicity (single vs 2+ real matches).

What admits a match to the "exact" rows (Q5)

The bar for a name to count as exact is 100% identical to the watchlist name after normalisation — FuzzyNameScorer.ExactNameSimilarity = 1.00, per-tenant via RiskProfile.ExactNameSimilarity. Anything below that bar, however close, is an algorithmic variation and may not auto-block; it is routed to a human.

Tiering and blocking are two different questions, and the bar applies to the second one. Two of the five tiers — ExactNameExactDob and ExactNameDobMismatch — are reached on the date of birth alone, whatever the name scored. That is deliberate: a hit whose DoB contradicts the subject must still SURFACE for review even on a name that is not character-identical, and requiring an exact name to reach the mismatch tier would silently clear exactly that case. The ExactName… prefix on those two tier names is historical — it describes the date half. The 100%-identical bar is therefore applied after tiering, to the resolved decision, as the third structural invariant below: a Fail requires an exact name. Nothing stops surfacing; only automatic blocking is narrowed.
Why this is not the same as "score ≥ 0.97". The provider score is a COMBINED figure — name similarity plus date-of-birth and nationality corroboration, clamped to [0,1]. A name similarity of 0.96 lifted to 1.0 by a nationality agreement used to read as "exact" and auto-Fail on a name that was never identical. The exact bar is now measured on the name alone. The separate near-exact constant NearExactNameSimilarity = 0.97 is unchanged and still governs the other things it always did: whether a DoB mismatch surfaces (DobMismatchSurfacing), the rarity prior, and default retrieval options. A tenant that wants the historical behaviour sets ExactNameSimilarity to 0.97; the exact rows then admit near-exact names again, with no code change.

The five evidence tiers combine that name bar with the date-of-birth signal:

Evidence tierName required?Date of birth
ExactNameExactDobNo — date-drivenFull DoB agrees within DobYearTolerance — the confirmed tier.
ExactNameNoDobYes — 100% identicalNo corroborating full DoB on one or both sides.
ExactNameDobNearMatchYes — 100% identicalFull DoB on both sides, differing but within tolerance — close, not identical (Q6).
ExactNameDobMismatchNo — date-drivenFull DoB present on both sides but differs beyond tolerance (DM-3).
WeakOrPartialName— (below the bar)No corroborating full DoB.

A match in one of the two date-driven tiers on a name that is not 100% identical still surfaces at its tier, but cannot auto-block: the third invariant clamps its Fail to Review, and the case file carries the reason code NAME_NOT_EXACT so the downgrade is visible to an analyst and in the regulator pack.

The shipped default grid

P is the tenant's unconfirmed-hit posture SanctionsUnconfirmedDecision — Review by default, Fail for a strict tenant. The grid is seeded identically for Single and Multiple:

CategoryExactName + DoBExactName, no DoBDoB near-matchExactName, DoB mismatchWeak / partial
sanctionsFailP ‡Review ◆PP
criminal / terrorFailFail †Review ◆PP
pep (all classes)ReviewReviewReviewReviewReview
adverse_mediaReview ★ReviewReviewReviewReview

‡ sanctions ExactName-no-DoB follows the posture P — it was Fail under DM-1 (Q4, §4). † criminal ExactName-no-DoB is Fail (ENG-2, unchanged: a 100%-identical name to a terror entry is confirmed even without a DoB). ◆ the DoB near-match column is resolved before any category ladder, so no category can auto-Fail on a date of birth that is close but not identical (Q6). ★ adverse-media ExactName+DoB is Review — it was Fail under DM-2 (Q7, §4).

Three structural invariants (un-overridable)

The matrix enforces these regardless of any tenant override — a misconfiguration cannot breach them:

InvariantEffect
Watchlist never auto-clearsA sanctions / criminal cell can never resolve to Pass. A Pass override on a watchlist cell is raised to Review.
Multiplicity never lowersEvery Multiple cell is clamped to at least the severity of its Single sibling — 2+ matches can only HOLD or ESCALATE, never soften.
A Fail requires an exact name (Q5)If the matched name does not clear the tenant's ExactNameSimilarity bar (default 100% identical after normalisation), a resolved Fail is clamped to Review. This binds whatever produced the Fail — any evidence tier, the strict SanctionsUnconfirmedDecision = Fail posture, a per-cell override the tenant pinned to Fail, a per-warning-type override, and the post-aggregation EscalateHighToFail band policy. The one exemption is the pipeline's own EDD escalation — see the table below.

What invariant 3 covers — the four producers of a Fail

There are exactly four things in the whole engine that can produce a Fail. The invariant binds three of them. Read the table as the answer to the only question that matters here — "can this configuration auto-block a name that is not 100% identical?": for every row but the first, the answer is no.

#What produces the FailComes fromCan it auto-block a fuzzy name?
1Pipeline EDD escalation — the §6 ladder raising a PEP class to Failthe post-screening pipeline, per screenYes — the single exemption
2Tenant per-warning-type override (WarningTypes, e.g. sanctions → Fail)tenant config (§7)No — clamped to Review
3A matrix cell, including a per-cell override the tenant pinned to Failshipped default / tenant config (§3, §7)No — clamped to Review
4EscalateHighToFail — the band policy, applied after aggregationtenant config (§5, §7)No — clamped to Review
Why EDD is the exemption. Q3 makes EDD a graduated ladder that must Fail a class-1 PEP, and essentially no real PEP name is 100% character-identical to a list entry — clamping it would silently delete the whole ladder. It is also unreachable from tenant configuration by construction: the escalation is written by the pipeline into its own channel, which no saved risk profile, PUT body or database column can address. A tenant that does not want it sets EddEscalationMaxClass to Unknown, or disables the edd_escalation check entirely (§7). No amount of tenant configuration can route any other Fail through this row.
Row 4 must NAME its carrier. EscalateHighToFail is applied after aggregation, so unlike rows 2 and 3 it has no match of its own — and the invariant is a statement about the match being blocked on, not about the screen containing an exact name somewhere. The band policy may therefore escalate a High-band Review to Fail only if it can name a carrier: one counted match satisfying all three of —
  1. Its own name is 100% identical at the tenant's ExactNameSimilarity bar — the invariant itself, asked of the blocking match rather than of the screen.
  2. It is itself capable of blocking — its own effective decision is at least Review, so a match the tenant overrode to Pass, or whose warning type is switched off as a decision input, cannot supply the blocking credential.
  3. It is materially driving the escalation — its own contribution alone reaches the High band. The band is a maximum over contributions, so the match that produced the High band is precisely the one that scores High by itself; a weak hit that lands in Minimal did not cause this escalation and cannot license it.
If no counted match satisfies all three, the escalation is clamped and the decision holds at Review, with NAME_NOT_EXACT recorded — which is what stops the band policy re-applying, one step later, the very block invariant 3 had just clamped.
This is stricter than the gate published on 2026-08-23, which read "does any counted match carry an exact name?". That quantifier tied nothing to the match being blocked on, to a match capable of blocking, or to the match that earned the High band, so the invariant reopened the moment a screen carried a second, unrelated hit. Shapes it re-blocked, every one on a name that is not identical:
  • a fuzzy High-band sanctions hit beside a 100%-identical low-weight pep hit — the exact customer shape the invariant exists for, and a real person who genuinely is a PEP is more likely to carry that second hit, so the old gate failed hardest on the true-identity case;
  • a fuzzy criminal hit beside a 100%-identical adverse_media hit — a category Q7 caps at Review and which cannot block alone;
  • the same again where the tenant had pinned adverse_media to Pass, so a match the tenant had switched off as a decision input still supplied the credential.
Worked example. sanctions (contribution 1.0, name 100% identical, but the tenant has overridden sanctions to Pass under WarningTypes) + criminal (contribution 1.0, name not identical), High band, EscalateHighToFail on. Under the withdrawn screen-wide gate this returned Fail, on the strength of a match the tenant had switched off. There is now no carrier — the sanctions hit fails condition 2, the criminal hit fails condition 1 — so the decision is Review.
Not producers of a Fail at all. The confirmed-PEP floor and the unconfirmed-watchlist floor (§5) only ever raise a Pass to Review. Nothing downstream of the aggregate can turn a Review into a Fail. A tenant that wants the pre-2026-08-23 blocking behaviour moves the bar — ExactNameSimilarity down to 0.97 (§7) — rather than fighting the invariant. The bar is theirs; the invariant is not.
A different name is not a matrix cell. A candidate whose name does not clear the match threshold is classified FalsePositive and dropped before the risk core runs — the subject is cleared by absence, not by a matrix decision.

4 · The named rules — DM-1, DM-2, DM-3, and the 2026-08-23 answers

Several cells depart from a naive "confirmed = name + DoB" reading. Each is an owner decision, and each has a rationale and a worked example. Two of the three original DM rules were superseded on 2026-08-23 — they are kept here, not deleted, because a client integrated against the older behaviour needs to see exactly what moved and why.

Q4 — a sanctions hit with an exact name and no DoB is a Review (supersedes DM-1)

sanctions × ExactNameNoDob → P — the unconfirmed posture; Review by default, Fail for a strict tenant.

  • What DM-1 said (2026-08-07). A sanctions entry that carries no DoB — common on OFAC — can never reach the ExactNameExactDob tier, so following the posture would let the commonest sanctions shape clear to Review. DM-1 therefore Failed it on the name alone.
  • Why it changed (2026-08-23). The missing DoB is precisely what leaves the identity unconfirmed, and an unconfirmed identity is not a basis for a machine to reject a customer with no human in the loop — particularly for common names. The recall argument survives intact: Review is not Pass. The hit is surfaced, the unconfirmed-watchlist floor (§5) stops any band policy quietly downgrading it, and the structural invariant means the cell can never be configured to Pass.
  • A tenant can have DM-1 back, two ways and without a code change: set SanctionsUnconfirmedDecision = Fail (strict posture), or override this one cell to Fail via PUT …/decision-matrix.
  • Example. Screen Bashar al-Assad with no DoB. The name is identical to the OFAC / EU / UK sanctions entries, which carry no DoB. Tier ExactNameNoDob → sanctions cell Review — a mandatory analyst decision, not an automatic rejection.

Q6 — a DoB that is close but not identical is a Review, in every category

* × ExactNameDobNearMatch → Review, resolved ahead of every category ladder.

  • Rationale. Two full dates of birth that are present on both sides and differ — but by less than the tenant's DobYearTolerance — are neither a corroboration nor a rule-out. Previously such a pair was absorbed into the corroborated tier and could carry a category to an automatic Fail. It now has a tier of its own, and that tier is Review everywhere: no category auto-Fails on a date of birth that is close but not identical.
  • Example. A subject born 1980-01-01 matches a sanctions entry reading 1980-11-02. Same year, inside a ±1-year tolerance, but not the same date → ExactNameDobNearMatch → Review, where the old behaviour reached the confirmed tier and Failed.
  • Beyond the tolerance the pair is a mismatch, not a near-match, and DM-3 below applies.

Q7 — an adverse-media hit with exact name + exact DoB is a Review (supersedes DM-2)

adverse_media × ExactNameExactDob → Review; every adverse-media tier is now Review.

  • What DM-2 said (2026-08-07). A name and a corroborated full DoB agreeing inside an adverse-media record is strong enough to block rather than merely review.
  • Why it changed (2026-08-23). Adverse media is an allegation reported by a publisher, not an adjudicated blocking event, and it is not a list a regulator obliges you to act on. Confirming which person the article is about does not make the article a finding — so the confirmation raises the quality of the review, not the severity of the outcome. GDPR Art. 10 (#108) continues to govern adverse media on natural persons.
  • A tenant that wants the old posture overrides the single cell to Fail; no code change.
  • Example. An adverse-media record names Jane Q. Public, DoB 1970-03-04; the subject supplies the same name and the same DoB → tier ExactNameExactDob → adverse-media cell Review, with the corroborated DoB visible in the factor so the analyst knows the identification is solid.

Unchanged — criminal / terror

criminal × ExactNameExactDob → Fail and criminal × ExactNameNoDob → Fail (ENG-2) both stand as cells: terror and criminal categories were not in scope of the 2026-08-23 answers. What tightened for them is the Q5 name bar — the auto-Fail now requires a 100%-identical name, where a 0.98 near-exact name previously qualified. Two shapes changed outcome, and they are not the same case:

  • No DoB, near-exact name (e.g. a one-character typo of a terror name). Falls to WeakOrPartialName and follows the tenant posture — and, being non-identical, cannot be lifted above Review even by the strict posture.
  • Corroborating DoB, non-identical name. The tier is still ExactNameExactDob and the cell still reads Fail, but the third invariant clamps it to Review. This is the single most consequential change in the wave: an agreeing date of birth no longer substitutes for the name. Andreas routes algorithmic name variations to an analyst precisely "to verify dates of birth, nationalities, or secondary identifiers", so a DoB that agrees is the analyst's evidence rather than a reason to bypass them. The case file carries NAME_NOT_EXACT and a rule string naming the clamp, so the downgrade is never silent.

DM-3 — an exact name with a wrong DoB is surfaced for review, not silently cleared

*.ExactNameDobMismatch is a real cell (default Review for PEP / adverse-media, posture P for sanctions / criminal) instead of being dropped as a false positive.

  • Rationale. An exact name whose full DoB is present on both sides but differs beyond the DobYearTolerance (default ±1 year) used to be classified FalsePositive and dropped — it Passed by absence. DM-3 surfaces it as a PotentialMatch so the tenant matrix decides it. A merely partial name with a differing DoB is still ruled out as a different person.
  • Example. A subject with a token-exact name to a watchlist entry supplies DoB 1980-01-01; the entry says 1955-06-30. Beyond ±1 year → tier ExactNameDobMismatch → surfaced as a PotentialMatch → decided by the matrix (Review), not dropped.
DM-3's per-tenant refinement — DobMismatchSurfacing (#368). When an exact name carries a mismatching DoB, which hits surface is a per-tenant choice:
  • HighScore (default) — surface a hit for a token-exact name AND for a partial name whose provider score clears the near-exact bar (DobMismatchHighScoreThreshold, default 0.97 = FuzzyNameScorer.NearExactNameSimilarity). This stops a watchlist entry carrying an extra middle name yet still scoring ~1.0 — e.g. Bashar al-Assad's own score-1.0 entries — from being silently dropped on a DoB difference: it surfaces for Review so a human confirms instead.
  • StrictExactName — only a token-exact name surfaces a DoB mismatch; a strong-but-partial name with a differing DoB is discarded. The pre-#368 behaviour, retained as an opt-in.

5 · Floors and policy modifiers

These are applied to the aggregate decision. They never lower a Fail; they exist to stop a risky match quietly clearing.

ModifierEffect
Confirmed-PEP floor (PepMatchFloorsToReview, default on)If the aggregate would otherwise be Pass and any real, enabled PEP factor is present, the decision is floored to Review — a sitting head of state can never quietly Pass, even in a low band.
Unconfirmed-watchlist floorWhen a band policy would downgrade a Review to Pass but an unconfirmed sanctions factor (any tier below ExactNameExactDob) or a weak/partial criminal-terror factor is driving the Review, the decision is floored back to Review.
EscalateHighToFail on and band = HighFail (entity field EscalateHighBandToFail) — but only if the screen has a carrier: one counted match whose own name is 100% identical, which is itself blocking-capable (its own effective decision is at least Review), and whose own contribution alone reaches the High band. This flag is producer 4 of a Fail and is bound by invariant 3 (§3): with no carrier the escalation is clamped and the decision holds at Review, with NAME_NOT_EXACT recorded. The gate names one match, not the screen, because the invariant is a statement about the match being blocked on — see §3 for the three conditions in full and for why the screen-wide reading published on 2026-08-23 was withdrawn.
AllowLowBandPass on and band ∈ {Minimal, Low}Pass — unless the unconfirmed-watchlist floor above applies.

6 · Enhanced Due Diligence (EDD) — a graduated ladder across all four PEP classes

A separate post-screening check (EddEscalationCheck, OPR-4b/5), run after the base decision — not part of the matrix. When EDD is on for the screen (the per-screen toggle, else the tenant default EnhancedDueDiligenceDefault, default false), every §5.5 PEP class attracts enhanced due diligence. What varies is the intensity:

PEP class (§2)Under EDD, default configuration
Class 1 — NationalEscalate → Fail (maximum diligence)
Class 2 — RegionalEnhanced diligence applies; recorded as a transparency note, decision untouched
Class 3 — Local and enterpriseEnhanced diligence applies; recorded as a note, decision untouched
Class 4 — Local government and associatesEnhanced diligence applies; recorded as a note, decision untouched
Unknown (not a PEP, or no class signal)Out of scope — no finding
Sanctions, criminal, adverse mediaUntouched
  • The ceiling is a tenant knob. EddEscalationMaxClass (default class 1, National) is the least-sensitive class that still escalates; every class at or above it in sensitivity Fails under EDD. Set it to LocalGovernmentAndAssociates and the whole ladder blocks; set it to Unknown and nothing escalates while the notes are still recorded.
  • 🔴 This inverted on 2026-08-23 (Q3). The check previously escalated class 4 only — so a tenant that switched EDD on blocked on a mayor's cousin and let a sitting head of government through at Review. The owner's rule is a ladder: "all four classes need EDD, graduated — class 1 maximum, class 4 calibrated", so escalation now runs from the most sensitive class down to the ceiling.
  • A non-escalating class is never silent. It emits a Note finding on the match ("EDD — <class>: enhanced due diligence applies at graduated intensity; reviewable, not escalated"), so an analyst can tell "EDD assessed this and calibrated it" apart from "EDD never looked at this match".

Only pep-tagged matches are in scope. A tenant opts out of the check entirely by adding its key (edd_escalation) to DisabledPostScreeningChecks. When EDD raises an otherwise-Review PEP to Fail, that escalation — not the category — is named as the headline reason (EDD_ESCALATION).

7 · What's tenant-configurable

Every rule above is per-tenant configuration, not a fixed constant:

How to set them. Every knob in the table below except DecisionMatrixOverrides is a field on the risk profile: GET /v1/tenants/{id}/risk-profile to read the current values, PUT the same route to write. The PUT is a full replace, not a patch — send the whole object back, or an omitted field reverts to its default. DecisionMatrixOverrides has its own route, GET/PUT /v1/tenants/{id}/risk-profile/decision-matrix. Invalid values are rejected with a validation error rather than silently coerced.
KnobDefaultWhat it changes
CategoryWeights[category]1.0Score multiplier per canonical category (sanctions, pep, adverse_media).
CountryWeights[isoCode]1.0Score multiplier per matched entity's nationality.
CriminalWeight1.0Score multiplier specifically for criminal-category hits.
LowThreshold / MediumThreshold / HighThreshold30 / 60 / 85Band cut-offs; High also anchors score normalization used by the band policy.
SanctionsUnconfirmedDecisionReviewPosture P for an unconfirmed sanctions / criminal cell — Review or Fail. Never permits auto-Pass.
PepMatchFloorsToReviewonFloors a confirmed PEP match to at least Review, regardless of band.
EscalateHighToFailoffEscalates a High-band Review to Fail.
AllowLowBandPassoffDowngrades a Minimal/Low-band Review to Pass (subject to the unconfirmed-watchlist floor).
DecisionMatrixOverridesnoneSparse per-cell overrides of the §3 grid. Re-normalized on write and read (watchlist→Pass raised to Review; softened Multiple raised to its Single sibling). Set by a platform operator (PUT …/decision-matrix); viewable by a tenant admin (GET).
WarningTypes overridesnonePer-warning-type kill switch and a per-warning-type decision override that wins over the matrix cell. A Fail set here is tenant policy like any other and is bound by the Q5 invariant (§3, producer 2): on a name that is not exact it is clamped to Review.
DecisionPriorityOrdersanctions > criminal > PEP1–4 > adverse mediaWhich match is named PRIMARY; never changes the outcome.
ExactNameSimilarity1.00Q5 — the bar at which a name counts as exact. It admits a match to ExactNameNoDob / ExactNameDobNearMatch, and it is the bar the third structural invariant tests before allowing any Fail (§3). 1.00 = 100% identical after normalisation; set 0.97 to restore the pre-2026-08-23 near-exact blocking behaviour. Range [0.97, 1] — a PUT below 0.97 is rejected with 400. The floor is not cosmetic: a low bar does not merely switch the invariant off, it also promotes every weak or partial name out of WeakOrPartialName into ExactNameNoDob, whose criminal cell is Fail. At 0, one field would turn the product into "auto-block everything the matcher retrieves". 0.97 is the loosest bar the product has ever supported.
DobYearTolerance1Years two DoBs may differ and still count as agreeing. Feeds the evidence tier: inside the tolerance and non-identical is the Q6 near-match tier; outside it is the DM-3 mismatch tier.
EddEscalationMaxClassNational (class 1)Q3 — the least-sensitive PEP class EDD escalates to Fail; every class at or above it in sensitivity escalates, the rest record a transparency note (§6). Sent as a class name — National, Regional, LocalAndEnterprise, LocalGovernmentAndAssociates, or Unknown (case-insensitive). Unknown is the documented off switch: it is accepted (200) and escalates nothing, while the transparency notes are still recorded. A numeric ordinal is rejected.
DobMismatchSurfacingHighScore#368 — strict (token-exact only) vs HighScore (the default: also near-exact partial names) surfacing of an exact-name-with-wrong-DoB.
DobMismatchHighScoreThreshold0.97Provider-score bar a partial name must clear to surface a DoB mismatch under HighScore.
EnhancedDueDiligenceDefaultfalseDefault EDD posture (§6) when a screen carries no per-screen EDD toggle.
DisabledPostScreeningChecksnonePost-screening check keys switched off, e.g. edd_escalation.
PepRecencyYears50Living-PEP recency window: years after leaving office a PEP still counts before demotion to an Observation.
Honest nuance. The retrieval threshold and the internal scoring weights remain engine-level: what is per-tenant is the bar at which a retrieved name counts as exact (ExactNameSimilarity), the DoB tolerance, and the mismatch-surfacing mode. Making the full name-strictness ladder per-tenant is still a documented pending item (DM-5). Everything else here is live per-tenant configuration today.

8 · How a decision is reached — the full flow

  1. Retrieve & classify. Candidates are classified on the name × DoB axis into TruePositive / PotentialMatch / FalsePositive. Only the first two are real and carry forward; a different name is dropped.
  2. Drop disabled types. A warning type the tenant has switched off is removed before decisioning, as if the hit never happened.
  3. Assign an evidence tier. Each real match lands in one of the five tiers from its name strength (against the 100%-identical ExactNameSimilarity bar) and its DoB signal — agrees / differs within DobYearTolerance / differs beyond it / absent.
  4. Resolve the base decision. Each match is resolved through its matrix cell (category × tier × multiplicity), or its per-warning-type override. Either way the result passes through invariant 3: a Fail on a name that does not clear the ExactNameSimilarity bar is clamped to Review, and NAME_NOT_EXACT is recorded on the case file. The named rules of §4 live here.
  5. Aggregate. Take the strongest base decision across all matches (Fail > Review > Pass).
  6. Apply floors & policy. Fail stands. A Review runs EscalateHighToFail — which can only reach Fail when the screen has a carrier, a counted match that is itself name-identical, blocking-capable and High-band on its own contribution (invariant 3, §3), and otherwise holds at Review — or AllowLowBandPass, then the unconfirmed-watchlist floor; any path to Pass runs the confirmed-PEP floor.
  7. EDD escalation. If EDD is on, a PEP match at or above the tenant's EddEscalationMaxClass (default class 1) escalates the decision to Fail; a less-sensitive class records a transparency note.
  8. Name the primary. The priority ladder names the decisive match — presentation only, never changing the outcome.
  9. Return. The response carries decision, riskScore, riskBand, reasonCodes, and the contributing factors[] — the full audit trail.
© PROOViD AML · Developer Docs Score & decision · How the data is built · API reference