The problem
Vendor risk tools tend to return a single opaque number. The design question here was how to keep risk and confidence as separate dimensions, so that a thin evidence base lowers confidence rather than quietly inflating or deflating the risk score - and how to make every record point back to the document it came from.
The system
What I built
- Implemented 40+ data collectors covering sanctions, regulatory and insolvency registers across Australia, the UK, the EU, the US and Canada.
- Streamed collection results to the interface with Server-Sent Events so a long-running scan reports progress as it goes.
- Implemented a sigmoid penalty scoring model, with human adjudication gating any sanctions match before it affects a record.
- Built an append-only, hash-stamped PostgreSQL evidence store so records can be verified as unmodified.
- Added peer benchmarking across 1,000+ possible cohorts by industry, revenue, headcount and region, with a widening-ladder fallback that refuses to report below eight peers.
- Added an optional read-only LLM evidence summariser that is structurally unable to modify risk scores.
Stack
PythonFastAPIPostgreSQLNeonServer-Sent EventsXAMLdnspythonhttpxPytestRuffReactViteTailwind CSS
Skills applied
- OSINT collection and source assessment
- Risk scoring model design
- Confidence modelling
- Entity resolution
- Hash-chained audit storage
- Peer cohort benchmarking
- Streaming APIs
- Regulatory and legal compliance design
- Rate limiting