<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC6020 SYSTEM "reference.RFC.6020.xml">
<!ENTITY RFC7895 SYSTEM "reference.RFC.7895.xml">
<!ENTITY RFC7950 SYSTEM "reference.RFC.7950.xml">
<!ENTITY RFC8407 SYSTEM "reference.RFC.8407.xml">
<!ENTITY OPENCONFIG-YANG-CATALOG SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.openconfig-netmod-model-catalog.xml">
<!ENTITY CLAISE-SEMVER "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.claise-semver.xml">
<!ENTITY OPENCONFIG-YANG-CATALOG SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.openconfig-netmod-model-catalog.xml">
<!ENTITY CLACLA-NETMOD-MODEL-CATALOG "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.clacla-netmod-model-catalog.xml">
<!ENTITY VERDT-NETMOD-YANG-VERSIONING-REQS "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.verdt-netmod-yang-versioning-reqs.xml">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="4"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc updates="7950" category="std" ipr="trust200902" docName="draft-verdt-netmod-yang-semver-00">
<front>
<title abbrev="YANG Module Versioning">YANG Semantic Versioning for Modules</title>

<author initials="B." surname="Claise" fullname="Benoit Claise">
  <organization abbrev="Cisco Systems, Inc.">
    Cisco Systems, Inc.
 </organization>
  <address>
    <postal>
<street>De Kleetlaan 6a b1</street>
<city>1831 Diegem</city>
<country>Belgium</country>
    </postal>
    <phone>+32 2 704 5622</phone>
    <email>bclaise@cisco.com</email>
  </address>
</author>

  <author initials="J." surname="Clarke" fullname="Joe Clarke">
    <organization>Cisco Systems, Inc.</organization>
    <address>
      <postal>
        <street>7200-12 Kit Creek Rd</street>
        <city>Research Triangle Park</city>
        <region>North Carolina</region>
        <country>United States of America</country>
      </postal>
      <phone>+1-919-392-2867</phone>
      <email>jclarke@cisco.com</email>
    </address>
  </author>

  <author initials="R." surname="Rahman" fullname="Reshad Rahman">
  <organization abbrev="Cisco Systems, Inc.">
    Cisco Systems, Inc.
  </organization>
    <address>
      <email>rrahman@cisco.com</email>
    </address>
  </author>

  <author initials="R." role="editor" surname="Wilton" fullname="Robert Wilton">
  <organization abbrev="Cisco Systems, Inc.">
    Cisco Systems, Inc.
  </organization>
    <address>
      <email>rwilton@cisco.com</email>
    </address>
  </author>

  <author initials="B." surname="Lengyel" fullname="Balazs Lengyel">
    <organization abbrev="Ericsson"> Ericsson </organization>
    <address>
      <postal>
        <street>Magyar Tudosok Korutja</street>
        <city>1117 Budapest</city>
        <country>Hungary</country>
      </postal>
      <phone>+36-70-330-7909</phone>
      <email>balazs.lengyel@ericsson.com</email>
    </address>
  </author>

 <author initials="J." surname="Sterne" fullname="Jason Sterne">
 <organization abbrev="Nokia">
    Nokia
  </organization>
    <address>
      <email>jason.sterne@nokia.com</email>
    </address>
  </author>

<author initials="K." surname="D'Souza" fullname="Kevin D'Souza">
  <organization>AT&amp;T</organization>
  <address>
    <postal>
<street>200 S. Laurel Ave</street>
<city>Middletown</city>
<region>NJ</region>
<country>United States of America</country>
    </postal>
    <phone></phone>
    <email>kd6913@att.com</email>
  </address>
</author>



<date/>
<abstract>
  <t>This document specifies a new YANG module update procedure using
  semantic version numbers, to allow for limited
  non-backwards-compatible changes, as an alternative proposal to module
  update rules in the YANG 1.1 specifications.  This document updates
  RFC 7950, RFC 8407 and RFC 8525.</t>
</abstract>
</front>
<middle>
<section anchor="intro" title="Introduction">
  <t>This document defines a solution to the YANG module lifecycle
  problems described in <xref
  target="I-D.verdt-netmod-yang-versioning-reqs"/>, covering all of the
  specified requirements except for requirements: 2.2, 3.1, and 3.2.</t>

  <t>Specifically, this document recognises a need to sometimes allow
  YANG modules to evolve with non-backwards-compatible changes, which
  might end up breaking clients.  The solution makes use of semantic
  version numbers to help manage the lifecycle of YANG modules.</t>
  
  <t>
  The solution is comprised of the following seven parts:
       <list style="bullets">
       <t>A definition for the YANG semantic versioning scheme for
       modules, and an explanation of how the semver extension can be
       used to annotate modules with their semantic version
       number.</t>
       <t>A YANG extension to allow YANG module imports to be restricted
       to modules with particular semantic versions, allowing
       inter-module version dependencies to be captured within YANG
       module definitions.</t>
       <t>Updates to the YANG 1.1 module update rules to accommodate the
       semantic versioning scheme.</t>
       <t>Updates and augmentations to ietf-yang-library to include the
       YANG semantic version number in the module descriptions, to
       report how 'deprecated' and 'obsolete' nodes are handled by a
       server, and to clarify how module imports are resolved when
       multiple versions could otherwise be chosen.</t>
       <t>A YANG extension to add a 'description' statement to the YANG
       'status' statement to allow additional documentation as to why a
       node is being deprecated, and what alternatives may be
       available.</t>
       <t>A description of how YANG semantic versioning applies to YANG
       instance data.</t>
       <t>Guidelines to YANG module authors on how the YANG semantic
       versioning rules should be used, along with examples.</t>
     </list>
  </t>

  <t>Open issues are listed at <xref target="open_issues"/>, and
  tracked at <eref target="https://github.com/netmod-wg/yang-ver-dt/issues"/>.</t>

  <section anchor="changes" title="Updates to YANG RFCs">
    <section anchor="changes_7950" title="Updates to RFC7950">
      <t>This document proposes updates to <xref target="RFC7950"/> to
      address some of the requirements.  It should be noted that there
      is also active WG discussion on the next steps towards an updated
      version of YANG, and potentially some of the functionality
      described here could be folded into an updated revision of <xref
      target="RFC7950"/>, although that might adversely impact when
      (parts of) a standards based YANG module versioning solution is
      available.</t>

      <t>The sections listed below provide updates to <xref
      target="RFC7950"/>.  The design team does not believe any of the
      changes require a new version of the YANG language.  It is
      believed that the extensions as they are defined can coexist with
      existing YANG 1.1 clients.
	<list style="symbols">
	  <t><xref target="update_rules"/> describes modification
	  to the <xref target="RFC7950"/> Section 11 module update text
	  to advise the use of semantic versioning as described in this
	  document.</t>
	  <t><xref target="import_semver"/> describes an extension
	  to do import by semantic version.</t>
	  <t><xref target="deprecated_and_obsolete_reasons"/> defines an
	  extension that adds a description child element to the YANG
	  "status" statement.</t>
	</list>
      </t>
    </section>
    <section anchor="changes_rfc8525" title="Updates to RFC8525">
      <t>This document updates <xref target="RFC8525"/>.  <xref
      target="ietf_yang_library_updates"/> defines how a reader of a
      YANG library datastore schema chooses which version of an
      import-only module is used to resolve a module import when the
      definition is otherwise ambiguous.</t>
    </section>
    <section anchor="changes_rfc8407" title="Updates to RFC8407">
      <t><xref target="guidelines"/> updates <xref target="RFC8407"/> to
      provide guidelines on how the YANG module semantic versioning can
      be used to manage the lifecycle of YANG modules when using strict RFC
      7950 chapter 11 backwards compatibility rules are not pragmatic.</t>
    </section>    
  </section>

  <section anchor="other_solns" title="Complementary solutions for the other requirements">
    <t>This section is to aid the WG understand how the full set of YANG
    versioning requirements are intended to be holistically addressed
    and is intended to be removed if this draft is adopted by the WG.</t>
    <t>As stated previously, this draft does not address requirements
    2.2, 3.1 and 3.2 of the requirements specified in <xref
    target="I-D.verdt-netmod-yang-versioning-reqs"/>.  Instead,
    additional work is needed to address those requirements, which the
    design team believes would be best addressed in separate drafts.  It
    is hoped that the WG agrees that viable solutions to the other
    requirements exist that complement the solution proposed in this
    draft, and thus this work can usefully progress in parallel.  In
    particular, there is value to the industry to achieve
    standardization of a partial solution that addresses the majority,
    but not all, of the stated requirements, on the agreement that a
    full solution will follow.</t>
    <t>The two additional drafts are:</t>
    <t>A tooling based solution is proposed for requirement 2.2, that
    allows two YANG schema versions to be algorithmically compared, with
    the algorithm reporting the list of differences between the two YANG
    schema and whether each change is regarded as being editorial,
    backwards-compatible, or non-backwards-compatible.  Annotations to
    the YANG modules, via the use of extension statements, may help
    improve the accuracy of the comparison algorithm, particularly for
    statements that are very hard for an algorithm to correctly classify
    the scope of any differences (e.g., a change in the semantic
    behaviour of a data node defined via modifications to the associated
    YANG description statement).  Given that requirement 2.2 is a soft
    requirement (SHOULD rather than MUST), and practical experience with
    the tooling is required, it is proposed that this work is deferred
    at this time.</t>
    <t>A proposed solution for requirements 3.1 and 3.2 is via the use
    of YANG packages <xref target="I-D.rwilton-netmod-yang-packages"/>
    and a protocol based version selection scheme that can be used by
    clients to choose a particular YANG datastore schema from the set of
    datastore schema that are supported by the server.</t>
  </section>
