Core Platform Team/Initiative/Reduce Extension Interface Surface Area/Initiative Description

Project Leads
Product: Cindy Cicalese

Engineering: TBD

Current state
Planning

Expected start
FY1819 Q4 - FY1920 Q1

Summary
Currently, extension code is very highly dependent upon MediaWiki core code. If a change is made to the parameters passed to a hook or the public interface to any of the core PHP classes, for example, it is likely that extension breakage will occur. Extensions currently rely extensively upon global state, which also introduces fragility.

This project will reduce the level of dependence of extensions upon MediaWiki core code by reducing the breadth of the interface through which extensions access MediaWiki core. This will be done by specifying a limited set of mechanisms by which extensions can access core, reducing the parameters that are passed to extensions to only what is necessary, and eliminating global state. The new interfaces will be documented for extension developers.

There are three mechanisms that have emerged over time by which extension code and core code interact:


 * 1) Extension code can be registered with the Extension Registry so that the extension code will invoked during execution of core code. Code of this type falls into four broad classes: action hooks, filter hooks, handlers, and services.
 * 2) Extension code can directly call any public core function to which it has access.
 * 3) Extension code can call core code through a web API (action API or REST API). This is usually done from JavaScript to add dynamic behavior, but can be done from PHP as well. (This mechanism is out of scope for this project as it is covered by another project.)

This project will examine each aspect of the first two mechanisms listed above to do the following:


 * 1) Analyze current usage
 * 2) Propose improved interfaces with reduced surface area (RFCs, as necessary)
 * 3) Create deprecation and migration plan
 * 4) Incrementally, for each new interface:
 * 5) implement new interface
 * 6) document new interface for extension developers
 * 7) deprecate old interface
 * 8) migrate extensions to new interface

This work has already begun with RFC: MediaWiki 2018 extension interfaces, which proposes action hooks and filter hooks. Once this RFC is approved, analysis of current hooks will begin to migrate existing hooks to the new hook interfaces. According to mediawiki.org, there are roughly 680 hooks currently defined in MediaWiki core.

Significance and motivation
This project aims to reduce the surface area of the extension interface so that the scope of changes to core that will affect extensions will be reduced. This will enable core developers to more confidently make changes to and improve core while reducing the need of extension developers to frequently react to changes in core that break their extensions. Constraints put on extensions by this new approach will yield dividends in the increased stability of the interface between core and extensions.

Milestones and major tasks

 * Develop the product plan
 * Analysis and Design:
 * Action and filter hooks:
 * Approve RFC for action and filter hooks
 * Enumerate all current hook points, and analyze their usage in extensions
 * Categorize current hooks as action and/or filter hooks and map parameters (identify any parameters that need to change/create new parameter types)
 * Develop deprecation and migration plan
 * Access to core:
 * Analyze which core code is called by extensions
 * Analyze what global state is accessed by extensions
 * Analyze which core classes are subclassed by extensions
 * Identify areas of core code that extensions should not access and identify alternatives
 * For each area of improvement identified:
 * Make proposal for improvement (possible RFC)
 * Collect feedback from stakeholders
 * Develop deprecation and migration plan
 * Create development plan
 * Development:
 * Implement the action and filter hook interfaces dictated in the RFC
 * Provide developer facing documentation for migration of for new hooks
 * Migrate extensions to new hooks
 * Implement new core interfaces per each proposal for improvement
 * Mark core code that is internal and may not be accessed by extensions (may require tool support)
 * Mark core classes that may be subclassed by extensions (may require tool support)
 * Provide developer facing documentation for migration to new core interfaces
 * Migrate extensions to new core interfaces
 * Deprecate then remove old hooks and interfaces

Outcome
Reduce complexity in core

Baseline

 * Number of hooks exposed to extensions: TBD
 * Percentage of APIs exposed to extensions: 100% of the code base

Target

 * TBD
 * TBD

Methodology and rationale
To measure success, we need to survey extension code and produce reports about 2 metrics:


 * The number of hooks points exposed to extensions
 * The number of APIs exposed to extensions

Time and resource estimate
Once RFC: MediaWiki 2018 extension interfaces is approved, the following tasks will need to be resourced:

Implement action hook and filter hook interfaces in core
1 engineer for 1 week

Analyze current hooks and their usage
There are roughly 680 hooks in core. These hooks and their usage in extensions are of various levels of complexity. Therefore, the hooks will be ranked by the frequency of their usage in actively maintained gerrit hosted extensions. 3 staff months will be allocated to analyzing hook usage in rank order. At the end of this period, re-estimation will be necessary to prioritize the remaining less frequently used hooks.

The analysis will answer the following questions for each hook by examining all extensions that implement the hook:


 * Is it an action hook?
 * If so, what parameters does it need to do its job?
 * Is it a filter hook?
 * If so, what parameters does it need to do its job?

Dependencies
TBD

Collaborators and stakeholders
TBD

Open questions

 * How should an extension expose a web API?
 * How do we annotate source code so that code is public or private to extensions?
 * Should Wikimedia and third party extensions have the same interface into core?
 * How close can we come to killing all global state, replacing it by using service locators?
 * Should there be a restricted service locator that extensions are forced to use?
 * Can the internal tag be used to mark certain classes as internal without making it difficult to work within core

Phabricator
TBD

Plans and RFCs
RFC: MediaWiki 2018 extension interfaces