Purpose of MDRS (Module Dependencies)
This month we encountered some problems with the MDRS (as a result of publishing a couple of new modules), which led to questions around the purpose of the Module Dependency Refset which has potentially evolved over the years.
So our scenario is we are now publishing an (optional) module within our release. The module contains a simple type reference set. The members of the simple type refset come from both core and the AU-extension. So we stated the following dependencies.
Optional Module → SNOMED CT-AU
Optional Module → SNOMED CT core
Optional Module → SNOMED CT model component
However, there's apparently an argument that the MDRS describes the the Edition dependencies. I don't agree with that, but it does raise the question how is an 'Edition defined' (if not by the MDRS)?
(Edition being a specific set of modules). This is probably a relatively new problem, as most editions (as far as I'm aware) only use a single module. So the module dependency as I describe earlier ALSO defines the edition. However when there's optional modules (like ours) these are two different things. The likely solution we're looking at is to have one module that represents our "Edition", and another that holds our "Extension content". To date Edition and Extension have been represented by the same moduleId.
I think the main issue here is that the MDRS is being used for two purposes.
When originally created with RF2, the MDRS allowed a module author to describe the module's dependencies - that is all the other modules and version of those modules that are required by this module. This is a common idea in software development where a component/module/library defines the other components/modules/libraries it uses/references and therefore depends on and needs if it is to be used. For Java developers Maven is a good example of this where dependencies on other Maven artefacts is explicitly declared, including the version of each.
Then there's the idea of an edition. A set of RF2 release files can contain any bucket of interdependent or independent modules, however an edition describes a set of modules to be used together and are versioned as a unit by a release centre. In the RF2 sense, a set of RF2 files can contain exactly the edition, no more and no less, or a set of RF2 files can contain multiple editions at the same time.
In order to define which modules an edition is comprised of, the URI specification references the module dependency reference set and the declared module dependencies of a module to represent the composition of an edition. That is the module dependencies of the module identified in an edition URI describe the versioned modules the edition is composed of.
To me, these are both valid and important pieces of metadata - for each version of each module which other versions of other modules are needed, and for an edition (for example the SNOMED CT-AU Edition) which set of modules (and their versions) are included in that version of that edition.
The problem occurs when a module is both a module (i.e. it contains content) that needs to express its dependencies on content in other modules, and is an edition which needs to express its composition. These are two different sets of statements and can differ.
Taking our example we have a module, SNOMED CT-AU, which contains content that depends on SNOMED CT Core. We also have a new module of content we want to attribute to a third party but release on their behalf, lets call that the X module. The X module references and therefore depends on content in the SNOMED CT-AU module. So naturally the dependencies are
X module → SNOMED CT-AU
X module → SNOMED CT Core (transitive but explicitly stated)
SNOMED CT-AU → SNOMED CT Core
There's all the other metadata modules at play too, but I've limited it to these to keep it simple. Our authoring tooling requires the dependencies to be set when classifying and attributing classification results to modules, as well as module versioning during release.
The problem is that SNOMED CT-AU is also our edition, and as such we need to express the edition's composition. We want to include X module in our edition publication, and allow Australian vendors to reference X module concepts using the code system version URI of the SNOMED CT-AU edition. Other tools (for example Ontoserver/Shrimp) use the module dependency reference set to determine what content is in scope when referring to a particular edition. So the required composition is
SNOMED CT-AU → X module
SNOMED CT-AU → SNOMED CT Core
If we declare both the dependencies and the composition we get
X module → SNOMED CT-AU (dependency)
X module → SNOMED CT Core (transitive dependency but explicitly stated)
SNOMED CT-AU → SNOMED CT Core (dependency and composition)
SNOMED CT-AU → X module (composition)
Which causes a cyclic dependency between SNOMED CT-AU and X module which is explicitly prohibited in the specification at 5.2.4.2 Module Dependency Reference Set.
One way to resolve this would be for the edition module to contain no content. That way the MDRS can be used to describe composition for that module and dependency for the other modules. We could create a new module (lets call it A) and "promote" all of SNOMED CT-AU's content to that module. That lets us define the edition composition for SNOMED CT-AU and the content dependencies on A - effectively we can separate the two.
X module → A module
X module → SNOMED CT Core (transitive but explicitly stated)
A module → SNOMED CT Core
SNOMED CT-AU → SNOMED CT Core
SNOMED CT-AU → X module
SNOMED CT-AU → A module
But it is a bit ugly because it is hard to tell when the rows in the module dependency reference set are describing an actual content dependency (which can be calculated from the content) versus composition.
I think the questions to answer are
do we need to define module content dependencies?
do we need to define edition composition?
do we want to do both with the same mechanism?
I think if the answer to those is all true, then you end up needing the edition modules to be "terminal" in the dependency chain (like SNOMED CT Core is or SNOMED CT-AU was) or empty so they can declare their composition without conflicting with the content dependencies.