Stable interface policy/T255803 Draft/Changes



  • Consolidate information about each kind of stability to its own section. Previously it was spread across different sections. For example, the meaning of "stable to call", what falls under it by default, how to opt-in/opt-out. The sentences from the "quick guide" are now call outs atop their relevant section. This facilitates scanning and avoids having to find your way up and down the page. A much reduced version of the guick guide still exists but it no longer tries to cover every area and every edge case.
  • Have each section about a stability guruantee lead with a simple sentence about what it does and what it can apply to.
  • Consolidate information about globals in its own section. See Global variables.
  • Consolidate information about "@unstable for implementation" to its own section. See Stable to type.


  • The grammatical form of annotations changed from present continuous to active. I believe this shorter form uses words we more commonly use, matches the keywords used in source code, and maybe easier to spell and recognise. For example, "call", "extend", "implement", and "override"; instead of "calling", "overriding", "subclassing" and "implementation".
  • Consistently use the same words for the same concepts, especially to reduce potential confusion for non-native speakers. (e.g. "safe/stable" -> "stable", "unafe" -> "not stable").

Content changes:

  • The overlap between "stable to call" and "stable to instantiate" was clarified, and there is no longer ambiguity over how to mark stable constructor, and when to use @newable. See "Stable to call".
  • Fix contradiction about overriding methods. It said "stable for overriding: … This annotation should be applied to all abstract methods of classes marked as stable for subclassing". But, it also said any method declared abstract is safe to override by default in "Only methods explicitly marked this way (or declared abstract) are safe to override". I leaned toward requiring the latter, which mandates fewer annotations – abstract method are stable to override by default. See "Stable to override".

Content additions:

  • Explain why interfaces are discouraged. The recommendation to use abstract classes as extension point was already mentioned in a few places, but not explained. Now consolidated and explained under Stable to extend.
  • Explain why using "stable to call" constructors are discouraged. It previously mentioned "dependency injection". I've written down that the intent is to allow authors to add and change their dependencies without requiring deprecation. See Stable to call.
  • Incorporate some points about our new hook system (T240307). See Stable to implement.
  • Define what "stable to override" promises. One might naively assume it just means core can't break the method's signature (as that would could cause a PHP error). But I believe the real intent is that "stable to override" (also) means that core must continue to call this method to let it do its thing. Removing the base method and caller from core would not cause a fatal error, but is most certainly breach of contract. See Stable to override.
  • Document that Wikimedia production must be updated before hard deprecation begins. See "Deprecation".