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 stable interface policy defines which parts of the PHP code in MediaWiki core (mediawiki/core.git) can be considered stable and safe for use by extensions and other code outside the core module. Any code that is part of the stable interface is subject to the deprecation policy. Any code that is not part of the stable interface is subject to change without notice.

Motivation
The motivation for this policy is two-fold: On the one hand, it provides guarantees to extension developers, providing guidance on what aspects of MediaWiki core they can safely rely upon. On the other hand, it provides guarantees to developers working on MediaWiki core, telling them what aspects of the code they can safely change without having to worry about breaking extensions.

Through this, this policy is designed to make extensions more robust against changes in core, and provide more freedom for the core code to evolve.

Principles
In principle, 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, unless these methods are documented to be unsafe (e.g. annotated with @deprecated or @unstable or @internal).
 * 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).
 * It's generally unsafe to rely on global variables. Static methods should be used instead.

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 declared otherwise using the annotation tags defined below.
 * All public methods and fields, for calling, unless declared otherwise using the annotation tags defined below. This does not include methods and fields that are lacking any access modifiers. See the note on legacy code below. Also, this does not guarantee public methods to be stable for overriding.
 * All documented hooks, unless declared otherwise using the annotation tags defined below.
 * Any code explicitly documented to be part of the stable interface, especially when annotated with the @stable, @fixed, @extensible or @newable tags, to the extent defined below for each of these tags.

In contrast, the following things are not part of the stable interface, and are therefore subject to change without notice:
 * Protected methods and fields, unless the class is marked as an extension point using the @extensible annotation.
 * Methods and fields lacking explicit access modifiers. Access modifiers should be added to such methods as soon as possible, according to their current usage in extensions.
 * Constructor signatures, unless marked as stable for calling using the @stable annotation. Stable constructor signatures can also be assumed for classes marked @extensible or @newable.
 * Interface signatures, unless the interface is marked to be safe for implementation using the @fixed or @extensible annotation. This means that extensions should not directly implement interfaces that are not documented to be safe for this purpose. An extensible base class should be provided for the use of extensions instead.
 * 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.
 * Any code explicitly documented to be unstable or internal, particularly when annotated with the tags @deprecated, @internal, @unstable, or @experimental.

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.
 * @experimental: same as @unstable.

to add guarantees:


 * @stable: backwards compatibility will be maintained for calls; changes that impact callers are subject to the deprecation policy. This applies to the function or method's contract as well as its signature. Note that a method can only safely be overridden if it is declared to be fixed, being stable is not sufficient.
 * @fixed: backwards compatibility will be maintained for calls, overriding, implementing, and subclassing; thus, 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, and no abstract methods can be added. Note that only methods declared to be fixed can be overwritten safely. 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.