Skip to content

Instantly share code, notes, and snippets.

@isaacs
Created February 9, 2012 01:51
Show Gist options
  • Save isaacs/1776425 to your computer and use it in GitHub Desktop.
Save isaacs/1776425 to your computer and use it in GitHub Desktop.
Stability ratings: 0-5
0 - Deprecated. This feature is known to be problematic, and changes are
planned. Do not rely on it. Use of the feature may cause warnings. Backwards
compatibility should not be expected.
1 - Experimental. This feature was introduced recently, and may change
or be removed in future versions. Please try it out and provide feedback.
If it addresses a use-case that is important to you, tell the node core team.
2 - Unstable. The API is in the process of settling, but has not yet had
sufficient real-world testing to be considered stable. Backwards-compatibility
will be maintained if reasonable.
3 - Stable. The API has proven satisfactory, but cleanup in the underlying
code may cause minor changes. Backwards-compatibility is guaranteed.
4 - API Frozen. This API has been tested extensively in production and is
unlikely to ever have to change.
5 - Locked. Unless serious bugs are found, this code will not ever
change. Please do not suggest changes in this area, they will be refused.
@piscisaureus
Copy link

Great idea, Isaac. Will there also be a way to comment on particular APIs? A structured effort to identify issues/inconsistencies in different would be very beneficial I think.

Also, you might consider including currently undocumented APIs in the list so we can decide what to do with it. e.g.
https://github.com/joyent/node/blob/9a6012edd9330296b7476bc6b7fbda2cd5c8165d/lib/url.js#L26
https://github.com/joyent/node/blob/9a6012edd9330296b7476bc6b7fbda2cd5c8165d/lib/tty.js#L352-393
https://github.com/joyent/node/blob/master/lib/timers.js#L114-154
https://github.com/joyent/node/blob/master/lib/buffer.js#L275

@ry
Copy link

ry commented Feb 9, 2012

We should consider using the Solaris stability attributes for this. The following is copied from the attributes(5) man page:

Committed

The intention of a Committed interface is to enable third parties to develop applications to these interfaces, release them, and have confidence that they will run on all releases of the product after the one in which the interface was introduced, and within the same Major release. Even at a Major release, incompatible changes are expected to be rare, and to have strong justifications.

Interfaces defined and controlled as industry standards are most often treated as Committed interfaces. In this case, the controlling body and/or public, versioned document is typically noted in a "Standard" entry in the Attributes table or elsewhere in the documentation.

Although a truly exceptional event, incompatible changes are possible in any release if the associated defect is serious enough as outlined in the Exceptions section of this document or in a Minor release by following the End of Feature process. If support of a Committed interface must be discontinued, Sun will attempt to provide notification and the stability level will be marked Obsolete.

Uncommitted

No commitment is made about either source or binary compatibility of these interfaces from one Minor release to the next. Even the drastic incompatible change of removal of the interface in a Minor release is possible. Uncommitted interfaces are generally not appro‐ priate for use by release-independent products.

Incompatible changes to the interface are intended to be motivated by true improvement to the interface which may include ease of use considerations. The general expectation should be that Uncommitted interfaces are not likely to change incompatibly and if such changes occur they will be small in impact and may often have a mitigation plan.

Uncommitted interfaces generally fall into one of the following subcategorizes:

  1. Interfaces that are experimental or transitional. They are typically used to give outside developers early access to new or rapidly changing technology, or to provide an interim solution to a problem where a more general solution is anticipated.
  2. Interfaces whose specification is controlled by an outside body yet Sun expects to make a reasonable effort to maintain compatibility with previous releases until the next Minor release at which time Sun expects to synchronize with the external specification.
  3. Interfaces whose target audience values innovation (and possibly ease of use) over stability. This attribute is often associated with administrative interfaces for higher tier components.

For Uncommitted interfaces, Sun makes no claims about either source or binary compatibility from one minor release to another. Applications developed based on these interfaces may not work in future minor releases.

Volatile

Volatile interfaces can change at any time and for any reason.

The Volatile interface stability level allows Sun products to quickly track a fluid, rapidly evolving specification. In many cases, this is preferred to providing additional stability to the interface, as it may better meet the expectations of the consumer.

The most common application of this taxonomy level is to interfaces that are controlled by a body other than Sun, but unlike specifications controlled by standards bodies or Free or Open Source Software (FOSS) communities which value interface compatibility, it can not be asserted that an incompatible change to the interface specification would be exceedingly rare. It may also be applied to FOSS controlled software where it is deemed more important to track the community with minimal latency than to provide stability to our customers.

It also common to apply the Volatile classification level to interfaces in the process of being defined by trusted or widely accepted organization. These are generically referred to as draft standards. An "IETF Internet draft" is a well understood example of a specification under development.

