top of page
OPEN TO WORK

Six systems, and the
 
decisions  behind them

Two built at work, four built to answer a question I could not put down. Every case study carries the same anatomy — the constraints, the alternatives I rejected, the numbers, and the parts that still are not done.

CASE STUDIES

6   ·   one template

BUILT AT WORK

2  ·  AXA Group Operations

PERSONAL

4  ·  built on my own

LIVE DEMOS

2  ·  both free-tier hosted

[[projects-stack]]

What every case study  contains 

Same six blocks, same order, six times. If you have read one of these pages you already know where to find the part you care about.

Snapshot

Problem, approach, stack and outcome in a table you can read in fifteen seconds. Read only this and you still know whether the rest is worth your time.

Key insight

The one thing that turned out to be true and was not obvious at the start. Usually the reason the first approach was thrown away.

Architecture

How the pieces fit, drawn rather than described, with the data path stated end to end.

Requirements and constraints

What the system had to do, and what it was not allowed to do. Latency budgets, confidentiality, cost ceilings, the people who had to sign off.

Hidden constraints

The ones nobody wrote down and I found by hitting them. This is the section most worth your time if you are trying to judge whether I have shipped anything real.

What is not done

Every page names its own limits and its saturation point — the load it has not been tested past, the path that is designed but not benchmarked.

Rather read the  code ?

SIX PUBLIC REPOS, README ON EACH, COMMIT HISTORY NOT SQUASHED.
bottom of page

Selected work

Build, break, rebuild

Six systems: one built at work, five on my own time. Every number below is measured and sourced.

01

Fraud Detection Platform

Personal2026
View case study
Transactions on a time axis, cut by a dashed line marked now. Everything before the cut is read by the score; everything after it has not yet happened.

End-to-end fraud scoring platform where every feature reads only a transaction's past, and each shortcut that reads its future is priced.

PythonXGBoostFastAPIRedisMLflowSHAP

590,540Transactions scored
0.5451Test PR-AUC
+0.2593Random-split inflation
37.6 msMedian scoring request

Sources. Public IEEE-CIS data, never deployed. PR-AUC interval 0.5274 to 0.5614, 95 percent bootstrap, 1,000 resamples of the test month.

02

Uplift Targeting

NewPersonal2025
View case study
Qini curve. An uplift-ranking line bows above the dashed random-targeting diagonal, and the gap between the two is labelled incremental gain.

Estimate incremental impact and turn it into a spend policy. Decision science rather than prediction: the question is not who will convert, it is who converts because you spent the money.

PythonEconMLOptunascikit-learnPandasStreamlit

+0.0905Qini uplift
8Models benchmarked
1Spend policy shipped
CriteoPublic dataset
03

Security Framework Mapping

One audit finding on payment-gateway log retention, linked to six ranked control candidates. The top match, A.12.4.1 Event Logging, scores 0.93.

NLP system that maps audit findings to compliance controls, replacing a manual mapping pass that ran for weeks each quarter at AXA Group Operations.

PythonBM25LightGBMspaCyscikit-learn

93%Top-1 accuracy
99%Top-3 accuracy
384Hours saved per quarter
$180KAnnual saving

Sources. AXA Group Operations deployment, signed off internally. Manual audit effort down 96%.

04

FinSight

Personal2025
View case study
A time series split by a dashed as-of date: point-in-time history to the left, forecast and its 80 percent interval to the right.

Leakage-safe financial forecasting, built point-in-time so a backtest reports what the model could actually have known on the day rather than what the dataset knows now.

PythonProphetXGBoostPandasPlotly

5Models compared
0.734MASE, naive 1.326
13 yrsPoint-in-time history
1 of 3Targets the naive wins
05

ClauseCheck

Personal2025
View case study
A grid of eight policy plans against the clauses retrieved for one question. Two rows, Plan C and Plan E, are outlined as the plans whose answers differ.

Clause-grounded RAG for insurance policy questions. It answers across eight plan variants, flags when the answer differs between them, and lists the clauses it retrieved rather than asking you to trust it.

PythonRAGFAISSLangChainStreamlit

8Plan variants compared
5Clauses retrieved per answer
37sCold start, disclosed
87.1%Recall at 5
06

Drift-watch

Personal2024
View case study
Population stability index tracked day by day. It runs flat below a dashed alert threshold, then rises through it at the point marked alert fires.

Monitoring service for models already in production: data drift, performance decay, and an alert that fires before a stakeholder notices instead of after.

PythonFastAPIDockerEvidentlyPrometheus

3Signals monitored
0.386PR-AUC, was 0.874
57Windows blind, no labels
0False alarms, clean run