Stable interface policy

I propose to create a policy that explicitly defines the stable interfaces for use by extensions, to accompany deprecation policy and the best practices for extensions. This policy defines which parts of the PHP code in MediaWiki core (mediawiki/core.git) can be considered stable and safe for use by extensions. Any parts of the code that are considered to be part of the stable interface are subject to the deprecation policy. Any parts of the code that are not considered stable are subject to change without notice.

Guarantees
The following things are considered part of the stable interface, and therefore subject to this deprecation policy, after having been present in at least one stable release:
 * global functions with the "wf" prefix, unless marked with the @internal annotation or otherwise documented to be unstable, experimental, or deprecated.
 * all public methods and fields of classes, unless the class or the method or field is marked with the @internal annotation or otherwise documented to be unstable, experimental, or deprecated. This does not include methods and fields that are lacking any access modifiers. See the note on legacy code below.
 * all documented hooks, unless the hook is documented to be internal, unstable, experimental or deprecated.
 * only some protected methods and fields of classes, namely ones that belong to classes that are documented to act as extension points or explicitly allow subclassing outside the MediaWiki core module.
 * only some constructor signatures, namely ones that belong to classes that are documented to act as extension points or explicitly allow subclassing outside the MediaWiki core module, as well as the constructor signatures of classes documented to define pure value objects.
 * only some interface signatures, namely ones of interfaces that are documented to act as extension points or explicitly allow implementation by code outside the MediaWiki core module.

In contrast, the following things are not part of the stable interface, and are therefore subject to change without notice:
 * protected methods and fields of classes, except ones that belong to classes that are documented to act as extension points or explicitly allow subclassing outside the MediaWiki core module.
 * constructor signatures, except ones that belong to classes that are documented to act as extension points or explicitly allow subclassing outside the MediaWiki core module, as well as the constructor signatures of classes documented to defined pure value objects.
 * interface signatures, except ones of interfaces that are documented to act as extension points or explicitly allow implementation by code outside the MediaWiki core module.
 * global variables, including those with the "wg" prefix. MediaWikiServices should be used as an entry point that provides access to service objects and configuration instead.

In summary, code outside of MediaWiki core, particularly in MediaWiki extensions, should expect that:
 * it's generally safe to call public methods and access public fields in classes defined by MediaWiki core.
 * it's generally unsafe to extend (subclass) a class or implement an interface defined by MediaWiki core, unless that class or interface was designated to be safe for that purpose (annotated with @fixed or @extensible). In particular, the constructor signature may change, and abstract methods may be added.
 * it's generally unsafe to directly instantiate (using new) a class defined by MediaWiki core, unless that class is designated to be safe for this purpose (annotated with @newable).

Some legacy code may not have any access modifiers, in which case it is not considered to be part of the stable, public interface. Developers SHOULD add visibility modifiers as soon as possible, and use judgement when making this code protected or private. Where known users exist, developers should still consider following the full deprecation process. New code MUST have explicit visibility set on all properties and functions.

Annotations
As described above, the following defaults apply:


 * Public methods of classes and interfaces are considered stable unless marked with @deprecated, @internal, or @unstable. They are however considered not fixed, meaning they are not safe to override.
 * Protected methods are considered unstable unless marked with @stable or @fixed.
 * Constructor signatures are considered unstable unless marked with @stable or @fixed.
 * Signatures of interfaces are considered not fixed unless the interface is marked with @fixed. Methods and optional arguments may be added without notice.
 * Similarly, the set of required abstract methods is considered unstable unless the class is marked with @extensible (@stable does not suffice). Methods and optional arguments may be added without notice.

The following annotations can be used to depart from the defaults above,

to remove guarantees:


 * @deprecated: do not use outside the module, may be removed without further notice. Should always be accompanied by instructions of what to use instead.
 * @internal: do not use outside the module, subject to change without notice. Same as @unstable, except that internal typically stays internal.
 * @unstable: do not use outside the module, subject to change without notice. Same as @internal, except that unstable things are intended to become stable in the future.

to add guarantees:


 * @stable: backwards compatibility will be maintained for calls; changes that impact callers are subject to the deprecation policy. Note that this applies to the function or method's contract as well as its signature.
 * @fixed: backwards compatibility will be maintained for calls, overriding, implementing, and subclassing; only very limited changes to signatures are possible, all such changes are subject to the deprecation policy. Applicable to the signatures and contracts of public and protected methods as well as entire interfaces. Only fixed interfaces are safe to implement outside the module, only fixed methods are safe to be overwritten.
 * @extensible: class is safe to subclass; changes affecting subclasses will be done in a backwards compatible way. This implies that the constructor is stable, protected and public methods are fixed, and no abstract methods can be added. If applied to an interface, @extensible should be considered to mean the same as @fixed, to avoid confusion. Constructors of extensible classes should be marked as @stable for clarity.
 * @newable: The class is safe to be instantiated. This implies that the constructor is stable. Generally, only plain value objects should be newable, since any other kind of object may require dependency injection.