Most new customers are routine and should onboard in seconds. A few need a human's eyes. This agent risk-tiers every applicant in deterministic code, catches the PEP and sanctions name variants an exact-string check would wave through, and refers the consequential cases to compliance. A language model never decides approve-or-refer. Here is exactly how the line is drawn, and the dial that moves it.
Reviewing every new customer by hand is slow, inconsistent, and exactly where good applicants drop off. Auto-approving everyone to be fast is reckless: a politically exposed person, a higher-risk jurisdiction, or a thin verification slips straight through, and now it's a MAS finding. The trap that costs the most is not the customer you reject. It is the sanctioned name you didn't recognise because it was spelled differently from your list. That miss is silent. Nothing fires, the account opens, and you learn about it from the regulator.
The obvious screen is exact-string equality: applicant.name in pep_list. It demos perfectly and fails in production, because a sanctions or PEP list is a set of spellings, and a real applicant controls how they spell their own name:
So the real job is not a lookup. It is fuzzy name matching against the watchlist with a defined similarity cutoff, fused with a deterministic risk score over PEP status, jurisdiction and verification completeness, and then a tiered decision: auto-approve the clearly routine, refer everything else to a person.
This is the load-bearing decision of the whole system. Every risk score, every watchlist match, and the approve/refer gate is computed in Python from the applicant's attributes, so it is reproducible, re-runnable, and auditable to the field. The language model is downstream and read-only. It drafts the referral note about a decision the engine already made, and it must cite the exact fields that triggered the referral or it writes nothing. A model never decides whether to approve or refer.
Inside the engine, each applicant is scored from explicit attributes and screened against the watchlist. The parameters are named, not vibes:
Take account W00001, "Daniel Bin Salim": SG, fully Verified, no PEP flag, closest watchlist name only 0.37 similar. Risk is low, so the engine auto-approves it in seconds and nothing reaches a human. Now the one that matters. Account W00005, "Fang Rahman". An exact-string screen finds nothing, because that spelling isn't on the list. But the list carries "Fhang Rahmann", and after normalisation the matcher scores the pair at 0.92, over the 0.85 cutoff, so the engine raises a watchlist hit, tiers the account high, and refers it for enhanced due diligence. Only then does the model draft the note, quoting both spellings and the score.
| Account | Check that fired | Observation | Score vs cutoff | Evidence | Result |
|---|---|---|---|---|---|
| W00001 | Risk tier | SG · Verified · no PEP · best name match 0.37 | low | W00001 | auto-approved |
| W00114 | PEP + cross-border | PEP flag set · country = ID (higher-risk) | high | W00114 · pep · ID | referred |
| W00005 | Fuzzy watchlist match | "Fang Rahman" vs list "Fhang Rahmann"; exact match finds nothing | 0.92 ≥ 0.85 | W00005 · watchlist | caught; exact-match misses |
The 44.7% referral rate is a dial, not a verdict. 134 of 300 referred looks like a swamped team. Read it instead as where the auto-approve line currently sits. Three named parameters move it: the risk-tier threshold (today, any medium factor refers; promote "Basic verification only" into the auto-approve band and the rate drops sharply), the jurisdiction list ({ID, MY}, where narrowing or widening it directly trades cross-border referrals), and the fuzzy cutoff (raise it from 0.85 toward 0.95 and fewer name variants refer). Each is a lever an analyst-capacity model sets, not a fixed property of the system.
Which way to turn it: false negatives vs false positives. Tightening the dials (higher cutoff, shorter jurisdiction list, looser tier) shrinks the queue but raises the false-negative risk: the missed sanctioned name, the dangerous miss. Loosening them refers more and raises false positives, the analyst hours spent clearing the innocent. In regulated onboarding you bias toward recall: a false positive costs a few minutes; a false negative costs a licence. The engine does not pretend a referral equals a problem. It produces a cited candidate list a human triages, and the dial is set by policy, in the open.
Where these come from, honestly. Origin Pay's accounts are synthetic, seeded with PEPs and higher-risk profiles deliberately, so these figures prove the mechanism, the scoring, the fuzzy catch, and the tiered gate. They do not prove that this exact rate survives a specific real book. A deployed version connects to the live onboarding flow and a sanctions/PEP screening feed; the boundary and the dials are what carry over.
Every decision, each auto-approval and each referral, is written to a hash-chained ledger. Each entry's hash covers its contents and the previous hash, so altering any record after the fact breaks the chain at exactly that row. The tier, factors and decision are the gate's structured output. The model never writes them.
seq : 114 agent : KYC Desk action : refer_kyc subject : W00114 tier : high decision : escalate → compliance (EDD) factors : [politically exposed person (PEP), cross-border (ID)] evidence : [W00114] prev_hash : 7a1d…b93f hash : c08e…41aa ← = sha256(prev_hash + canonical(entry))
I don't build AI that approves or rejects people. I draw the line first. The risk score, the watchlist match and the approve/refer gate all sit in code, reproducible to the field, and the model stays strictly downstream and cited. Then I confront the hard parts out loud: the transliteration that defeats exact match, the false-negative-versus-false-positive trade the dial controls, and the near-miss the system must get right. Designing where the auto-approve line sits, making it tunable by policy, and proving where it was drawn is what governing AI in financial services actually means.
The artifact above is real output from the engine over Origin Pay's wallet accounts: the 167 auto-approved, the 133 referred, the 7 PEPs, each with its factors. The full interactive desk runs as a working application.