Volatile can also be applied to experimental interfaces.

No assertion is made regarding either source or binary compatibility of Volatile interfaces between any two releases, including patches. Applications containing these interfaces might fail to function properly in any future release.

Not-an-Interface

The situation occasionally occurs where there exists an entity that could be inferred to be an interface, but actually is not. Common examples are output from CLIs intended only for human consumption and the exact layout of a GUI.

This classification is a convenience term to be used to clarify such situations where such confusion is identified as likely. Failure to apply this term to an entity is not an indi‐ cation that the entity is some form of interface. It only indicates that the potential for confusion was not identified.

Private

A Private interface is an interface provided by a component (or product) intended only for the use of that component. A Private interface might still be visible to or accessible by other components. Because the use of interfaces private to another component carries great stability risks, such use is explicitly not supported. Components not supplied by Sun Microsystems should not use Private interfaces.

Most Private interfaces are not documented. It is an exceptional case when a Private interface is documented. Reasons for documenting a Private interface include, but are not limited to, the intention that the interface might be reclassified to one of the public stability level classifications in the future or the fact that the interface is inordinately visible.

Obsolete

Obsolete is a modifier that can appear in conjunction with the above classification levels. The Obsolete modifier indicates an interface that is "deprecated" and/or no longer advised for general use. An existing interface may be downgraded from some other status (such as Committed or Uncommitted) by the application of the Obsolete modifier to encourage customers to migrate from that interface before it may be removed (or incompatibly changed).

An Obsolete interface is supported in the current release, but is scheduled to be removed in a future (minor) release. When support of an interface is to be discontinued, Sun will attempt to provide notification before discontinuing support. Use of an Obsolete interface may produce warning messages.

@isaacs
Copy link
Author

isaacs commented Feb 9, 2012

@ry I'd read through the solaris stability indicators a few weeks ago, at your suggestion. They're ok, and they make sense for an OS. But there are a few aspects that make them suboptimal for node, and in trying to think of how to apply them to Node's API, I ended up at this simplified version.

  1. There's frequent references to governing bodies, etc., which an operating system has a lot of. Node has none.
  2. There are very few things in node that should be considered "not an interface". Basically just the output of util.inspect and console.trace, which we can put special language around. An operating system is often used by piping the string output of one program into another, so this is a much more relevant issue there.
  3. Anything private should be obvious by virtue of not being exposed, being exposed only through process.binding, or having an underscore at the start of the name (which is such a common red-flag that most JavaScripters will be very fearful.) These interfaces should not be in the public-facing docs. (Documenting them elsewhere would be a good move to enable new contributors. Reading the code is best.)

That leaves Obsolete, Volatile, Uncommitted, and Committed, in order of least to most reliable.

I also want a way to shoo people away from making changes to, say, assert.js or module.js; these parts of the program are extremely sensitive, used internally, and have been behaving well for a long time. You should be able to rely on these with absolute confidence that nothing will change unless there is a very serious bug found, which is highly unlikely.

So, Obsolete, Volatile, Uncommitted, Committed, and Locked.

Then, I thought that there's a difference between API-locked and Code-locked. For example, module.js should just be considered hands-off except in extreme cases. On the other hand, while most of fs.js's API should be considered locked, and not open to further discussion, the code itself may need further cleanup or optimization as we use more of it in more platforms, and fixes that don't change the API are welcome. This is more than just a commitment to provide backwards-compatibility; it's a strong claim that we believe that backwards-compatibility will not ever even be an issue, because we're done changing the surface.

So, Obsolete, Volatile, Uncommitted, Committed, API Frozen, and Locked.

I then just changed the names to match what we actually use in discussions. For example, we refer to interfaces as "experimental", not as "volatile". ("Broken" should probably be called "deprecated", since that's the term we use internally. Updating gist.) "OK" sounds a bit more inviting than "Uncommitted", and since these interfaces are areas where we benefit from people using them, I don't want to scare them off too strongly. But maybe something a bit more risky-sounding would be good there.

Leaving us with:

Deprecated, Experimental, OK (?), Stable, API Frozen, and Locked.

I don't remember when I started thinking of them as a measure of Volatility rather than a measure of Stability, but having Stabiliity: <number> all over the docs might be a bit more encouraging on a subliminal level than Volatility: <number>. Reversing the order to reflect this.

@Gozala
Copy link

Gozala commented Feb 10, 2012

I would go for "unsettled" or "unstable" instead of "ok" which to me is confusing.

@isaacs
Copy link
Author

isaacs commented Feb 12, 2012

Unstable is good. You're right, "ok" is kind of confusing.

Updated the list, and the language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment