Check features using future/target info; fit transforms only on train; audit unrealistically high scores.
How to answer it
Leakage is information in the training features that will not exist at prediction time. The symptom is a model that looks too good; the cause is almost always time or the target.
Where to look, in order:
Any feature computed with a window that reaches past the prediction moment. "Total purchases" that includes the purchase you are predicting. "Days until cancellation" in a churn model.
Anything derived from the target: a flag set by the process that also sets the label, a status field that only changes after the outcome.
Preprocessing fit on the full dataset: scalers, imputers, target encoders, feature selection done before the split.
Duplicates or near-duplicates across train and test: the same user, the same document, the same session split across both.
Joins to tables that are updated retroactively, so a training row sees a version of the world that did not exist at the time.
How to find it when you suspect it:
# 1. per-feature suspicion: a single feature with near-perfect separation is a leak until proven otherwise
from sklearn.metrics import roc_auc_score
{c: roc_auc_score(y, X[c]) for c in X.columns if X[c].dtype != object}
# 2. time-respecting evaluation: train on months 1-9, test on 10-12; a big drop vs random CV is a leak
Then the structural fix: build features as of a timestamp (point-in-time joins), fit every transform inside the pipeline on training folds only, and split by entity and by time.
What they are checking: that you name time as the usual culprit and that you can propose a test, not just a definition.
Common mistake: celebrating an AUC of 0.99 on a problem where the previous best was 0.75.