Christopher Farmer
CF
Christopher Farmer
Case studies
All case studies ← Back to portfolio
Case study 07 · Sanctions screening & exposure

Sanctions Suite — four offline screening tools on one dated snapshot

A screening desk, an ownership-exposure graph, a vessel screener and a portfolio console — all built on one checksummed OpenSanctions snapshot, all running with the network cable unplugged.

308,597 sanctions & crime entities12,113 relationship records2,347 vessels & aircraftAttestation outputVanilla JS · offline
Sentinel Screen showing a Rosneft query returning eight sanctioned entities with scores, list labels, countries and sanctions programmes
Sentinel Screen — a real query against the deposited snapshot, returning designated Rosneft entities with their programmes and source lists. Drawn from the tool’s own output on snapshot 20260802074701-juq: the records, scores, list labels, countries and programmes are exactly what it returns. Programme lists are abridged to the first three for width.

01The problem

Sanctions screening is usually bought as a subscription to somebody else's black box, and the subscription is the point of failure: the moment it lapses, or the connection drops, or the matter is too sensitive to send to a third-party API, the screening stops — and the firm still has to answer the question. Most tools also answer “hit / no hit” against a name while leaving three things unsaid: as at when, on what corpus, and why this record. A compliance file needs all three, because what gets defended a year later is not the answer but the search: what was run, against what data, on what date. That is an evidential problem before it is a technical one.

02What I built

Four tools sharing one pipeline. A Python builder streams two dated OpenSanctions collections — sanctions (292,861 entities) and crime (522,965) — into deterministic data packs holding 308,597 distinct targets drawn from 147 source datasets; four single-file browser tools read those packs and never touch the network again.

  • Sentinel Screen — name, identifier or pasted-list screening against 308,597 distinct sanctions and crime entities, with a PEP overlay of 771,755 records loaded on demand in the local build (the overlay is 141 MB and is not published with the web demo). Produces a dated attestation carrying the SHA-256 of every source file, the snapshot version of each collection, and the method applied.
  • Exposure Graph — 12,113 ownership, directorship, family, association and representation records, searched breadth-first for the shortest routes from a counterparty to a designated party, every hop showing the source that records it.
  • Vessel & Trade Screener — 2,347 vessels and aircraft (2,003 ships, 344 aircraft) from the designated lists, searched by IMO, MMSI, call sign or pasted manifest — ship-type prefixes and all. Each row is marked LISTED or RELATED, with ownership chains and sanctioned owners shown.
  • Meridian Sanctions Console — a 1,317-company register pre-screened against the snapshot, producing a review queue filterable by score band.

03Three decisions that carry the legal judgement

First, point-in-time is stated, never implied. Every screen, export, dossier and attestation carries the snapshot version and build stamp, and that stamp is derived from the data rather than the clock, so the same snapshot reproduces byte-identical packs. An answer without a date is not evidence. Second, the tool refuses to be quietly wrong: the builder aborts rather than emit a short pack if a source file is missing or a row count disagrees with the snapshot's own index, because a truncated corpus produces a confident green “no match” for records that were never searched — the worst failure this class of tool has. In the same spirit, a single-token query that finds nothing is reported as inconclusive, not clear. Third, candidates are not findings: matching is deterministic token-set overlap with published guards, one rule shared by the builder and all four tools so the suite cannot give two answers for the same pair of names, and every surfaced record shows which name matched and why.

04What it proves to a regulated employer

Screening calibration is a judgement call disguised as a setting. Building this end to end meant making those calls in the open and being measured on them: an early containment rule flooded the review queue to 591 of 1,317 companies, and the fix was not a threshold nudge but a rarity test — a lone token may carry a match only if it is rare in the corpus, which is what separates a designated Rosneft subsidiary from a coincidental surname. Successive independent audit passes drove corpus recall, alias handling, non-Latin script coverage and the false-positive rate on a realistic vessel manifest, which fell from nine in twenty to zero. For a sanctions or financial-crime function, that is the useful half of the skill set: someone who can interrogate a vendor's matching logic rather than accept it, and who knows what a regulator will ask of the file afterwards.

Status & dataRuns here in the portfolio, entirely in the browser and entirely offline — nothing typed into it leaves the page. The published build carries the complete 308,597-entity corpus, not a sample: repeated fields are interned into dictionaries and rehydrated in the browser, which is what makes a corpus of that size shippable at all. Sentinel Screen pulls 55 MB for the core pack, with 23 MB of listing detail following in the background; the other three tools carry their own smaller packs, 87 MB for the suite. Once a tool’s page and its pack have loaded, the machine can be taken off the network and that tool keeps answering. That is the point of building it this way — screening work is often done where connectivity is unavailable, untrusted, or where the query itself is the sensitive part, and a tool that needs an API call is no tool at all in those conditions. The one component held back is the 771,755-record PEP overlay, a 141 MB pack past GitHub's file limit; it runs in the local build and every tool says so rather than hiding it. Data is OpenSanctions, licensed CC BY-NC 4.0 — non-commercial use with attribution; business use requires a licence from OpenSanctions. Output is point-in-time, produces candidates for human adjudication, and is not legal advice.