User:Jdlrobson/Extension:Gadget/Policy

Despite gadgets and user scripts being a key component of MediaWiki projects, up until now APIs have been ill-defined leading to misunderstandings and frustrations between engineers and gadget developers when gadgets break. This also leads to code rot, where developers do not feel empowered to make changes as it's unclear how their changes will impact gadget developers.

On top of this, when gadgets break it's not clear who can and will fix them.

Together, we should determine a policy that works for both Wikimedia staff and gadget developers to lead to a better experience for both parties and try to restore trust and good faith between the two parties.

To contribute to the policy please use the discussion page to raise concerns, suggestions, removals or additions.

Problem statement
MediaWiki engineers follow the Stable interface policy. However, currently CSS and HTML is not subject to this policy as they cannot be deprecated in the same way as JavaScript and PHP.

A few problems have arisen in the development of skins because of this:


 * Developers make HTML changes that break gadgets. Examples: A gadget uses an element ID to insert itself into the page and that ID is changed, or the HTML is refactored by engineers for better maintainability leading to unexpected consequences on code assuming the old HTML structure.
 * Developers moving CSS to improve page performance, inadvertently break wikitext that assumes it exists. Example
 * Gadget developers make assumptions about CSS availability based on desktop, leading to display problems on the mobile site.
 * Editors can edit MediaWiki:Common.js or site-wide gadgets and introduce unchecked errors leading to bugs that impact high volumes of users. Examples: https://phabricator.wikimedia.org/T291512, Japanese gadget

Recommended solution
To solve this a policy is recommended to make the contract between MediaWiki developers and gadget developers explicit.

JavaScript

 * Code SHOULD be loaded to a page by the `mw.loader.load` method. Methods such as `importScript` are not officially supported by the MediaWiki software and may break in future. See ResourceLoader/Migration_guide_(users) for more information.
 * Code inside the `mw` object can be used by gadgets and is subject to the rules of the Stable interface policy. Gadget developers are encouraged to use these libraries, but MUST pay attention to any deprecation warnings in JavaScript console.
 * Gadget developers SHOULD NOT assume that certain HTML structures and classes that are used now will be used in future and are encouraged to request explicit APIs for absent use cases.
 * For example, menu items SHOULD be added via the `mw.util.addPortletLink` method. Any menu items added via other mechanisms e.g. $('').appendTo('#p-personal ul li") is not supported and is prone to future breakage.
 * Gadget and user scripts developers SHOULD not use global scope where possible, to make it easier for other JavaScript developers to debug where errors originate.
 * At the top of the gadget, the maintainers should be listed, so that when there is a problem it is clear who needs to be talked to.

CSS

 * Gadget developers SHOULD provide their own CSS for styling their gadgets and SHOULD NOT rely on MediaWiki HTML classes provided by the software. In certain cases it might make sense for gadget and MediaWiki developers to share code, but this MUST be documented in the code using a @public keyword per the Stable interface policy. If the code is not documented gadget developers MUST file a Phabricator ticket to make sure this is documented.
 * Gadget developers CAN override existing CSS rules for content generated by wikitext e.g. thumbnails
 * MediaWiki developers CAN change default CSS for content generated by wikitext provided they go through the deprecation policy.
 * MediaWiki developers must prefix their CSS classes with "mw-" to avoid namespace clashes with gadget developers.
 * Gadget developers MUST NOT introduce or use CSS classes prefixed with "mw-" to avoid namespace clashes with MediaWiki developers.

Deprecation policy

 * All classes that can be generated by wikitext without the use of a template e.g. `.wikitable` are subject to the deprecation policy. Any other HTML classes provided by the interface are NOT subject to the deprecation policy.
 * HTML IDs are subject to the deprecation policy.
 * MediaWiki engineers MUST notify Project:Tech_News prior to making a change to CSS and HTML code covered by the stable policy. The message MUST mention "BREAKING CHANGE" and provide steps to resolve the problem. A period of at least two weeks must be given for gadget developers to raise any concerns relating to the change, but ideally 1 release.
 * Gadget developers MUST follow Project:Tech_News to learn about upcoming deprecations.

Maintaining code and error handling

 * Client side errors occurring in gadgets are tracked alongside errors on Grafana and can be explored further inside our logstash instance.
 * MediaWiki developers MUST fix gadget and/or user script errors that cause alerts. Having healthy metrics helps us have more confidence when we deploy code.
 * MediaWiki developers CAN fix gadget and/or user script errors that undermine user privacy. For example, if an active user is triggering an error on every page load, which reveals their page history, you are encouraged to fix it.
 * MediaWiki developers CAN disable gadgets that are broken provided the edit summary documents how the issue can be fixed.
 * MediaWiki developers CAN run bots to fix multiple gadgets where resolution is straightforward.
 * Gadget/script developers CAN opt out of error tracking by the guidelines given on wikitech:Client error
 * Gadget/scripts in the user namespace of a retired or blocked user MUST BE blanked as they are no longer maintained. They SHOULD be forked to other places (e.g. MediaWiki namespace, another user namespace) where they can be maintained.
 * Volunteers CAN request anonymized data from WMF staff and other engineers with NDA about errors coming from their gadgets by creating a Phabricator ticket in #Instrument-ClientError