As a subtask of clamsproject/mmif-python#12, I'd like to specify what three digits mean in the version space of MMIF.
Versioning principles
It is preferred that versions of sub-components are tied to each other. In an ideal world, all versions are exactly synchronized, but as we discuss here in the below, that is not very practically likely.
Type of changes and using digits
- version number format
x.y.z
: version numbers consist of three digits, each digit is positive integer
- major: major changes are breaking changes that are not backward compatible - any major change will increase
x
digit in the version number by 1.
- minor: minor changes add features - any minor change will increase
y
digit
- patch: patches are not adding any feature - any patch will increase
z
digit
MMIF components
As described in clamsproject/mmif-python#12, there are largely 5 sub-components;
- MMIF specification (
spec
hereinafter)
- either as a set of abstract API, or simply as documentation
- MMIF JSON schema (
schema
hereinafter)
- MMIF JSON-LD context (
context
hereinafter)
- MMIF reserved vocabulary (
vocab
hereinafter)
- MMIF serialization API implementation (
sdk
hereinafter)
td; dr
- updates in
schema
are most likely major
- updates in
vocab
are most likely minor (additions)
- updates in
sdk
are always patches, but not reflected to main spec
version
- no standalone updates in
context
- all five sub-components share
x
and y
digtis
spec
, schema
, context
, and vocab
share z
as well
sdk
never make major or minor changes
Areas of change
Changes in spec
Any changes in a sub-component would result in change in specification as well, and thus will increase the version number. Changes in specification that are not accompanied by changes in component(s) are not very imaginable, unless changes to fix typographical errors. Fixing typos should be a patch level version bump.
Changes in schema
Possible changes include (not limited to)
- addition of fields (e.g. introducing new metadata)
- re-organization of existing fields (e.g. changes in value types)
- deletion of fields (deprecation)
In terms of automatic JSON validation, an addition of a field/term can be non-breaking change unless the new field is required. All other changes are not backward compatible.
Changes in vocab
As there is not a forcible way of validating semantics of MMIF string using vocab
as validation source, backward compatibility must mean something different here. However, I'd like to suggest all additions (items, props of an item) to the ontology must be non-breaking and minor level version bump-ups.
Changes in context
Any addition of items in the vocab
or schema
should update context
as well. But changes originating from context
is not so likely.
Changes in sdk
In contrast to other components, sdk
is actual code, and is very prone to have software bugs. However, as sdk
is a mere implementation of what's defined and documented in the spec
, unless it's originated from updates of other components, all standalone changes in sdk
would be only fixing bugs, optimizing code, or adding supplementary (possibly undocumented) APIs. So those types of updates won't add (or change) any feature to the MMIF spec
. But, by its virtue, sdk
will receive a lot more patches compared to other components, thus I propose we untie patch number (z
) of sdk
from MMIF version.
Version binding
In conclusion, we want to stick to the principle of shared version numbers between all relevant components, however, because sdk
is more likely to receive frequent patches, patch number of sdk
needs to be independent from MMIF version.
Handling MMIF versions in consumers
We don't want to pose any restriction on consumer (e.g. MMIF visualizer) implementation. By publishing sdk
to version-controlled package repositories (e.g. pypi), we can expect a specific implementation of a consumer is tied to a specific version of MMIF (at least on x
and y
level). If a developer of such a consumer wants to support multiple versions of MMIF using our sdk
, it might not be trivial as the sdk
does not inherently support backward compatibility (by design), so the recommended way of support many versions would be maintaining different versions of the consumer software - which is not ideal (in fact a really bad practice, I believe). This leads us to a new question that might need its own issue card; namely, if it turned out that sdk
of older version (say 1.2.18) contains some critical bug after the main MMIF version went up with some major changes (say latest MMIF version is 2.1.0), do we need to fix the old sdk
and publish a new version (say 1.2.19)?