Making the extension contract stable through version upgrades

### Describe the workflow you want to enable

Currently, every time `scikit-learn` releases a new minor version - e.g., 1.5.0, 1.6.0, 1.7.0 - compliant extensions, e.g., custom transformers, classifiers, etc, break - specifically, referring to the API conformance as tested through `check_estimator` or `parametrize_with_checks`.

These repeated breakages in the "extender contract" contrast the stability of the usage contract, which is stable and professionally managed.

For a package like `scikit-learn` which means to be a standard not just for ML algorithms but also an API standard that everyone uses, this is not a good state to be in - "do not break user code" is the maxim that gets broken for power users writing extensions.

Of course maintaining downwards compatibility is not always possible, but nothing should break without a proper warning.

### Describe your proposed solution

The main reason imo why this keeps happening is that `scikit-learn` is not using a proper pattern that ensures stability of the extension contract - and also no secondary deprecation patterns in relation to it.

A simple pattern that could improve a lot would be the "template pattern", in a specific form to separate likely changing parts such as the boilerplate (e.g., `validate_data` vs `_validate_data` and such) from the extension locus.
Reference: https://refactoring.guru/design-patterns/template-method

Examples of how this can be used to improve stability:

* `sktime`, for a different API, has a separation between `fit` calling an internal `_fit`, where change-prone boilerplate is sandwiched between a stable user contract (`fit`) and a stable extender contract (`_fit`); similarly `predict` and `_predict`
* `feature-engine` overrides the `BaseTransformer` `scikit-learn` extension contract with a similar pattern using `super()` calls in `fit` etc.

In particular the `fit`/`_fit` pairing that combines strategy and template pattern can be introduced easily via pure internal refactoring - I would go with that, and also add a layer of tests that checks the stability of the extension contract.

As a side effect, this would likely reduce the amount of copy-pasted boilerplate among the core estimators in `scikit-learn` proper as well.

### Describe alternatives you've considered, if relevant

The obvious alternative is "do nothing" - which will lead to packages with extensions producing their own version of mitigating patterns for the unstable status quo.

The problem with this is that the extending packages are mutually incompatible with their extender pattern. It would be better if there is a single stable extension pattern prescribed - or at least recommended - by `scikit-learn`.

### Additional context

_No response_

COMMENT:
>> Is there a way of engaging or escalating that the suggestion gets attention? Is there a procedure to follow? Or is it more an unstructured random process, by which maintainers may or may not ultimately reply?

> Aggressive and passive aggressive comments like this are certainly not helpful, and we reserve our rights to block individuals if it repeats @fkiraly .

@adrinjalali, my comments were not meant as being aggressive or unhelpful. In fact, they were quite concrete in my opinion.
I was trying find out if there is a way to get developer attention, since there are a large number of issues. For instance, I do not think you have a slack or discord where you directly engage with users, your developer ecosystem is quite "walled off" from my outsider perspective.

Plus, getting out the stick in the first response to the above, after it has been waiting for a month, is neither kind nor constructive from your side.

I get how you may feel attacked, but that was not my intention! Please do not "shoot the messenger" if I am pointing out a shortcoming in the extender interface.

In any case, it is not user and customer oriented, and I would strongly recommend you to change your tone in reply to input that is critical of the status quo, but professional and constructive.

> Any library breaks things for advanced users, the same way we continuously have CI issues regarding our dependencies (numpy, scipy, etc), and the way to make sure users are not affected, is to make sure you have a CI testing against the nightly build, and report issues as soon as they come about, for us to fix it either inside sklearn or sklearn-compat.

I think this is an oversimplification.

This statement, if read at face value, puts the onus exclusively on the downstream. That is certainly not "the way" - you can, for instance, just make your interfaces more stable.

The topics user and customer orientation can be pointed to again.

>  I'm not sure if there's anything to do specifically in this issue, and I'm also in favor of a `_fit` / `fit` separation which we can implement in a non-breaking way for people developing future extensions. 

Ok, I will open a new issue if that is how it works.

Labels: New Feature, Developer API