Requests for comment/Deprecation policy

Background
One of MediaWiki's greatest strengths is the diverse extension ecosystem. But we (MediaWiki core developers) can often make it hard for extension developers to keep up with constant breaking changes. We do not have a standard deprecation policy, leading to widely inconsistent practices depending on who writes and/or reviews the patch. Some reviewers expect you to fix all instances in Gerrit before merging a core deprecation patch, others will be fine with fixing none.

Problem
The MediaWiki core codebase is constantly changing. In addition, lately there has been a major push on improving the architecture of MediaWiki, meaning making possibly large changes to our codebase (this is a good thing!). However, because there is no consistent deprecation or backwards-compatibility policy, it is difficult for extension authors to anticipate what changes might need to be made and core developers who don't know how much they need to bend over backwards to provide back-compat. It is important that any deprecation policy works both ways - it should not place an undue burden on either side. MediaWiki core does not exist in a vacuum, it depends upon having extensions as much as extensions depend upon the core.

There is some documentation about deprecating code at Deprecation, but recommendations like "Deprecations of MediaWiki core functionality should be flagged for a minimum of two MediaWiki releases before removal (except in extreme circumstances)" are not followed in practice.

Proposal
We should create an actual policy that is followed by developers. The following content would replace the content currently at Deprecation. I've proposed a mix of the status quo and what I (Legoktm) would like to see. If it is too controversial, I think it is important that we have a policy that documents what the actual practice is even if it is non-ideal. I would like to see this implemented starting with the 1.29 development cycle.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Scope
This proposed policy applies to the PHP API of the MediaWiki core (mediawiki/core.git) codebase. It explicitly does not apply to the api.php API, client-side JavaScript, HTML output, or database schemas. Those should (and do) have their own deprecation practices. If changes do affect those components, they should also follow those deprecation practices as necessary. As with all policies, developers should apply their best judgement when following it, and use common sense as necessary.

More specifically, the stable part of the PHP API is comprised of all code that is explicitly marked public, and has been included in at least one stable release. In addition, some classes expect to be subclassed in extensions; in those cases protected functions also are included in the API. These classes should have a note in their documentation comment that they expect subclassing. If no note is present, it SHOULD be assumed that the class is not expected to be subclassed. Hooks are considered part of the PHP API.

Note: Typically PHP code would use private or final, however those are not supported by PHPUnit's mocking features, and as a result not really used in MediaWiki code.

Classes and/or functions with public visibility MAY also have,   or   annotations to indicate they are not stable interfaces that SHOULD NOT be depended upon.

Some legacy code may not have any visibility modifiers, in which case it is not considered to be part of the stable interface. Developers SHOULD add visibility modifiers as soon as possible, and use judgement when making de-facto public code protected or private. New code MUST have explicit visiblity set on all properties and functions.

Prior to deprecation
Deprecation is typically considered when code needs to be refactored in order to add new functionality, improve general architecture, or fix bugs. Developers SHOULD consider the impact of their proposed changes by doing basic greps on extensions or using tools like Github's code search.

Extension developers are encouraged to mirror their code into Wikimedia's Gerrit/Phabricator/Github to make it easier for core developers to identify usage patterns. Extensions that are open source will be given more consideration than those that core developers cannot see.

Deprecations MUST first take place on the master branch. It is NOT RECOMMENDED to backport deprecations to stable branches.

Developers SHOULD consider deprecating similar parts of code together so affected code can be updated all at once.

Deprecation
There are two steps to deprecation: a soft deprecation, and then a hard deprecation.

A soft deprecation occurs when a developer adds a  annotation to the documentation comment for a method, function, or class.
 * The documentation comment MUST mention what the alternative method or migration path is. If there is no alternative, it should state that.
 * The documentation comment MUST state what MediaWiki core version the deprecation occurred in.
 * If code is only soft deprecated, it SHOULD function the same as prior to deprecation. (This is only a SHOULD not MUST as sometimes it is only possible to provide similar functionality, which is enough for practical purposes, but technically not equal functionality.)
 * Any relevant documentation in the git repository or on mediawiki.org MUST be updated once the change is approved.
 * The deprecation MUST also be mentioned in the relevant RELEASE-NOTES file, and MAY also be mentioned in the "Upgrade notices for MediaWiki administrators" section of the wiki release page depending upon severity. Deprecation of hooks MUST be mentioned in docs/hooks.txt.
 * Developers SHOULD update MediaWiki core to no longer use the deprecated functionality.
 * Developers SHOULD update any extension or skin bundled with the MediaWiki tarball when soft deprecating, and MAY update popular extensions (WikiApiary.com and ExtensionDistributor can be used as indicators of extension popularity).
 * If they are don't submit patches, developers MUST file bugs about bundled extensions/skins using deprecated functions so their maintainers can work on updating them.

A hard deprecation occurs, when a  call is added to the function or method in question, or by supplying the $deprecatedVersion parameter to Hooks::run. This emits deprecation warnings and causes things like unit tests to fail.
 * Code that is hard deprecated MUST also be soft deprecated.
 * The version number in the wfDeprecated call MUST match the one in the @deprecated annotation, even if the hard deprecation occurs in a different release.
 * Often code is soft deprecated first, and hard deprecated at a later date, but they MAY occur at the same time.
 * Hard deprecated code MAY act as no-ops instead of actually functioning, though this is not recommended.
 * MediaWiki core code that triggers hard deprecation warnings MUST NOT be reachable from non-deprecated core code using non-deprecated configuration settings
 * Extensions and skins bundled with the MediaWiki tarball MUST NOT trigger hard deprecation warnings and MUST be updated to use the new code.


 * Developers MAY email wikitech-l or mediawiki-l about the soft or hard deprecation depending about severity.
 * When a bug report or a task is related to a deprecation, it is RECOMMENDED to tag it specifically in the bug tracker; for instance with the "Technical Debt" tag, column "Deprecate / Remove" in Phabricator.

Removal

 * Code MUST emit hard deprecation notices for at least one major MediaWiki version before being removed. It is RECOMMENDED to emit hard deprecation notices for at least two major MediaWiki versions. EXCEPTIONS to this are listed in the section "Removal without deprecation" below.
 * Developers SHOULD consider how difficult it is to support and maintain the deprecated code when determining how urgent removal is. In addition, developers SHOULD consider usage statistics in extensions.
 * Developers MAY consider the LTS cycle in removing deprecated code (removals may be accelerated to avoid deprecated code being included in LTS versions, requiring an extended support period).
 * The removal MUST also be mentioned in the relevant RELEASE-NOTES file, and MAY also be mentioned in the "Upgrade notices for MediaWiki administrators" section of the wiki release page depending upon severity.

Caveat: As one of the principles of MediaWiki, developers should ensure any removals will not cause issues in the Wikimedia setup and extensions deployed there. If they do, developers should expect to be reverted by Wikimedia system administrators.

Removal without deprecation
In some cases, it is necessary to remove code without deprecating it in a major MediaWiki version beforehand. Some past examples include: TODO FIND SOME


 * Developers MUST email wikitech-l ahead of time, explaining why deprecation is not possible or not reasonable.
 * All steps about documenting deprecations and removals MUST still be followed, as applicable.

Examples
These are some examples of well documented, announced, or implemented deprecations and removals, and can be used as a guide:
 * ... find some!

Meta
Changes to the substance of this document MUST be announced on wikitech-l, and SHOULD be discussed beforehand.