A churn model shipped three months ago and the intervention team says it has gone bad. The model has not changed and the relationship between behaviour and churn has not changed either: what changed is the data arriving at the door. Four separate things went wrong upstream, each of a different kind, and each needs a different check to catch. Your job is to build the validation and monitoring layer that names them, then harden the feature pipeline so the model survives contact with them.
Turn the clean training frame into a schema you can check future batches against.
Implement build_reference_profile(train_df) returning a dict with:
Exclude the label column "churned" throughout.
This dict is the contract. Everything in the next four milestones is a comparison against it, and the reason to build it explicitly is that "the data looks fine" is not something you can diff.
Evaluated server-side against a hidden test set.