Merge pull request #2844 from matrix-org/travis/msc/global-versioning
MSC2844: Global version number for the whole specpull/977/head
commit
5800dcb654
@ -0,0 +1,211 @@
|
||||
# MSC2844: Using a global version number for the entire specification
|
||||
|
||||
Currently we have 4 kinds of versions, all of which have slightly different use cases and semantics
|
||||
which apply:
|
||||
|
||||
1. The individual API spec document versions, tracked as revisions (`r0.6.1`, for example).
|
||||
2. Individual endpoint versioning underneath an API spec document version (`/v1/`, `/v2/`, etc). Note
|
||||
that the client-server API currently ties the major version of its spec document version to the
|
||||
endpoint, thus making most endpoints under it `/r0/` (currently).
|
||||
3. Room versions which define a set of behaviour and algorithms on a per-room basis. These are well
|
||||
defined in the spec and are not covered here: https://matrix.org/docs/spec/#room-versions
|
||||
4. An overarching "Matrix" version, largely for marketing purposes. So far we've only cut Matrix 1.0
|
||||
back when we finalized the initial versions of the spec documents, but have not cut another one
|
||||
since.
|
||||
|
||||
This current system is slightly confusing, and has some drawbacks for being able to compile builds of
|
||||
the spec documents (published on matrix.org) and generally try and communicate what supported versions
|
||||
an implementation might have. For example, Synapse currently supports 4 different APIs, all of which
|
||||
have their own versions, and all of which would need to be considered and compared when validating
|
||||
another implementation of Matrix such as a client or push gateway. Instead, Synapse could say it
|
||||
supports "Matrix 1.1", making compatibility much easier to determine - this is what this proposal aims
|
||||
to define.
|
||||
|
||||
## Proposal
|
||||
|
||||
Instead of having per-API versions (`r0.6.1`, etc), we have a version that spans the entire specification.
|
||||
This version represents versioning for the index (which has quite a bit of unversioned specification on
|
||||
it currently), the APIs, room versions, and the appendices (which are also currently unversioned but
|
||||
contain specification). Room versions are a bit more nuanced though, and are covered later in this MSC.
|
||||
|
||||
The version which covers the entire specification and all its parts is called the "Matrix version", and
|
||||
is a promotion of the previously marketing-only version number assigned to the spec. The first version
|
||||
after this proposal is expected to be Matrix 1.1, though the spec core team will make that decision.
|
||||
v1.0 would be left in the marketing era and recorded for posterity (though still retains no significant
|
||||
meaning).
|
||||
|
||||
Doing this has the benefits previously alluded to:
|
||||
|
||||
* Implementations of Matrix can now easily compare their supported versions using a single identifier
|
||||
without having to (potentially) indicate which API they built support for.
|
||||
* Publishing the specification is less likely to contain broken or outdated links due to API versions
|
||||
not matching up properly. This is currently an issue where if we want to release a new version of
|
||||
the server-server specification then we must also either rebuild or manually fix the blob of HTML
|
||||
known as the client-server API to account for the new version - we often forget this step, sometimes
|
||||
because it's just too difficult.
|
||||
* Explaining to people what version Matrix or any of the documents is at becomes incredibly simplified.
|
||||
No longer will we have to explain most of what the introduction to this proposal covers to every new
|
||||
person who asks.
|
||||
|
||||
### Full Matrix version grammar
|
||||
|
||||
The Matrix versioning scheme takes heavy inspiration from semantic versioning, though intentionally does
|
||||
not follow it for reasons described throughout this proposal. Primarily, the argument against semantic
|
||||
versioning is held in the alternatives section below.
|
||||
|
||||
Given a version number `MAJOR.MINOR`, incremement the:
|
||||
|
||||
* `MAJOR` version when a substantial change is made to the core of the protocol. This is reserved for
|
||||
interpretation by the Spec Core Team, though is intended to be for extremely invasive changes such
|
||||
as switching away from JSON, introducing a number of features where a `MINOR` version increase just
|
||||
doesn't feel good enough, or changes to the signing algorithms.
|
||||
* `MINOR` version when a feature is introduced, or a backwards incompatible change has been managed
|
||||
through the specification. Later on, this proposal explains what it means to manage a breaking change.
|
||||
|
||||
When present in the protocol itself, the Matrix version will always be prefixed with `v`. For example,
|
||||
`v1.1`.
|
||||
|
||||
Additional information can be supplied in the version number by appending a dash (`-`) to the end of the
|
||||
version and including any relevant information. This is typically used to denote alpha, beta, unstable,
|
||||
or other similar off-cycle release builds. This MSC does not propose a scheme for RCs or pre-releases,
|
||||
though the Spec Core Team may wish to do so. This can also be used to represent patch builds for the
|
||||
documentation itself, such as correcting spelling mistakes. An example would be `v1.1-patch.20210109`.
|
||||
|
||||
See the section on brewing Matrix versions for information on how the unstable version is decided.
|
||||
|
||||
`MINOR` versions have a backwards compatibility scheme described later in this proposal. `MAJOR`
|
||||
versions are expected to have zero backwards compatibility guarantees to them.
|
||||
|
||||
For clarity, `v1.2` will probably work with `v1.1`, though implementations should be wary if they
|
||||
depend on a version. As mentioned, the backwards compatibility scheme section goes into more detail on
|
||||
this.
|
||||
|
||||
Most notably, this MSC does not propose including a patch version at all. The specifics of what would
|
||||
be included in a patch version (spelling changes, release process bug fixes, etc) do not impact any
|
||||
implementations of Matrix and thus are not needing of a patch version.
|
||||
|
||||
### Structure changes and changelogs
|
||||
|
||||
The API documents remain mostly unchanged. We'll still have a client-server API, server-server API, etc,
|
||||
but won't have versions associated with those particular documents. This also means they would lose their
|
||||
individual changelogs in favour of a more general changelog. An exception to this rule is room versions,
|
||||
which are covered later in this proposal.
|
||||
|
||||
### Endpoint versioning
|
||||
|
||||
Under this MSC, all HTTP endpoints in the specification are to be per-endpoint versioned. This is already
|
||||
the case for all APIs except the Client-Server API, and so this section deals specifically with that API.
|
||||
The deprecation of endpoints is handled later in this proposal.
|
||||
|
||||
Under this proposal, all endpoints in the client-server API get assigned `v3` as their per-endpoint
|
||||
version as a starting point. This is primarily done to avoid confusion with the ancient client-server API
|
||||
versions which had `v1` and called the `rN` system "v2". Though many of the endpoints available today
|
||||
are not present in those older API editions, it is still proposed that they start at `v3` to avoid
|
||||
confusion with long-standing implementations.
|
||||
|
||||
Servers would advertise support for the new Matrix version by appending it to the array in `/versions`.
|
||||
If the sever also supports an older `rN` version, it would include those too.
|
||||
For example: `["v1.1", "r0.6.1"]`.
|
||||
|
||||
### Room versions
|
||||
|
||||
*Author's note*: Having many things with the root word "version" can be confusing, so for this section
|
||||
"room versions" are called "room editions" and the Matrix version refers to what this proposal is
|
||||
introducing. This MSC does not propose renaming "room versions" - that is another MSC's problem.
|
||||
|
||||
Room editions are a bit special in that they have their own versioning scheme as servers and, potentially,
|
||||
clients need to be aware of how to process the room. As such, a room edition's versioning scheme is not
|
||||
altered by this proposal, however the publishing of the (in)stability of a given edition is now covered by the
|
||||
newly proposed Matrix version.
|
||||
|
||||
Whenever a room edition transitions from stable to unstable, or unstable to stable, or is introduced
|
||||
then it would get counted as a feature for a `MINOR` release of Matrix. We don't currently have a plan
|
||||
to remove any room editions, so they are not covered as a potential process for this MSC.
|
||||
|
||||
### Deprecation approach
|
||||
|
||||
Previous to this proposal the deprecation approach was largely undocumented - this MSC aims to codify
|
||||
a standardized approach.
|
||||
|
||||
An MSC is required to transition something from stable (the default) to deprecated. Once something has
|
||||
been deprecated for suitably long enough (usually 1 version), it is eligible for removal from the
|
||||
specification with another MSC. Today's process is the same, though not defined explicitly.
|
||||
|
||||
The present system for deprecation also allows implementations to skip implementation of deprecated
|
||||
endpoints. This proposal does not permit such behaviour: for an implementation to remain compliant
|
||||
with the specification, it must implement all endpoints (including deprecated ones) in the version(s)
|
||||
it wishes to target.
|
||||
|
||||
As an example, if `/test` were introduced in v1.1, deprecated in v1.2, and removed in v1.3 then an
|
||||
implementation can support v1.1, v1.2, and v1.3 by implementing `/test` as it was defined in v1.2 (minus
|
||||
the deprecation flag). If the implementation wanted to support just v1.2 and v1.3, then it still must
|
||||
implement `/test`. If the implementation only wanted to support v1.3, then it *should not* implement
|
||||
`/test` at all because it was removed.
|
||||
|
||||
Generally deprecation is paired with replacement or breaking changes. For example, if `/v3/sync` were
|
||||
to be modified such that it needed to be bumped to `v4`, the MSC which does so would deprecate `/v3/sync`
|
||||
in favour of its proposed `/v4/sync`. Because endpoints are versioned on a per-endpoint basis, `/v4/sync`
|
||||
will still work with a server that supports `/v3/profile` (for example) - the version number doesn't mean
|
||||
an implementation can only use v4 endpoints.
|
||||
|
||||
## Potential issues
|
||||
|
||||
None appear to be relevant to be discussed on their own - they are discussed in their respective
|
||||
sections above when raised.
|
||||
|
||||
## Alternatives
|
||||
|
||||
There are some strong opinions that we should use proper semantic versioning for the specification
|
||||
instead of the inspired system proposed here. So, why shouldn't we use semantic versioning?
|
||||
|
||||
1. It's meant for software and library compatibility, not specifications. Though it could theoretically
|
||||
be used as a specification version, the benefits of doing so are not immediately clear. The scheme
|
||||
proposed here is simple enough where rudimentary comparisons are still possible between versions,
|
||||
and existing semantic versioning libraries can still be made to work. Further, the specification's
|
||||
version number should not be relied upon by a library for its versioning scheme - libraries,
|
||||
applications, etc should have their own versioning scheme so they may work independently of the
|
||||
spec's release schedule.
|
||||
|
||||
2. It has potential for causing very high major version numbers. Though largely an aesthetic concern,
|
||||
it can be hard to market Matrix v45 (or even Matrix v4) to potential ecosystem adopters due to
|
||||
the apparant unstable-ness of the specification. Similarly, the major version is used for advertising
|
||||
purposes which could be confusing or overly noisy to say there's a major version every few
|
||||
releases. By instead staying in the 1.x series for a long period of time, the specification appears
|
||||
stable and easy to work with, attracting potential adopters and making that 2.0 release feel all
|
||||
that more special.
|
||||
|
||||
3. The semantic versioning spec is not followed in practice. Most uses of semantic versioning are
|
||||
actually off-spec adaptations which are largely compatible with the ideals of the system. This, however,
|
||||
puts Matrix in a difficult spot as it would want to say we follow semantic versioning, but can't
|
||||
because there's no relevant specification document to link to. Even if there was, it would appear
|
||||
as though we were encouraging the idea of forking a specification as a specification ourselves,
|
||||
which may be confusing if not sending the wrong message entirely. Though the system proposed here
|
||||
is a reinvention of semantic versioning to a degree, this proposed system is different from how
|
||||
semantic versioning works in so many ways it is not entirely comparable.
|
||||
|
||||
4. The benefit of saying we use a well-popularized versioning system is not a strong enough argument
|
||||
to be considered here.
|
||||
|
||||
This MSC is also inherently incompatible with semantic versioning due to its approach to deprecation.
|
||||
Instead of encouraging breaking changes (removal of endpoints) be major version changes, this MSC
|
||||
says that happens at the minor version change level. As mentioned in the relevant section, this is
|
||||
not foreseen to be an issue for Matrix given its a system already used by the protocol and is common
|
||||
enough to at least be moderately familiar - the arguments for using semantic versioning in this respect
|
||||
do not hold up, per above.
|
||||
|
||||
## Security considerations
|
||||
|
||||
None relevant - if we need to make a security release for Matrix then we simply make a release and
|
||||
advertise accordingly.
|
||||
|
||||
## Unstable prefix
|
||||
|
||||
The author does not recommend that this MSC be implemented prior to it landing due to the complexity
|
||||
involved as well as the behavioural changes not being possible to implement. However, if an implementation
|
||||
wishes to try anyways, it should use `org.matrix.msc2844` in the `unstable_features` of `/versions`
|
||||
and use `/_matrix/client/unstable/org.matrix.msc2844` in place of `/_matrix/client/r0`.
|
||||
|
||||
This MSC is largely proven as possible through an in-development build of the specification which uses
|
||||
an alternative toolchain for rendering the specification: https://adoring-einstein-5ea514.netlify.app/
|
||||
(see the 'releases' dropdown in the top right; link may not be available or even the same as described
|
||||
here due to development changes - sorry).
|
Loading…
Reference in New Issue