Denied-Party Screener
Screens importer, consignee, and supplier against the US government denied-party lists.
Deterministic service (not an LLM). Fuzzy-matches every party on an entry against US sanctions and watch lists. Auditable, reproducible, defensible.
What it does
Takes the supplier, importer, and consignee names off an entry and fuzzy-matches them against ~30K+ entity records from OpenSanctions us_trade_csl — the consolidated US trade screening list. Returns a band (block / review / watch / clear) per party with the matched entity, source list, and similarity score.
Why no LLM here: a denied-party hit must be reproducible across runs, must be cite-able in a CBP audit, and must never hallucinate. A pg_trgm similarity score with a documented cutoff is defensible; a model's "I think this looks like Hoshine" is not.
Inputs
{
parties: {
supplier?: { name: string; country?: string };
importer?: { name: string; country?: string };
consignee?: { name: string; country?: string };
};
}
Outputs
{
shipmentId: 'SHIP-1042',
partiesScreened: 3,
totalHits: 1,
blockingHits: 1, // count of `block`-band hits
reviewHits: 0,
watchHits: 0,
hitsByRole: [
{
role: 'supplier', // 'importer' | 'consignee' | 'supplier' | 'carrier'
partyId: null,
name: 'Xinjiang Apparel Mfg Co.',
hits: [
{
sourceList: 'UFLPA', // 'SDN' | 'EL' | 'DPL' | 'UVL' | 'UFLPA' | 'MEU' | 'ISN' | 'DTC'
canonicalName: 'XINJIANG APPAREL MFG. COMPANY LTD',
matchedOn: 'XINJIANG APPAREL MFG. COMPANY LTD',
score: 1.0,
band: 'block', // 'block' | 'review' | 'watch'
sourceUrl: 'https://www.dhs.gov/uflpa-entity-list',
},
],
},
],
topHit: { role: 'supplier', name: 'Xinjiang Apparel Mfg Co.', band: 'block', score: 1.0, sourceList: 'UFLPA' },
}
When it runs
- Every entry, automatically — in the
draft → ai_reviewtransition. The result is stored and surfaced as a header banner in the drawer. - Every Simulation — runs on the supplier name pulled from the PO so the user sees the band before any commitment.
- On-demand from the supplier passport — broker clicks "Re-screen" to pick up newly-added entries to the sanctions lists.
- On data refresh — when the screening lists refresh from OpenSanctions, all open entries are re-screened.
Dependencies
- OpenSanctions
us_trade_csl— ~30K+ entities, consolidated from:- OFAC SDN (Treasury) —
SDN - BIS Entity List (Commerce) —
EL - BIS Denied Persons List —
DPL - BIS Unverified List —
UVL - BIS Military End-User (MEU) List —
MEU - DHS UFLPA Entity List —
UFLPA - State Department non-proliferation (ISN) —
ISN - State DDTC / AECA-debarred —
DTC
- OFAC SDN (Treasury) —
- Postgres with
pg_trgmextension for trigram similarity. - Corporate-suffix normalization — strips "Co., Ltd.", "Inc.", "GmbH", "Pvt.", "JSC", etc. before scoring, so "Hoshine Silicon Industry Co., Ltd." and "Hoshine Silicon" both resolve at 1.0.
What success looks like
Screens every party on the entry — importer, consignee, and supplier — against the full set of US denied-party lists in under a second, tuned so that a true match is never missed (recall is the priority; a broker would rather clear a near-miss than let a real hit through). The lists are re-ingested weekly (upstream OpenSanctions updates daily; Aduaria pulls the feed on a weekly Sunday cron), so screening runs against a recent denied-party universe.
The bands themselves are chosen to be CBP-defensible:
| Band | Score cutoff | What it means |
|---|---|---|
block | ≥ 0.55 | High-confidence match. Broker must clear before transmit. |
review | ≥ 0.40 | Likely match — surface to broker. |
watch | ≥ 0.35 | Possible alias — investigate. |
clear | < 0.35 | No actionable match. |
What it does NOT do
- Does not make the screening decision. It surfaces hits with evidence; the broker decides whether to dismiss (with a reason code) or hold the entry.
- Does not screen against EU, UK, or UN lists today. US-only — adding EU
consolidated_euis on the Q4 roadmap. - Does not rank or interpret matches with an LLM. Future LLM re-ranking pass to distinguish a true match from a generic word collision is on the roadmap (see AI architecture) but is NOT in production yet — the deterministic scoring is.
- Does not check DOB, address, or program-specific eligibility (e.g. USMCA certificate validity). Out of scope.
- Does not monitor for changes after the entry clears — that's a separate audit concern.
Roadmap
- Q3 2026 — LLM re-ranking pass on
reviewandwatchband hits to separate true alias matches from generic word collisions. The deterministic score stays as the primary signal; the LLM is a secondary confidence input only. - Q3 2026 — Add EU consolidated list + UK FCDO list for customers doing transshipment.
- Q4 2026 — Beneficial-ownership chain screening (today we screen only the parties named on the entry; this would walk the corporate graph one level).
- Q4 2026 — Address-based screening (some Entity List records have address-only entries; we'd parse the shipper address off the BoL).
Put your own book of entries through Aduaria.