</section>

<section anchor="semantic_versioning" title="YANG Semantic Versioning">
  <t>The chapter defines YANG Semantic Versioning, explains how it is
  used with YANG modules, and the rules associated with changing a
  module's semantic version number when the module definitions are
  updated.</t>

  <t>The YANG semantic versioning scheme applies only to YANG modules.
  YANG submodules are not independently versioned by the YANG semantic
  versioning scheme.  Instead, if a versioned module includes one or
  more submodules then those submodules are implicitly versioned as part
  of the module's 'semver:version' statements, and all the module's
  'include' statements MUST specify the revision-date for each of the
  included submodules.</t>


  <section anchor="version_classification" title="Classification of changes between module revisions">
    <t>The principle aim of YANG semantic versioning is to allow a user
    of a YANG module to understand the overall significance of any
    changes between two module revisions solely based on the semantic
    version number.</t>
    
    <t>The semantic version change between any two arbitrary revisions
    of a YANG module can be classified into one of four categories:
    'unchanged', 'editorial, 'backwards-compatible' or
    'non-backwards-compatible'.  A summary of the classification is
    given below, with the specific rules as they apply to YANG
    statements provided in <xref target="update_rules"/>.
    <list style="bullets">
      <t>The semantic version change between two module revisions is
      defined as 'unchanged' if, after excluding 'revision' and
      'semver:version' statements and their substatements, the only
      remaining changes are insignificant white space changes.</t>
      
      <t>An 'editorial' module semantic version change is where there
      are changes in the module's statements, between the two module
      revisions, but those changes do not affect the syntax or semantic
      meaning of the module in any way.  An example of an editorial
      change would be a fix to a spelling mistake in a description
      statement. </t>

      <t>A 'backwards-compatible' module semantic version change is
      where some syntax or semantic changes exists between the two
      module revisions, but all changes follow the rules specified in
      <xref target="bc_update_rules"/>.</t>

      <t>A 'non-backwards-compatible' module semantic version change is
      where some syntax or semantic changes exists between the two
      module revisions, and those changes do not follow the rules for a
      'backwards-compatible' version change.</t>
    </list>
    </t>
  </section>

       
  <section anchor="versioning_scheme" title="YANG Semantic Versioning Scheme for Modules">
    <t>This document defines the YANG semantic versioning scheme that is used for YANG
    modules. The versioning scheme has the following properties:
    <list style="bullets">
      <t>The YANG semantic versioning scheme is extended from version
      2.0.0 of the semantic versioning scheme defined at semver.org <xref
      target="semver"/> to cover the additional requirements for the
      management of YANG module lifecyles that cannot be addressed using
      the semver.org 2.0.0 versioning scheme alone.</t>
      
      <t>Unlike the semver.org 2.0.0 versioning scheme, the YANG
      semantic versioning scheme supports limited updates to older
      versions of YANG modules, to allow for bug fixes and enhancements
      to module versions that are not the latest.</t>

      <t>Module definitions that follow the semver.org 2.0.0 versioning
      scheme are fully compatible with implementations that understand
      the YANG semantic versioning scheme.</t>

      <t>If module updates are always restricted to the latest version
      of the module only, then the version numbers used by the YANG
      semantic versioning scheme are exactly the same as those defined
      by the semver.org 2.0.0 versioning scheme.</t>
    </list>
    </t>
    <t>Every YANG module versioned using the YANG semantic versioning
    scheme specifies the module's semantic version number by including
    the 'semver:module-version' statement according to the following
    rules:
    <list>
    <t>The module MUST include at least one revision statement.</t>
    <t>The most recent module revision statement MUST include a
    'semver:module-version' sub-statement, that defines the module's
    YANG semantic version.</t>
    <t>The preceding module revision statement SHOULD also include a
    'semver:module-version' sub-statement, to allow the module's
    semantic version history to be derived.</t>
    <t>All other revision statements MAY include a
    'semver:module-version' sub-statement if they have an associated
    YANG semantic version.</t>
    </list>
    </t>

    <t>
     "The YANG semver version number is expressed as a string of the
     form: 'X.Y.Zv'; where X, Y, and Z each represent non-negative
     integers smaller than 32768, and v represents an optional single
     character suffix: 'm' or 'M'.
     
     <list style="symbols">
       <t>'X' is the MAJOR version.  Changes in the major version number
       indicate changes that are non-backwards-compatible to versions
       with a lower major version number.</t>

       <t>'Y' is the MINOR version.  Changes in the minor version number
       indicate changes that are backwards-compatible to versions with
       the same major version number, but a lower minor version number
       and no patch 'm' or 'M' modifier.</t>

       <t>'Zv' is the PATCH version and modifier.  Changes in the patch
       version number can indicate editorial, backwards-compatible, or
       non-backwards-compatible changes relative to versions with the
       same major and minor version numbers, but lower patch version
       number, depending on what form modifier 'v' takes:
       <list style="symbols">
	 <t>If the modifier letter is absent, the change represents an
	 editorial change</t>
	 <t>'m' - the change represents a backwards-compatible change</t>
	 <t>'M' - the change represents a non-backwards-compatible change</t>
       </list>
       </t>
     </list>
    </t>
    <t>The YANG module name and YANG semantic version number uniquely
    identifies a revision of a module, with an associated revision date.
    There MUST NOT be multiple instances of a YANG module definition
    with the same module name and YANG semantic version number but
    different content or revision date.</t>
    <t>There MUST NOT be multiple versions of a YANG module that have
    the same MAJOR, MINOR and PATCH version numbers, but different patch
    modifier letter.  E.g., module version "1.2.3M" MUST NOT be defined
    if module version "1.2.3" has already been defined.</t>
    <section anchor="example_versions" title="Examples for YANG semantic version numbers">
      <t>The following diagram and explanation illustrates how YANG semantic version numbers work.</t>
      <figure>
        <preamble>Example YANG semantic version numbers for an example module:</preamble>
      <artwork>
        0.1.0
          |
        0.2.0
          |  
        1.0.0
          |  \
          |   1.1.0 -> 1.1.1m -> 1.1.2M
          |    |
          |   1.2.0 -> 1.2.1M -> 1.2.2M
          |    |
          |   1.3.0 -> 1.3.1
          |
        2.0.0
          |
        3.0.0
             \
              3.1.0
      </artwork>
    </figure>
    <t>The tree diagram above illustrates how an example modules version
    history might evolve.  For example, the tree might represent the
    following changes, listed in chronological order from oldest
    revision to newest:
    <list>
      <t>0.1.0  - first beta module version</t>
      <t>0.2.0  - second beta module version (with NBC changes)</t>
      <t>1.0.0  - first release (may have NBC changes from 0.2.0)</t>
      <t>1.1.0  - added new functionality, leaf "foo" (BC)</t>
      <t>1.2.0  - added new functionality, leaf "baz" (BC)</t>
      <t>1.3.0  - improve existing functionality, added leaf "foo-64" (BC)</t>
      <t>1.3.1  - improve description wording for "foo-64" (Editorial)</t>
      <t>1.1.1m - backport "foo-64" leaf to 1.1.x to avoid implementing "baz" from 1.2.0 (BC)</t>
      <t>2.0.0  - change existing model for performance reasons, e.g. re-key list (NBC)</t>
      <t>1.1.2M - NBC point bug fix, not required in 2.0.0 due to model changes (NBC)</t>
      <t>3.0.0  - NBC bugfix, rename "baz" to "bar"; also add new BC leaf "wibble"; (NBC)</t>
      <t>1.2.1M - backport NBC fix, changing "baz" to "bar"</t>
      <t>1.2.2M - backport "wibble".  This is a BC change but "M" modifier is sticky.</t>
      <t>3.1.0  - introduce new leaf "wobble" (BC)</t>
    </list>
    </t>
    <t>The partial ordering relationships based on the semantic versioning numbers can be defined as follows:
    <list>
      <t>1.0.0 &lt; 1.1.0 &lt; 1.2.0 &lt; 1.3.0 &lt; 2.0.0 &lt; 3.0.0 &lt; 3.1.0</t>
      <t>1.0.0 &lt; 1.1.0 &lt; 1.1.1m &lt; 1.1.2M</t>
      <t>1.0.0 &lt; 1.1.0 &lt; 1.2.0 &lt; 1.2.1M &lt; 1.2.2M</t>
    </list>
    </t>
    <t>There is no ordering relationship between 1.1.1M and either 1.2.0 or
    1.2.1M, except that they share the common ancestor of 1.1.0.</t>
    <t>Looking at the version number alone, the module definition in
    2.0.0 does not necessarily contain the contents of 1.3.0.  However,
    the module revision history in 2.0.0 would likely indicate that it
    was edited from module version 1.3.0.</t>
    </section>
  </section>
  
  <section anchor="semver_update_rules" title="YANG Semantic Version Update Rules">
    <t>When a new revision of a module is produced, then the following
    rules define how the YANG semantic version number for the new module
    revision is calculated, based on the changes between the two module
    revisions, and the YANG semantic version number of the base module
    revision that the changes are derived from.  A two step process is
    used:</t>

    <t>The first step is to classify the module change as 'editorial',
    'backwards-compatible', or 'non-backwards-compatible version' using
    the rules defined in <xref target="version_classification"/> and
    <xref target="update_rules"/>.</t>

    <t>The second step is to calculate the value of the 'semver:version'
    field for the new module revision, based on the value of the
    'semver:version' field in the base module, any how the module
    changes have been classified.</t>

    <t>The following rules define how the value for the 'semver:version'
    argument in the new module revision is calculated:
    <list style="numbers">
      <t>If a module is being updated in a non-backwards-compatible
      way, then the module version "X.Y.Z[m|M]" MUST be updated to
      "X+1.0.0" unless that module version has already been defined with
      different content, in which case the module version "X.Y.Z+1M MUST
      be used instead.</t>

      <t>If a module is being updated in a backwards-compatible way,
      then the next version number depends on the format of the current
      version number:
      <list style="format %i">
	<t>"X.Y.Z" - the module version MUST be updated to "X.Y+1.0",
	unless that module version has already been defined with
	different content, when the module version MUST be updated to
	"X.Y.Z+1m instead".</t>
	<t>"X.Y.Zm" - the module version MUST be updated to
	"X.Y.Z+1m".</t>
	<t>"X.Y.ZM" - the module version MUST be updated to
	"X.Y.Z+1M".</t>
      </list>
      </t>

      <t>If a module is being updated in an editorial way, then the next
      version number depends on the format of the current version
      number:
      <list style="format %i">
	<t>"X.Y.Z" - the module version MUST be updated to "X.Y.Z+1"</t>
	<t>"X.Y.Zm" - the module version MUST be updated to
	"X.Y.Z+1m".</t>
	<t>"X.Y.ZM" - the module version MUST be updated to
	"X.Y.Z+1M".</t>
      </list>
      </t>

      <t>YANG module semantic version numbers beginning with 0, i.e
      "0.X.Y" are regarded as beta definitions and need not follow the
      rules above.  Either the MINOR or PATCH version numbers may be
      updated, regardless of whether the changes are
      non-backwards-compatible, backwards-compatible, or editorial.</t>
    </list>
    </t>
  </section>
  <section anchor="semver_extension" title="YANG Module Semver Extension">
    <t>This document defines a YANG extension to add the YANG module
    semantic version to a Module.  The complete definition of this YANG
    module is in <xref target="yang_modules"/>.
    </t>

    <figure>
      <artwork>
        extension module-version {
          argument semver;
        }
      </artwork>
    </figure>
    <t>The extension would typically be used this way:
    </t>
    <figure>
      <artwork>
    module yang-module-name {

      namespace "name-space";
      prefix "prefix-name";

      import ietf-semver { prefix "semver"; }
      
      description
        "to be completed";

      revision 2018-02-28 {
        description "Added leaf 'wobble'";
        semver:module-version "3.1.0";
      }

      revision 2017-12-31 {
        description "Rename 'baz' to 'bar', added leaf 'wibble'";
        semver:module-version "3.0.0";
      }
	
      revision 2017-10-30 {
        description "Change the module structure";
        semver:module-version "2.0.0";
      }

      revision 2017-08-30 {
        description "Clarified description of 'foo-64' leaf";
        semver:module-version "1.3.1";
      }

      revision 2017-07-30 {
        description "Added leaf foo-64";
        semver:module-version "1.3.0";
      }

      revision 2017-04-20 {
        description "Add new functionality, leaf 'baz'";
        semver:module-version "1.2.0";
      }

      revision 2017-04-03 {
        description "Add new functionality, leaf 'foo'";
        semver:module-version "1.1.0";
      }

      revision 2017-04-03 {
        description "First release version.";
        semver:module-version "1.0.0";
      }

      revision 2017-01-30 {
        description "NBC changes to initial revision";
        semver:module-version "0.2.0";
      }

      revision 2017-01-26 {
        description "Initial module version";
        semver:module-version "0.1.0";
      }

      //YANG module definition starts here
      </artwork>
    </figure>
   <t>See also "Semantic Versioning and Structure for IETF
   Specifications" <xref target="I-D.claise-semver"/> for a mechanism to
   combine the semantic versioning, the GitHub tools, and a potential
   change to the IETF process.
    </t>
  </section>
</section>

<section title="Import by Semantic Version" anchor="import_semver">
  <t>RFC 7950 allows YANG module 'import' statements to optionally
  require the imported module to have a particular revision date.  In
  practice, importing a module with an exact revision date is overly
  burdensome because it requires the importing module to be updated
  whenever any change to the imported module occurs.  The alternative
  choice of using an import statement without a revision date is also
  not ideal because the importing module may not work with all possible
  revisions of the imported module.</t>

  <t>With semantic versioning, it is desirable for a importing module to
  specify the set of module versions of the imported module that are
  anticipated to be compatible.</t>
  
  <t>This document specifies a YANG extension for selecting which
  versions of a module may be imported.  It is designed around the
  assumption that most changes to a YANG module do not break importing
  modules, even if the changes themselves are not backwards compatible.
  E.g., fixing an incorrect pattern statement or description for a leaf
  would not break an import, changing the name of a leaf could break an
  import but frequently would not, but removing a container would break
  imports if it is augmented by another module.</t>

  <t>The ietf-semver module defines the 'version' extension, a
  substatement to the YANG 'import' statement.
  <list>
    <t>An 'import' statement MAY contain 'version' statements or a
    'revision-date' statement, but not both.</t>
    <t>The 'version' statement MAY be specified multiple times,
    requiring that the imported module version conforms to at least one
    of the 'version' statements.</t>
  </list>
  </t>

  <t>The argument to the 'version' statement takes one of three valid forms:
  <list style="numbers">
  <t>"A.B.C" - import the exact module version that matches "A.B.C".</t>
  <t>"A.B.C+" - import any module version that matches, or is
  greater than, "A.B.C".</t>
  <t>"A.B.C-X.Y.Z" - import any module version that matches, or is
  greater than, "A.B.C"; and also matches, or is less than, "X.Y.Z".
  The word "MAX" can be used for 'Y' or 'Z' to represent the numerical
  value 32,767.</t>
  </list></t>
  <t>The rules for comparing module version numbers are as follows:
  <list style="numbers">
    <t>Version "R.S.T" matches version "A.B.C", only if
    <list style="none">
      <t>R = A, S = B, and T = C</t>
    </list>
    </t>

    <t>Version "R.S.T" is greater than version "A.B.C", only if
    <list style="none">
      <t>R = A, S = B, and T > C; or</t>
      <t>R = A and S > B; or</t>
      <t>R > A</t>
    </list>
    </t>

    <t>Version "R.S.T" is less than version "X.Y.Z", only if
    <list style="none">
      <t>R = X, S = Y, and T &lt; Z; or</t>
      <t>R = X and S &lt; Y; or</t>
      <t>R &lt; X</t>
    </list>
    </t>
  </list>
  The patch modifier letter is not included as part of the
  'semver:version' argument, and is entirely ignored for import
  statement module version number comparisons.
  </t>
  <section title="Module import examples">
      <t>Consider an example module "example-module" that is
      hypothetically available in the following versions: 0.1.0, 0.2.0,
      1.0.0, 1.1.0, 1.1.1m, 1.1.2M, 1.2.0, 1.2.1M, 1.2.2M, 1.3.0, 1.3.1,
      2.0.0, 3.0.0, and 3.1.0.  E.g. matching the versions illustrated
      in <xref target="example_versions"/>.</t>

      <t>The first example selects the specific version 1.1.2M.  A
      specific version import might be used if 1.1.2M contained changes
      that are incompatible with other versions.</t>
      <figure>
        <artwork>
import example-module {
  semver:version 1.1.2;
}
       </artwork>
      </figure>

      <t>The next example selects module versions that match, or are
      greater than, version 1.2.0.  This form may be used if there is a
      dependency on a data node introduced in version 1.2.0.  This is
      expected to be the most commonly used form of 'import by version'.</t>
      <t>Includes versions: 1.2.0, 1.2.1M, 1.2.2M, 1.3.0, 1.3.1, 2.0.0,
      3.0.0 and 3.1.0.</t>
      <figure>
        <artwork>
import example-module {
  semver:version 1.2.0+;
}
        </artwork>
      </figure>

      <t>The next example selects module versions that match, or are
      greater than 1.1.0, but excluding all 1.1.x and 1.2.x 'M'
      versions.  This form may be needed if structural non backwards
      compatible changes are introduced in a patch 'M' version.
      Generally, it is advisable to avoid making such changes.</t>
      <t>Includes versions: 1.1.0, 1.1.1m, 1.2.0, 1.3.0, 1.3.1, 2.0.0,
      3.0.0, and 3.1.0.</t>
      <figure>
        <artwork>
import example-module {
  semver:version 1.1.0-1.1.1;
  semver:version 1.2.0;
  semver:version 1.3.0+;
}
        </artwork>
      </figure>

      <t>The last example selects all module versions with a major
      version number of 1.  This form may be useful if significant non
      backwards compatible changes have been introduced in version 2.0.0
      that break import backwards compatibility.</t>
      <t>Includes versions: 1.0.0, 1.1.0, 1.1.1m, 1.1.2M, 1.2.0, 1.2.1M,
      1.2.2M, 1.3.0 and 1.3.1.</t>
      <figure>
        <artwork>
import example-module {
  semver:version 1.0.0-1.MAX.MAX;
}
        </artwork>
      </figure>
  </section>
</section>

<section title="Classifying changes in YANG modules" anchor="update_rules">
  <t><xref target="RFC7950"/> chapter 11 defines the rules for what
  constitutes a backwards compatible change in YANG 1.1.  However, the
  YANG semantic versioning scheme defined in this document uses a
  slightly modified version of this scheme, and also provides rules to
  classify changes as editorial, backwards-compatible, or
  non-backwards-compatible.</t>
  <section anchor="editorial_update_rules" title="Editorial changes">
    <t>Any changes that do not change the ordering or meaning of the
    YANG module in any way are classified as 'editorial'.  The following
    rules define 'editorial':
   <list style="symbols">
     <t>Changing any 'description' statement if it does not change the
     semantic meaning of the statement is relates to.  E.g., fixing
     spelling or grammar, or changing layout, are all allowed.</t>
     <t>Adding or updating 'reference' statements.</t>
     <t>Adding or updating the 'organization' statement.</t>
     <t>Adding a new 'revision' or 'semver:module-version'
     statement, or correcting a previous 'revision' or
     'semver:module-version' statement.</t>
     <t>A module may be split into a set of submodules or a submodule
     may be removed, provided the definitions in the module do not
     change except in the ways described above.</t>
    </list></t>
  </section>
  <section anchor="bc_update_rules" title="Backwards-compatible changes">
    <t><xref target="RFC7950"/> chapter 11 defines the rules for what
    constitutes a backwards-compatible change in YANG 1.1.  The document
    update these rules in the following ways:
    <list style="symbols">
      <t>Adding or changing a 'status' node to 'obsolete' is not a
      backwards-compatible change.  Other changes/additions of status
      elements are backwards-compatible, as per <xref
      target="RFC7950"/>.</t>
      <t>Changing the ordering of statements is allowed if it does not
      chanage the ordering of an rpc's 'input' substatements.</t>
    </list></t>
  </section>
  <section anchor="nbc_update_rules" title="Non-backwards-compatible changes">
    <t>All other changes to YANG modules that are not classified as
    'editorial' or 'backwards-compatible' are defined as being
    non-backwards-compatible.</t>
    <t>Examples of non-backwards-compatible changes include:
    <list style="symbols">
      <t>Deleting a data node, or changing it to status obsolete.</t>
      <t>Changing the name, type, or units of a data node.</t>
      <t>Modifying the description in a way that changes the semantic
      meaning of the data node.</t>
      <t>Any changes that change or reduce the allowed value set of the
      data node, either through changes in the type definition, or the
      addition or changes to 'must' statements, or changes in the
      description.</t>
      <t>Adding or modifying 'when' statements that reduce when the data
      node is available in the schema.</t>
      <t>Making the statement conditional on if-feature.</t>
    </list></t>
  </section>
</section>

<section title="Updates to ietf-yang-library" anchor="ietf_yang_library_updates">
    <t>YANG library <xref target="RFC7895"/> <xref target="RFC8525"/> is
    modified to support semantic versioning in three ways.</t>

    <section title="Advertising module version number">
    <t>The ietf-semver YANG module augments the 'module' list in
    ietf-yang-library with a 'version' leaf to optionally declare the
    YANG semantic version of each module.</t>
    </section>
    <section title="Resolving ambiguous module imports">
      <t>A YANG datastore schema, defined in
      <xref target="RFC8525"/>, can specify multiple
      revisions of a YANG module in the schema using the 'import-only'
      list, with the requirement from <xref target="RFC7950"/> that only
      a single revision of a YANG module may be implemented.</t>
      <t>If a YANG module import statement does not specify a specific
      version or revision within the datastore schema then it could be
      ambiguous as to which module revision the import statement should
      resolve to.  Hence, a datastore schema constructed by a client
      using the information contained in YANG library may not exactly
      match the datastore schema actually used by the server.</t>
      <t>The following rules remove the ambiguity:</t>
      <t>If a module import statement could resolve to more than one
      module revision defined in the datastore schema, and one of those
      revisions is implemented (i.e., not an 'import-only' module), then
      the import statement MUST resolve to the revision of the module
      that is defined as being implemented by the datastore schema.</t>
      <t>If a module import statement could resolve to more than one
      module revision defined in the datastore schema, and none of those
      revisions are implemented, but one of more modules revisions
      specify a YANG semantic version, then the import MUST resolve to
      the module with the greatest version number, according to the
      version comparison rules in <xref target="import_semver"/>.</t>
      <t>If a module import statement could resolve to more than one
      module revision defined in the datastore schema, none of those
      revisions are implemented, and none of the modules revisions have
      a YANG semantic version number, then the import MUST resolve to
      the module that has the most recent revision date.</t>
    </section>
    <section title="Reporting how deprecated and obsolete nodes are handled">
      <t>The ietf-semver YANG module augments YANG library with two
      leaves to allow a server to report how it handles status
      'deprecated' and status 'obsolete' nodes.  The leaves are:
        <list style="hanging">
          <t hangText="deprecated-nodes-implemented:">If present, this
          leaf indicates that all schema nodes with a status
          'deprecated' child statement are implemented equivalently as
          if they had status 'current', or otherwise deviations MUST be
          used to explicitly remove 'deprecated' nodes from the schema.
          If this leaf is absent then the behavior is unspecified.</t>
          <t hangText="obsolete-nodes-absent:">If present, this leaf
          indicates that the server does not implement any status
          'obsolete' nodes.  If this leaf is absent then the behaviour
          is unspecified.</t>
         </list>
     </t>
     <t>Implementations that implement the YANG semantic versioning
     scheme defined in this document MUST set the
     'deprecated-nodes-implemented' leaf because the refined module
     update rules in <xref target="update_rules"/> require that this is
     how servers handle 'deprecated' and 'obsolete' nodes to comply with
     YANG module semantic versioning.</t>
     <t>If a server does not set the 'deprecated-nodes-implemented'
     leaf, then clients MUST NOT rely solely on the YANG module semantic
     version number to determine whether two module versions are
     backwards compatible, and MUST also consider whether the status of
     any nodes has changed to 'deprecated' and whether those nodes are
     implemented by the server.</t>
    </section>
  </section>

  <section title="YANG status description extension" anchor="deprecated_and_obsolete_reasons">
    <t>The ietf-semver module specifies the YANG extension
    'status-description' that can be used as a substatement of the
    status statement.  The argument to this extension can contain
    freeform text to help readers of the module understand why the node
    was deprecated or made obsolete, when it is anticipated that the
    node will no longer be available for use, and potentially reference
    other schema elements that can be used instead.  An example is shown
    below.</t>

      <figure>
        <artwork>
leaf imperial-temperature {
  type int64;
  units "degrees Fahrenheit";
  status deprecated {
    semver:status-description
      "Imperial measurements are being phased out in favor
       of their metric equivalents.  Use metric-temperature
       instead.";
  }
  description
    "Temperature in degrees Fahrenheit.";
}
        </artwork>
      </figure>
    </section>

<section title="Semantic versioning of YANG instance data">
<t>Instance data sets <xref
target="I-D.ietf-netmod-yang-instance-file-format"/> do not have an
associated YANG semantic version, as compatibility for instance data is
undefined.</t>

<t>However, instance data may reference an associated YANG schema, and
that schema could make use of semantic version numbers, both for the
individual YANG modules that comprise the schema, and potentially for
the entire schema itself (e.g., <xref
target="I-D.rwilton-netmod-yang-packages"/>).</t>

<t>In this way, the versioning of a schema associated with an instance
data set, may allow a client to determine whether the instance data
could also be used in conjunction with other versions of the YANG
schema, or other versions of the modules that define the schema.</t>

<t>One common scenario, where instance data may have to cope with
changes to the schema is for the &lt;startup&gt; datastore when a server
is restarted with a different YANG schema (e.g. due to a software
upgrade or downgrade).  How a server restores the configuration from
&lt;startup&gt; during such upgrades or downgrades is outside the scope
of this specification.</t>
</section>

<section anchor="guidelines" title="Guidelines">
   <section anchor="guidelines_authors" title="Guidelines to YANG model authors">
      <t>NBC changes to YANG models may cause problems to clients, who are consumers of YANG models, and SHOULD be 
         avoided.  However, there are cases where NBC changes are required, e.g. to fix an incorrect YANG model.</t>
      <t>YANG model authors are recommended to minimize NBC changes and keep changes BC whenever possible.</t>
      <t>The use of status "deprecated" with the status-description statement allows clients to plan a migration to alternative 
         data nodes.</t>
      <t>When NBC changes are introduced, consideration should be given to the impact on clients and YANG model authors SHOULD 
         try to mitigate that impact.</t>
      <section anchor="authors_semver" title="Use of YANG semantic versioning">
	<t>Module authors should use the following guidance when applying the module version update rules specified in <xref target="semver_update_rules"/>.</t>
	<t>Updates to modules SHOULD be applied to the latest version of
	YANG modules, avoiding the use the 'm|M' patch modifier.  When
	used in this way, the YANG semantic version numbers are
	compatible with the versioning scheme defined by the semver.org
	2.0.0 rules.</t>
	<t>Changes to older versions of published YANG modules SHOULD be
	minimized, since there may be a greater impact on clients, and
	comparing between version numbers becomes more limited if the
	'm|M' modifiers are used.  However, if it is necessary to make such
	changes then the following guidelines apply:
	<list>
	  <t>Any changes SHOULD also be made to a new latest version of the YANG module, if appropriate.</t>
	  <t>Where possible, changes SHOULD be restricted to backwards-compatible changes only.</t>
	  <t>NBC changes MAY be made, subject to the constraints defined in <xref target="semver_update_rules"/>. The impact to clients SHOULD be carefully considered and minimized if possible.</t>
	</list>    
	</t>
	<t>The version numbers associated with a module MUST never be reused.  E.g., when updating module version 3.4.0 in a NBC manner the module author must verify whether version 4.0.0 is available for use and if that version was already used, the updated module must use version 3.4.1M instead.</t> 
	<t>Patch modifier letters (i.e. 'm' or 'M') are sticky.  For example if version 3.4.1M is modified in a BC way, the next
         version is 3.4.2M. This is to indicate that 3.4.2M is not BC with 3.4.0, however it comes at the cost of not being able to indicate the 
         type of  change between 3.4.1M and 3.4.2M.</t>
      <t>As explained in <xref target="implementation_experience"/>, while programatically determining a semantic version is possible
         using tools (e.g. the pyang utility), human oversight is highly recommended because of some special cases which can not be detected by tools.
         Therefore, a model author SHOULD use both means to determine a model's semantic version.</t>
       </section>
       <section title="Making non-backwards-compatible changes to a YANG module">
       <t>There are various valid situations where a YANG module has to be modified in a non-backwards-compatible way. Here are the different ways in which this can be done:
          <list style="symbols">
             <t>If the server can support NBC versions of the YANG module simultaneously using version selection, then the NBC changes MAY be done immediately.  Clients would be required to select the version which they support and the NBC change would have no impact on them.</t>
             <t>When possible, NBC changes are done incrementally to provide clients time to adapt to NBC changes.</t>
          </list>
       </t>
       <t>Here are some guidelines on how non-backwards compatible changes can be made incrementally:
          <list style ="numbers">
             <t>The changes should be made incrementally, e.g. a data node's status SHOULD NOT be changed directly from "current" to "obsolete" (see Section 4.7 of <xref target="RFC8407"/>), instead the status SHOULD first be marked "deprecated" and then when support is removed its status MUST be changed to "obsolete". Instead of using the "obsolete" status, the data node MAY be removed from the model but this has the risk of breaking modules which import the modified module.</t>
             <t>A node with status "deprecated" MUST be supported for the solution described here to function properly.</t>
             <t>A node with status "deprecated" SHOULD be available for at least one year before its status is changed to "obsolete", see Section 4.7 of <xref target="RFC8407"/>.</t>
             <t>Support for a node which is "obsolete" is indicated by the node "obsolete-nodes-present, see <xref target="ietf_yang_library_updates"/>.</t>
             <t>The new extension "status-description" SHOULD be used for nodes which are "obsolete" or "deprecated".</t>
             <t>For status "deprecated", the "status-description" SHOULD also indicate until when support for the node is guaranteed. If there is a replacement data node, rpc, action or notification for the deprecated node, this SHOULD be stated in the "status-description".</t>
             <t>When obsoleting or deprecating data nodes, the "deprecated" or "obsolete" status SHOULD be applied at the highest possible level in the data tree. For example, when deprecating all data nodes in a container, the "deprecated" status SHOULD be applied to the container. For clarity, the status MAY be added in all the affected nodes but the status-description SHOULD be added only at the highest level in the tree.</t>            
          </list>
          </t>
         <t>The following sections have examples on how non-backwards-compatible changes can be made.</t>

         <section anchor="remove_bode" title="Removing a data node">
            <t>Removing a leaf or container from the data tree, e.g. because support for the corresponding feature is being removed:
            <list style="numbers">
               <t>The node's status SHOULD be changed to "deprecated" and it MUST be supported for at least one year. This is a backwards-compatible change.</t>
               <t>When the node is not available anymore, its status MUST be changed to "obsolete" and the "status-description" updated, this is a non-backwards-compatible change. The "status-description" SHOULD be used to explain why the node is not available anymore.</t>
            </list>
            </t>
         </section>

         <section anchor="type_change" title="Changing the type of a leaf node">            
            <t>Changing the type of a leaf-node. e.g. consider a "vpn-id" node of type integer being changed to a string:
            <list style="numbers">
               <t>The status of node "vpn-id" SHOULD be changed to "deprecated" and the node SHOULD be available for at least one year. This is a backwards-compatible change.</t>
               <t>A new node, e.g. "vpn-name", of type string is added to the same location as the existing node "vpn-id". This new node has status "current" and its description SHOULD explain that it is replacing node "vpn-id".</t>
               <t>During the period of time where both nodes are available, how the server behaves when either node is set is outside the scope of this document and will vary on a case by case basis. Here are some options:
               <list style="numbers">
                  <t>A server MAY prevent the new node from being set if the old node is already set (and vice-versa). The new node MAY have a when statement to achieve this. The old node MUST NOT have a when statement since this would be a non-backwards-compatible change, but the server MAY reject the old node from being set if the new node is already set.</t>
                  <t>If the new node is set and a client does a get or get-config operation on the old node, the server MAY map the value. For example, if the new node "vpn-name" has value "123" then the server MAY return integer value 123 for the old node "vpn-id". However, if the value can not be mapped, we need a way of returning "unsupported" TBD.</t>
               </list>
               </t>
               <t>When node "vpn-id" is not available anymore, its status MUST be changed to "obsolete" and the "status-description" is updated. This is a non-backwards-compatible change.</t>
            </list>
            </t>
         </section>
         
         <section anchor="range_reduction" title="Reducing the range of a leaf node">
         </section>

         <section anchor="key_change" title="Changing the key of a list">
         </section>

         <section anchor="rename_node" title="Renaming a node">
         </section>

         <section anchor="default_change" title="Changing a default value">
         </section>

       </section>
   </section>
   <section anchor="guidelines_clients" title="Guidelines to YANG model clients">
     <t>Guidelines for clients of modules using YANG semantic versioning:
         <list style="symbols">
            <t>Clients SHOULD be liberal when processing data received from a server. For example, the server may have increased the range of an operational node causing the client to receive a value which is outside the range of the YANG model revision it was coded against</t>
            <t>Clients SHOULD monitor changes to published YANG modules through their version numbers, and use appropriate tooling to understand the specific changes between module versions.  In particular, clients SHOULD NOT migrate to NBC versions of a module without first understanding the specifics of the NBC changes.</t>
            <t>Clients SHOULD plan to make changes to match published status changes. When a node's status changes from "current" to "deprecated", clients SHOULD plan to stop using that node in a timely fashion. When a node's status changes to "obsolete", clients MUST stop using that node.</t>
         </list> 
      </t>
   </section>
</section>

<section anchor="yang_modules" title="Semantic Version Extension YANG Modules">
  <t>
    <figure>
      <preamble> YANG module with extensions for defining a module's
      YANG semantic version number, and importing by version.</preamble>
      <artwork><![CDATA[
<CODE BEGINS> file "ietf-semver@2019-02-07.yang"
module ietf-semver {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-semver";
  prefix semver;

  organization
    "IETF NETMOD (Network Modeling) Working Group";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
     WG List:  <mailto:netmod@ietf.org>

     Author:   Benoit Claise
               <mailto:bclaise@cisco.com>

     Author:   Joe Clarke
               <mailto:jclarke@cisco.com>

     Author:   Reshad Rahman
               <mailto:rrahman@cisco.com>

     Author:   Robert Wilton
               <mailto:rwilton@cisco.com>

     Author:   Kevin D'Souza
               <mailto:kd6913@att.com>

     Author:   Balazs Lengyel
               <mailto:balazs.lengyel@ericsson.com>

     Author:   Jason Sterne
               <mailto:jason.sterne@nokia.com>";
  description
    "This module contains a definition for a YANG 1.1 extension to
     express the semantic version of YANG modules.";

  revision 2019-02-27 {
    description
      "* Move YANG library augmentations into a separate module.
       * Update references.";
    reference
      "draft-verdt-netmod-yang-semver: 
       YANG Semantic Versioning for Modules";
    semver:module-version "0.3.0";
  }

  revision 2018-04-05 {
    description
      "* Properly import ietf-yang-library.
       * Fix the name of module-semver => module-version.
       * Fix regular expression syntax.
       * Augment yang-library with booleans as to whether or not
         deprecated and obsolete nodes are present.
       * Add an extension to enable import by semantic version.
       * Add an extension status-description to track deprecated
         and obsolete reasons.
       * Fix yang-library augments to use 7895bis.";
    reference
      "draft-clacla-netmod-yang-model-update:
       New YANG Module Update Procedure";
    semver:module-version "0.2.1";
  }
  revision 2017-12-15 {
    description
      "Initial revision.";
    reference
      "draft-clacla-netmod-yang-model-update:
       New YANG Module Update Procedure";
    semver:module-version "0.1.1";
  }

  typedef version {
    type string {
      pattern '[0-9]{1,5}\.[0-9]{1,5}\.[0-9]{1,5}(m|M)?';
    }
    description
      "The type used to represent a YANG semantic version number.

      The YANG semver version number is expressed as a string of the
      form: 'X.Y.Zv'; where X, Y, and Z each represent non-negative
      integers smaller than 32768, and v represents an optional
      single character suffix: 'm' or 'M'.

      o 'X' is the MAJOR version.  Changes in the major version
        number indicate changes that are non-backwards-compatible to
        versions with a lower major version number.

      o 'Y' is the MINOR version.  Changes in the minor version
         number indicate changes that are backwards-compatible to
         versions with the same major version number, but a lower
         minor version number.

     o 'Zv' is the PATCH version and modifier.  Changes in the patch
        version number can indicate editorial, backwards-compatible,
        or non-backwards-compatible changes relative to versions with
        the same major and minor version numbers, but lower patch
        version number, depending on what form modifier 'v' takes:

        *  'M' - the change represents a non-backwards-compatible
                 change

        *  'm' - the change represents a backwards-compatible change

        * If the modifier letter is absent, the change represents an
          editorial change";

    reference
      "draft-verdt-netmod-yang-semver: YANG Semantic Versioning";
  }
  
  extension module-version {
    argument semver;
    description
      "The version number for the module revision it is used in.
       
       This format of the argument matches the type version.

       The rules for updating the module-version number are described
       in section XXX of 'YANG Semantic Versioning for Modules';

       By comparing the module-version between two revisions of a
       given module, one can determine if different revisions are
       backwards compatible or not, as well as whether or not new
       features have been added to a newer revision.

       If a module contains this extension it indicates that for this
       module the updated status and update rules as this described
       in RFC XXXX are used.

       The statement MUST only be a substatement of the 'revision'
       statements.  Zero or one module-version statement is allowed
       per parent statement. No substatements are allowed.

       'revision' statements in submodules MAY contain a
       'module-version' statement for documentation purposes, but
       its meaning is undefined, and has no effect on the including
       module's semantic version.";
    reference
      "draft-verdt-netmod-yang-semver: 
       YANG Semantic Versioning for Modules";
  }

  extension import-versions {
    argument version-clause;
    description
      "This extension specifies an acceptable set of semantic
       versions of a given module that may be imported.
         
       The statement MUST only be a substatement of the import
       statement.

       The statement MUST NOT be present if the import has a
       revision-date substatement.

       The statement MUST NOT be present if the imported module does
       not support semantic versioning.

       Zero or more versions statements are allowed per parent
       statement.  No substatements are allowed.
        
       The version-clause argument MUST follow one of the below
         patterns:
           (i)  "+' \d+\.\d+\.\d+ '+" 
             Matches exact version, e.g. 3.6.1
            
           (ii) "+ '\d+\.\d+\.\d+\+ '+"
             Matches exact version or greater, e.g. 3.6.1+

           (iii) "+' \d+\.\d+.\d+-\d+\.(\d+|MAX).(\d|MAX)+ '+"
             Matches inclusive range,
             e.g. 3.6.1-7.8.4, or 3.2.1-3.MAX.MAX";

    reference
      "draft-verdt-netmod-yang-semver: Import by Semantic Version";
  }

  extension status-description {
    argument description;
    description
      "Freeform text that describes why a given node has been
       deprecated or made obsolete.  This may point to other schema
       elements that can be used in lieu of the given node.

       This statement MUST only be used as a substatement of the
       status statement

       Zero or more status-description statements are allowed per
       parent statement.  No substatements are allowed.";
    reference
      "draft-verdt-netmod-yang-semver: YANG status description
       extension";
  }
}
<CODE ENDS>
]]></artwork>
</figure>
<figure>
  <preamble>YANG module with augmentations to YANG Library to support
  semantic version numbers.</preamble>
      <artwork><![CDATA[
<CODE BEGINS> file "ietf-yl-semver@2019-02-07.yang"
module ietf-yl-semver {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-yl-semver";
  prefix yl-semver;

  import ietf-semver {
    prefix semver;
  }
  
  import ietf-yang-library {
    prefix yanglib;
  }

  organization
    "IETF NETMOD (Network Modeling) Working Group";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
     WG List:  <mailto:netmod@ietf.org>

     Author:   Benoit Claise
               <mailto:bclaise@cisco.com>

     Author:   Joe Clarke
               <mailto:jclarke@cisco.com>

     Author:   Reshad Rahman
               <mailto:rrahman@cisco.com>

     Author:   Robert Wilton
               <mailto:rwilton@cisco.com>

     Author:   Kevin D'Souza
               <mailto:kd6913@att.com>

     Author:   Balazs Lengyel
               <mailto:balazs.lengyel@ericsson.com>

     Author:   Jason Sterne
               <mailto:jason.sterne@nokia.com>";
  description
    "This module contains augmentations to YANG Library to add module
     level semantic version numbers and to provide an indication of
     how deprecated and obsolete nodes are handled by the server.";

    semver:module-version "0.1.0";

  revision 2019-02-27 {
    description
      "Moved YANG library augmentations into a separate module.";
    reference
      "draft-verdt-netmod-yang-semver: 
       YANG Semantic Versioning for Modules";
    semver:module-version "0.1.0";
  }

  augment "/yanglib:yang-library/yanglib:module-set/yanglib:module" {
    description
      "Augmentation modules with a semantic version.";
    leaf version {
      type semver:version;
      description
        "The semantic version for this module.  The version MUST
         match the semver:version value in specific revision of the
         module loaded in this module-set.";
      reference
        "draft-verdt-netmod-yang-semver: YANG Semantic Versioning";
    }
  }

  augment "/yanglib:yang-library/yanglib:schema" {
    description
      "Augmentations to the ietf-yang-library module to indicate how
       deprecated and obsoleted nodes are handled for each datastore
       schema supported by the server.";

    leaf deprecated-nodes-implemented {
      type empty;
      description
        "If present, this leaf indicates that all schema nodes with a
         status 'deprecated' child statement are implemented
         equivalently as if they had status 'current', or otherwise
         deviations MUST be used to explicitly remove 'deprecated'
         nodes from the schema.  If this leaf is absent then the
         behavior is unspecified.";
      reference
        "draft-verdt-netmod-yang-semver: Reporting how deprecated and
         obsolete nodes are handled";
    }
    leaf obsolete-nodes-absent {
      type empty;
      description
        "If present, this leaf indicates that the server does not
         implement any status 'obsolete' nodes.  If this leaf is
         absent then the behaviour is unspecified.";
      reference
        "draft-verdt-netmod-yang-semver: Reporting how deprecated and
         obsolete nodes are handled";
    }
  }
}
<CODE ENDS>
]]></artwork>
</figure>
</t>
</section>

<section anchor="contributor" title="Contributors">
  <t>This document grew out of the YANG module versioning design team
  that started after IETF 101. The design team consists of the following
  members whom have worked on the YANG versioning project:</t>
      <t>
        <list style="symbols">
          <t>Balazs Lengyel</t>
          <t>Benoit Claise</t>
          <t>Ebben Aries</t>
          <t>Jason Sterne</t>
          <t>Joe Clarke</t>
          <t>Juergen Schoenwaelder</t>
          <t>Mahesh Jethanandani</t>
          <t>Michael (Wangzitao)</t>
          <t>Qin Wu</t>
          <t>Reshad Rahman</t>
          <t>Rob Wilton</t>
        </list>
      </t>

   <t>The initial revision of this document was refactored and built
   upon <xref target="I-D.clacla-netmod-yang-model-update"/>.</t>
   <t>Discussons on the use of Semver for YANG versioning has been held
   with authors of the OpenConfig YANG models.  We would like thank both
   Anees Shaikh and Rob Shakir for their input into this problem
   space.</t>
</section>

<section anchor="security" title="Security Considerations">
  <t>The document does not define any new protocol or data model.  There
  are no security impacts.</t>
</section>
<section anchor="iana" title="IANA Considerations">
  <section anchor="yang-module-registrations" title="YANG Module Registrations">
  <t>The following YANG module is requested to be registred in the "IANA
  Module Names" registry:</t>

  <t>The ietf-semver module:</t>

  <t><list>
    <t>Name: ietf-semver</t>
    <t>XML Namespace: urn:ietf:params:xml:ns:yang:ietf-semver</t>
    <t>Prefix: semver</t>
    <t>Reference: [RFCXXXX]</t>
  </list></t>
  <t>The ietf-yl-semver module:</t>

  <t><list>
    <t>Name: ietf-yl-semver</t>
    <t>XML Namespace: urn:ietf:params:xml:ns:yang:ietf-yl-semver</t>
    <t>Prefix: yl-semver</t>
    <t>Reference: [RFCXXXX]</t>
  </list></t>
</section>
</section>
</middle>
<?rfc needLines="20"?>
<back>
<references title="Normative References">
   <?rfc include='reference.RFC.7950'?>
   <?rfc include='reference.RFC.7895'?>
   <?rfc include='reference.RFC.8407'?>
   <?rfc include='reference.RFC.8525'?>
   <?ref include='reference.I-D.verdt-netmod-yang-versioning-reqs'?>
</references>
<references title="Informative References">
   <?rfc include='reference.I-D.openconfig-netmod-model-catalog'?>
   <?rfc include='reference.I-D.claise-semver'?>
   <?rfc include='reference.I-D.clacla-netmod-yang-model-update'?>
   <?rfc include='reference.I-D.clacla-netmod-model-catalog'?>
   <?rfc include='reference.I-D.ietf-netmod-yang-instance-file-format'?>
   <?rfc include='reference.I-D.rwilton-netmod-yang-packages'?>
   <reference anchor="openconfigsemver" target="http://www.openconfig.net/docs/semver/">
     <front>
      <title>Semantic Versioning for Openconfig Models</title>
      <author/>
      <date/>
    </front>
   </reference>
      <reference anchor="semver" target="https://www.semver.org">
      <front>
       <title>Semantic Versioning 2.0.0</title>
       <author/>
       <date/>
    </front>
   </reference>
   <reference anchor="yangcatalog" target="https://yangcatalog.org">
     <front>
       <title>YANG Catalog</title>
       <author/>
       <date/>
     </front>
   </reference>
</references>
<?rfc needLines="100"?>

<section anchor="appendix" title="Appendix">
  <section anchor="open_issues" title="Open Issues">
    <t>Open issues are being tracked at <eref target="https://github.com/netmod-wg/yang-ver-dt/issues"/>.  Currently open issues are:
      
      <list style="symbols">
        <t>Do we need a new version of YANG? <eref target="https://github.com/netmod-wg/yang-ver-dt/issues/14">#14</eref></t>
	<t>Add guidance text about warning NBC changes might break imports <eref target="https://github.com/netmod-wg/yang-ver-dt/issues/11">#11</eref></t>
	<t>Add a naming convention for versioned YANG file<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/13">#13</eref></t>
	<t>Define editorial, bc, nbc impact of adding, changing, removing extension stmts<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/12">#12</eref></t>
	<t>How to version modules in IETF drafts (after they have been published at 1.0.0 or later<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/10">#10</eref></t>
	<t>The solution does not strictly support semver 2.0.0<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/9">#9</eref></t>
	<t>Are whitespace changes allow between two module instances with the same version (or revision)?<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/8">#8</eref></t>
	<t>Do we assume that a module has an implicit semver if none as been specified?<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/7">#7</eref></t>
	<t>Is changing the ordering of nodes an NBC change?<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/6">#6</eref></t>
	<t>Should version statement be at top level or under revision statement?<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/5">#5</eref></t>
	<t>Figure out whether changing the imports constitute a BC or NBC change<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/4">#4</eref></t>
	<t>Does BC or NBC depend on whether the node is config true/false?<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/15">#15</eref></t>
	<t>Status obsolete nodes<eref target="https://github.com/netmod-wg/yang-ver-dt/issues/2">#2</eref></t>
      </list>
    </t>
  </section>
  <section anchor="derived_semver" title="Derived Semantic Version">
    <t>This temporary text is intended to be moved to a separate draft
    the describes the tool based approach for versioning YANG modules
    mentioned in <xref target="other_solns"/>.</t>
    <section anchor="the_derived_semantic_versioning" title="The Derived Semantic Version">
      <t>
	If an explicitly defined semantic version is not available in
	the YANG module, it is possible to algoritmically calculate a
	derived semantic version. This can be used for modules not
	containing a definitive semantic-version as defined in this
	document or as a starting value when specifying the definitive
	semantic-version. Be aware that this algorithm may sometimes
	incorrectly classify changes between the categories
	non-compatible, compatible or error-correction.
	</t>
    </section>
    <section anchor="implementation_experience" title="Implementation Experience">
      <t>
	<xref target="yangcatalog"/> uses the pyang utility to calculate
	the derived-semantic-version for all of the modules contained
	within the catalog.  <xref target="yangcatalog"/> contains many
	revisions of the same module in order to provide its
	derived-semantic-version for module consumers to know what has
	changed between revisions of the same module.
      </t>
      <t>
	Two distinct leafs in the YANG module <xref target="I-D.clacla-netmod-model-catalog"/> contain this semver notation:
      </t>
      <t>
	<list style="symbols">
	  <t>the semantic-version leaf contains the value embedded
	  within a YANG module (if it is available).
	  </t>
	  <t>the derived-semantic-version leaf is established by
	  examining the the YANG module themselves.  As such
	  derived-semantic-version only takes syntax into account as
	  opposed to the meaning of various elements when it computes
	  the semantic version.</t>

	  <t>The algorithm used to produce the derived-semantic-version is as follows:
            <list style="numbers">
              <t>Order all modules of the same name by revision from
              oldest to newest.  Include module revisions that are not
              available, but which are defined in the revision
              statements in one of the available module versions. </t>
              <t>If module A, revision N+1 has failed compilation, bump
              its derived semantic MAJOR version.  For unavailable
              module versions assume non-backward compatible changes
              were done., thus bump its derived semantic MAJOR
              version.</t>
              <t>Else, run "pyang --check-update-from" on module A,
              revision N and revision N+1 to see if
              backward-incompatible changes exist.</t>
              <t>If backward-incompatible changes exist, bump module A,
              revision N+1's derived MAJOR semantic version.</t>
              <t>If no backward-incompatible changes exist, compare the
              pyang trees of module A, revision N and revision N+1.</t>
              <t>If there are structural differences (e.g., new nodes),
              bump module A, revision N+1's derived MINOR semantic
              version.</t>
              <t>If no structural differences exist, bump module A,
              revision N+1's derived PATCH semantic version.</t>
            </list>
          </t>
	</list>
      </t>
      <t>
	The pyang utility checks many of the points listed in section 11
	of <xref target="RFC7950"/> for known module incompatibilities.
	While this approach is a good way to programmatically obtain a
	semantic version number, it does not address all cases whereby a
	major version number might need to be increased.  For example, a
	node may have the same name and same type, but its meaning may
	change from one revision of a module to another.  This
	represents a semantic change that breaks backward compatibility,
	but the above algorithm would not find it.  Therefore,
	additional, sometimes manual, rigor must be done to ensure a
	proper version is chosen for a given module revision.
      </t>
    </section>
  </section>
</section>
</back>
</rfc>
<!-- Local Variables: -->
<!-- fill-column:72 -->
<!-- End: -->
