Contract for a pluggable exogenous-feature source.
A provider maps the hourly target index to a numeric feature frame on that exact index. Subclasses set name (a short identifier used in logs and as the default column name) and implement build.
Implementations should load their backing data lazily inside build and raise ExogProviderError when the data is missing or cannot cover the requested range, so the fail-safe policy lives in one place.
pd.DataFrame: Numeric columns indexed exactly by index, NaN-free within the validated window (the full index unless a provider_window was set at construction).