KYC onboarding and a compliance review desk that can explain every decision it made.
Identity vendors lose, repeat and reorder their notifications. This system stays correct anyway, and can prove it afterwards.
- Duplicates
- 0 duplicate jobs in 5 test runs
- Decisions
- Every decision explainable in one sentence
- Screening list
- OFAC SDN, 19,393 entries, versioned snapshot
- Applicants
- 400 synthetic, seeded
The principle underneath
Prefer a visible failure to a silent degradation. A screen run against half a list looks like a clean result — so a half-loaded list refuses to run.
Walkthrough
Six decisions, each one defended.
01 · the queue
The job queue is a Postgres table
When a verification result arrives, the system must record it and schedule the work it implies. If those aren’t atomic, no ordering is safe. With the queue in the same database, the enqueue is part of the same transaction as the write — both happen or neither does.
When it stops being right: at thousands of jobs per second. This handles a few hundred applications a day.
02 · concurrency
Two workers never claim the same job
The claim is one statement using
FOR UPDATE SKIP LOCKED: a locked row is treated as absent, so the next worker takes the next job instead of queuing behind it. A deliberately broken version is kept for comparison.Without the lock
200 jobs ran 376 times (176 duplicates)
With it · 5 of 5 runs
200 runs, 0 duplicates
03 · lifecycle
Nothing is decided without being screened
Two codebases write the same table, so a rule held in one of them is a rule the other can break.
The allowed transitions are rows in a table, enforced by a database trigger. Changing a rule is a reviewable migration.
started → submitted → checking → screening → decided04 · scoring
Risk scoring is points, not machine learning
When a regulator or a customer asks why someone was refused, the answer has to be a sentence. “Name match at 100%, downgraded because the listed date of birth conflicts” is one. “The model scored 0.83” is not. A name match alone routes to a human, never to rejection — screening finds names; identity is a judgement.
The cost: the weights are a judgement call, not back-tested. A real firm would validate them.
05 · evidence
The audit log refuses edits
Every state change writes a row to the audit table, which rejects UPDATE, DELETE and TRUNCATE at the database level. The officer’s case view shows that timeline raw; there is no edit control to build because the write would be refused.

06 · disclosure
Two audiences, two rules
The officer and the applicant read the same audit table but must not see the same thing. Showing an applicant their screening detail risks tipping-off, teaches evasion, and attaches a sanctioned person’s identity to someone who is usually somebody else. The applicant view is a whitelist that fails closed: an event type nobody has written a sentence for shows nothing.
The mistake: the first version rendered the raw rows. A test now fetches the live page and asserts the screening terms never appear.
Limits
What this demo does not prove.
Synthetic data only.
400 seeded applicants and a versioned public sanctions list. No real identities, documents or vendor traffic have been through it.
Tamper-evident, not tamper-proof.
The audit table refuses UPDATE, DELETE and TRUNCATE. That makes edits visible failures; it does not make the database impossible to change.
Not client work.
Nothing here has been through a real audit, regulator or production incident. It shows the approach, not a track record.
Describe the decision or the exception that worries you.
One paragraph, no customer data needed.