<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent">
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<?rfc compact="no" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="std" consensus="true" docName="draft-birrane-dtn-adm-04" ipr="trust200902" submissionType="IETF" symRefs="true" tocInclude="true" version="3" xml:lang="en">
  <front>
    <title abbrev="ADM">DTNMA Application Data Model</title>
    <seriesInfo name="Internet-Draft" value="draft-birrane-dtn-adm-04"/>
    <author fullname="Edward J. Birrane, III" initials="E.J." surname="Birrane">
      <organization abbrev="JHU/APL">The Johns Hopkins University Applied Physics Laboratory</organization>
      <address>
        <postal>
          <street>11100 Johns Hopkins Rd.</street>
          <city>Laurel</city>
          <region>MD</region>
          <code>20723</code>
          <country>US</country>
        </postal>
        <phone>+1 443 778 7423</phone>
        <email>Edward.Birrane@jhuapl.edu</email>
      </address>
    </author>
    <author fullname="David Linko" initials="D." surname="Linko">
      <organization abbrev="JHU/APL">The Johns Hopkins University Applied Physics Laboratory</organization>
      <address>
        <email>David.Linko@jhuapl.edu</email>
      </address>
    </author>
    <author fullname="Brian Sipos" initials="B." surname="Sipos">
      <organization abbrev="JHU/APL">The Johns Hopkins University Applied Physics Laboratory</organization>
      <address>
        <email>brian.sipos+ietf@gmail.com</email>
      </address>
    </author>
    <date/>
    <area>Transport</area>
    <workgroup>Delay-Tolerant Networking</workgroup>
    <keyword>DTN</keyword>
    <keyword>Network Management</keyword>
    <keyword>Autonomy</keyword>
    <abstract>
      <t>
         This document defines a data model that captures the 
         information necessary to asynchronously manage applications.
         This model 
         provides a set of common type definitions, data structures, and a 
         template for publishing standardized representations of model elements.
      </t>
    </abstract>
  </front>
  <middle>
    <section>
      <name>Introduction</name>
      <t>
         The DTN Management Architecture (DTNMA) <xref target="I-D.ietf-dtn-dtnma"/>
         defines a concept for the open-loop control of applications (and protocols) 
         in situations where timely, highly-available connections cannot exist 
         among managing and managed nodes in a network. While the DTNMA 
         provides a conceptual information model, it does not include details 
         necessary to produce interoperable data models.
      </t>
      <section>
        <name>Scope</name>
        <t>
This document defines a two-level data model suitable for managing applications in accordance with the DTNMA.
The two levels of model are:
        </t>
        <ol>
          <li>
A meta-model for the DTNMA, called the Application Management Model (AMM), which defines the object structures and literal-value types used in the DTNMA in a concrete way.
          </li>
          <li>
An object model, based on the AMM meta-model, which is used in static Application Data Models (ADMs) and dynamic Operational Data Models (ODMs) as instances of the AMM within an Agent.
          </li>
        </ol>
        <t>
This document also defines a text representation of an ADM using the types and structures defined by the AMM combined with the syntax and processing semantics of YANG modules <xref target="RFC7950"/>.
With this representation, individual applications can capture their static management information in YANG modules. 
        </t>
        <t>
Although this document defines a representation for the ADM, it does not define a representation for the objects and literal values modeled by the ADM/ODM. 
In order to communicate values between DTNMA Agents and Managers in a network, the model must be encoded for transmission.
Any such encoding scheme is outside of the scope of this document. 
Generally, the encoding of the model is a separate concern from the specification of data within the model.  
        </t>
        <t>           
            Because different networks may use different encodings for data, 
            mandating an encoding format would require incompatible networks to 
            encapsulate data in ways that could introduce inefficiency and 
            obfuscation. It is envisioned that different networks would be able 
            to encode values in their native encodings such that the translation 
            of ADM data from one encoding to another can be completed using 
            mechanical action taken at network borders.
        </t>
        <t>
            Since the specification does not mandate an encoding format, the 
            AMM and ADM must provide enough information to make encoding (and 
            translating from one encoding to another) an unambiguous process. 
            Therefore, where necessary, this document provides identification, 
            enumeration and other schemes that ensure ADMs contain enough 
            information to prevent ambiguities caused by different encoding 
            schemes. 
        </t>
      </section>
      <section>
        <name>Terminology</name>
        <t>
         The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
         "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
         document are to be interpreted as described in <xref target="RFC2119"/>.
        </t>
        <t>
         The terms "Actor", "Agent", "Externally Defined Data",
         "Variable", "Constant", Control", "Literal", "Macro", "Manager", 
         "Operator", "Report", "Report Template", "Rule", "State-Based Rule", 
         "Table", "Table Template", and "Time-Based Rule" are used without 
         modification from the definitions provided in <xref target="I-D.ietf-dtn-dtnma"/>.
        </t>
        <t>
         Additional terms defined in this document are as follows.  
        </t>
        <dl>
          <dt>Application:</dt>
          <dd>
A software implementation running on an Agent and being managed by a Manager.
This includes software that implements protocol processing on an Agent.
          </dd>
          <dt>Application Management Model (AMM):</dt>
          <dd>
The object and literal-value model defined by this document in <xref target="sec-amm"/> and implemented as instances in ADMs and ODMs.
          </dd>
          <dt>Application Resource Identifier (ARI):</dt>
          <dd>
A unique identifier for any AMM object and literal value, syntactically conformant to the Uniform Resource Identifier (URI) syntax documented in <xref target="RFC3986"/> and using the scheme name "ari".
          </dd>
          <dt>Application Data Model (ADM):</dt>
          <dd>
The set of statically-defined objects necessary to manage an application asynchronously.
This is also the name for the text-based syntax used to express the contents of that ADM, as defined in <xref target="sec-yang"/>.
          </dd>
          <dt>Operational Data Model (ODM):</dt>
          <dd>
The set of dynamically-defined objects created and controlled by Managers in the network.
          </dd>
          <dt>Namespace:</dt>
          <dd>
Each ADM and ODM has a universally unique identifier and acts as a namespace for a set of AMM objects.
          </dd>
        </dl>
      </section>
    </section>
    <section anchor="sec-conops">
      <name>Data Modeling Concept of Operations</name>
      <t>
In order to asynchronously manage an application in accordance with the <xref target="I-D.ietf-dtn-dtnma"/>, an application-specific data model must be created containing static structure for that application. 
This model is termed the Application Data Model (ADM) and forms the core set of information for that application in whichever network it is deployed.
ADM structure and base ADMs are discussed in detail in <xref target="sec-adm"/>.
      </t>
      <t>
The objects codified in the ADM represents static configurations and definitions that apply to any deployment of the application, regardless of the network in which it is operating.
Within any given network, Managers supplement the information provided by ADMs with dynamic objects.
Each namespace of dynamic objects is termed an Operational Data Model (ODM) and is discussed in detail in <xref target="sec-odm"/>.
      </t>
      <t>
Both the ADMs and ODMs rely on a common meta-model, the Application Management Model of <xref target="sec-amm"/>, which defines the basic structure of what kinds of types and objects are available to use within the DTNMA. 
The relationships among the AMM, ADM, and ODM are illustrated in <xref target="fig-models"/>.
Together, the set of objects in the union of all supported ADMs with dynamic ODM objects forms the data model used to manage an Agent.
      </t>
      <t>
While an agent hosts the actual object instances, each manager must contain the corresponding ADM and ODM definitions in order to identify and interact with those objects.
Those interactions are performed using Application Resource Identifiers (ARIs) as depicted in <xref target="fig-agent-manager"/>.
      </t>
      <figure align="center" anchor="fig-models">
        <name>Data Model Relationships</name>
        <artwork align="center" xml:space="preserve">
      +---------------+
      |      AMM      |
      | (object types)|
      +-------^-------+
              |
      +-------+-------+
      |               |
+-----+-----+   +-----+-----+
|    ADM    |   |    ODM    |
|(instances)|   |(instances)|
+-----------+   +-----------+
           </artwork>
      </figure>
      <figure align="center" anchor="fig-agent-manager">
        <name>Agent and Manager Interaction</name>
        <artwork align="center" xml:space="preserve">
+------------------------------------------+
|                                          |
|  +-------+  +-------+         +-------+  |
|  | ADM 1 |  | ADM 2 |         | ODM 1 |  |
|  | def'n |  | def'n |         | def'n |  |'
|  +-------+  +-------+         +-------+  |
|           ...                    ...     |
|        +-------+              +-------+  |
|        | ADM N |              | ODM M |  |
|        | def'n |              | def'n |  |
|        +-------+              +-------+  |
|            Manager instance              |
+------------------------------------------+
                     ^^
                     ||
                 ARI values
                     ||
                     vv
+------------------------------------------+
|                                          |
|  +-------+  +-------+         +-------+  |
|  | ADM 1 |  | ADM 2 |         | ODM 1 |  |
|  | objs  |  | objs  |         | objs  |  |
|  +-------+  +-------+         +-------+  |
|           ...                    ...     |
|        +-------+              +-------+  |
|        | ADM N |              | ODM M |  |
|        | objs  |              | objs  |  |
|        +-------+              +-------+  |
|              Agent instance              |
+------------------------------------------+
           </artwork>
      </figure>
      <section anchor="sec-conops-values">
        <name>Values and Value-Producing Objects</name>
        <t>
The ARI of <xref target="I-D.birrane-dtn-ari"/> is used as the basis for the values used internally for <xref format="title" target="sec-conops-proc"/> activities and for the basis of <xref format="title" target="sec-conops-msg"/> contents.
        </t>
        <t>
Of the value-producing object types discussed in <xref target="sec-obj"/> and <xref target="sec-proc-prod"/>, the functions of these objects are summarized and compared with literals in <xref target="tab-val-objs"/> and the following list.
In that table, "internal" means values are managed by the Agent itself and "external" means the source of values is outside the Agent.
        </t>
        <dl>
          <dt><xref format="title" target="sec-value-lit"/>:</dt>
          <dd>
            <t>
ARI literals are, by definition, immutable and fully self-contained values.
            </t>
            <t>
For example, the number 4 is a literal value.
The name "4" and the value 4 represent the same thing and are inseparable.
Literal values cannot change ("4" could not be used to mean 5) and they are defined external to the autonomy model (the autonomy model is not expected to redefine what 4 means).
            </t>
          </dd>
          <dt><xref format="title" target="sec-obj-const"/>:</dt>
          <dd>
            <t>
These objects are named values which are defined in specific revisions of an ADM and produced directly by the Agent implementing the ADM.
Both the name and the value of the constant are fixed and cannot be changed (within a revision).
            </t>
            <t>
An example of a constant would be defining the numerical value <em>pi</em> to some predetermined precision.
            </t>
          </dd>
          <dt><xref format="title" target="sec-obj-var"/>:</dt>
          <dd>
            <t>
These objects are named value storage entities which are defined in ADMs or ODMs and managed by the Agent implementing the ADM or ODM.
While the name is constant the value can change over time due to controls acting upon the Agent.
One standard interface is an ADM-defined initial state expression with a control available to reset to that initial state (which can itself reference other value producing objects and operators).
Another standard interface is a control to set a variable to a specific value.
            </t>
            <t>
An example of a variable using just its initial expression would be an accumulator summing together a list of counter values produced by other objects.
An example of a manager-controlled variable would be a threshold value used to compare against a sensor value in a rule predicate.
            </t>
          </dd>
          <dt><xref format="title" target="sec-obj-edd"/>:</dt>
          <dd>
            <t>
These objects are named entities which are defined in an ADM but produce values based on data provided to an Agent from its environment.
These values are the foundation of state-based autonomy as they capture the state of the managed device.
The autonomy model treats these values as read-only state.
It is an implementation matter to determine how external data is transformed into values of the specific type specified for an EDD.
            </t>
            <t>
Examples of externally defined values include temperature sensor readings and the instantaneous data rate from a modem or radio.
            </t>
          </dd>
        </dl>
        <table anchor="tab-val-objs">
          <name>Value-Producing Object Types</name>
          <thead>
            <tr>
              <th/>
              <th>Immutable</th>
              <th>Mutable</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <th>Internal</th>
              <td>CONST</td>
              <td>VAR</td>
            </tr>
            <tr>
              <th>External</th>
              <td>LIT</td>
              <td>EDD</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="sec-conops-proc">
        <name>Agent Processing</name>
        <t>
Based on the reasoning described in <xref target="I-D.ietf-dtn-dtnma"/>, much of the closed-loop processing of the state of the DTNMA Agent is performed on the Agent itself using rule objects.
The different types of processing performed on the Agent are separated into <xref format="title" target="sec-proc-exec"/>, <xref format="title" target="sec-proc-eval"/>, and <xref format="title" target="sec-proc-rpt"/> with corresponding AMM object types related to each of these as indicated in <xref target="tab-proc-objs"/> (<em>e.g.</em>, execution relates to CTRL objects but not OPER objects).
Some of the objects defined in the <xref target="sec-agentadm">Agent ADM</xref> combine the use of these processing activities, but they are still independent of each other.
There is no mixing of activities such as executing a control within an expression; although the execution of a control can result in an expression being evaluated they are independent activities.
        </t>
        <t>
Within the runtime of an Agent any input, output, and intermediate values can use the concept of a <xref target="sec-type-semantic">semantic type</xref> to do things like restrict the valid numeric range of a value or allow a union of disjoint types to be present (<em>e.g.</em>, a certain value can be a boolean or an unsigned integer).
This is combined with the literal types available from the ARI to allow complex type information to be present in an ADM or ODM without requiring additional over-the-wire encoding size.
A <xref format="title" target="sec-proc-cast"/> activity is defined for when implicit or explicit type conversion is needed.
        </t>
        <table anchor="tab-proc-objs">
          <name>Processing Activities and Object Types</name>
          <thead>
            <tr>
              <th>Activity</th>
              <th>Objects</th>
              <th>Values</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Execution</td>
              <td>CTRL</td>
              <td>MAC</td>
            </tr>
            <tr>
              <td>Evaluation</td>
              <td>OPER, TYPEDEF</td>
              <td>EXPR</td>
            </tr>
            <tr>
              <td>Reporting</td>
              <td>
                <em>N/A</em></td>
              <td>RPTT</td>
            </tr>
            <tr>
              <td>Value Production</td>
              <td>CONST, EDD, VAR</td>
              <td>
                <em>N/A</em></td>
            </tr>
            <tr>
              <td>Type Casting</td>
              <td>TYPEDEF</td>
              <td>
                <em>N/A</em></td>
            </tr>
            <tr>
              <td>Rule Autonomy</td>
              <td>SBR, TBR</td>
              <td>
                <em>N/A</em></td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="sec-conops-msg">
        <name>Agent-Manager Messaging</name>
        <t>
This document does not define a messaging protocol between agents and managers but full functioning of this data model behavior does rely on the following types of messages being available:
        </t>
        <dl>
          <dt>Execute:</dt>
          <dd>
This message causes an <xref format="title" target="sec-proc-exec"/> of a referenced parameterized <xref target="sec-obj-ctrl">CTRL object</xref> or produced <xref target="typedef-mac">MAC value</xref>.
This type of message is only sent from Manager to Agent.
An optional field of this message is an opaque correlator "nonce" which can be used to indicate that the result of the corresponding CTRL execution is desired to be reported back to the Manager.
Each message can reference multiple execution sources (CTRL and MAC) and, unlike the MAC execution itself, can be handled by executing multiple items in parallel.
It is an implementation detail whether a Manager sends fewer messages with more sources or more timely messages with fewer sources.
          </dd>
          <dt>Report:</dt>
          <dd>
This message carries the <xref target="typedef-rpt">RPT values</xref> generated by <xref format="title" target="sec-proc-rpt"/> activities.
This type of message is only sent from Agent to Manager.
One field of the report message is a correlator nonce which is used to associate report items with specific Execute messages which caused the reports to be generated.
Each message can contain multiple RPT values but all must be associated with the same nonce, although it is an implementation detail whether an Agent sends fewer report messages with more report values or more timely messages with fewer values.
          </dd>
        </dl>
        <t>
The contents of these messages, individual fields, are representable by ARI values so require only small additional message-type identifying and framing overhead to bind to whatever transport is being used (<em>e.g.</em> the Bundle Protocol).
        </t>
      </section>
    </section>
    <section anchor="sec-amm">
      <name>Application Management Model (AMM)</name>
      <t>
This section describes the Application Management Model, which is the meta-model used to implement the DTNMA.
This section also provides additional information necessary to work with this model, such as: literal value types, object structure, naming conventions, and processing semantics.
      </t>
      <t>
The overall AMM is decomposed into two categories: 
      </t>
      <dl>
        <dt>Objects:</dt>
        <dd>
These are the structural and behavioral elements of the AMM, present in ADMs and ODMs.
Objects implement the actual purpose of the applications being managed; they extract values from the Agent's environment, operate on expressions, store variables, and execute controls to affect the Agent's environment.
Because objects are behavioral they have no complete static representation, objects are only ever described and identified.
AMM object types are defined in <xref target="sec-obj"/> and objects are instantiated as part of an ADM or ODM.
        </dd>
        <dt>Values:</dt>
        <dd>
These are the runtime state and intermediates of the AMM, present in the Agent's state but not directly in ADMs or ODMs.
Objects produce, operate on, and store or consume values and these values are what are present in messaging between Managers and Agents.
AMM values are explained in more detail in <xref target="sec-value"/>.
        </dd>
      </dl>
      <section anchor="sec-value">
        <name>AMM Values</name>
        <t>
Values within the AMM have two top-level classes: literal values, and object references. 
Each of these is discussed more detail in the following subsections.
Both classes of AMM values are related to what can be represented externally as an ARI, as described in <xref target="sec-ari"/>.
        </t>
        <section anchor="sec-value-lit">
          <name>Literal (LIT)</name>
          <t>
As defined in the DTNMA, Literal (LIT) values are those whose value and identifier are equivalent.
These are the most simple values in the AMM.
For example, the literal "4" serves as both an identifier and a value.
          </t>
          <t>
Because the value of a Literal object serves as its identifier, there is no concept of a parent namespace or parameters.
A literal can be completely identified by its data type and data value.
          </t>
          <t>
Literals have two layers of typing: 
          </t>
          <dl>
            <dt>Literal Type:</dt>
            <dd>
This is the lower layer which defines the syntax of the literal value and bounds the domain of the value (<em>e.g.</em> a <tt>BOOL</tt> has two possible values, while an <tt>INT</tt> has a large domain of integers).
There are a small number of literal types and they are managed with an IANA registry defined in <xref section="9.3" target="I-D.birrane-dtn-ari"/>.
            </dd>
            <dt>Semantic Type:</dt>
            <dd>
This is the higher layer which defines additional semantics to a value, such as a restricted domain of values or a human-friendly text unit or limits on the items of an ARI collection.
Semantic types are defined within ADMs (see <xref target="sec-type-semantic"/> and <xref target="sec-obj-typedef"/>), so there can be an arbitrary number of them and they are managed outside of a central authority.
            </dd>
          </dl>
          <t>
All literal values have a concrete and stand-alone representation independent of any ADM or ODM behavior in the form of an <xref target="sec-ari">ARI</xref>, but when represented as an ARI a value loses its semantic type.
          </t>
        </section>
        <section anchor="sec-value-objref">
          <name>Object Reference (OBJ-REF)</name>
          <t>
Every object in the AMM is uniquely identifiable, regardless of whether the item is defined statically in an ADM or dynamically in an ODM.
Object reference values are composed of four parts: a namespace, an object type, an object name, and object-specific optional parameters.
          </t>
          <t>
AMM objects are identified within unique namespaces to prevent conflicting names within network deployments, particularly in cases where network operators are allowed to define their own object names.
In this capacity, namespaces exists to eliminate the chance of a conflicting object name.
They MUST NOT be used as a security mechanism.
An Agent or Manager MUST NOT infer security information or access control based solely on namespace information.
          </t>
          <t>Two categories of namespaces available within the OBJ-REF and the ARI syntax:</t>
          <dl>
            <dt>ADM Namespace:</dt>
            <dd>These are defined, with text-name and enumeration, in an IANA registry of ADMs in <xref section="9.3" target="I-D.birrane-dtn-ari"/>. There is also a reservation of private-use code points for domain- and mission-specific ADMs. In ARI form, ADM namespaces are present as either their name or enumeration directly.</dd>
            <dt>ODM Namespace:</dt>
            <dd>These are defined, with text-name and enumeration, in an IANA registry of ODMs in <xref section="9.3" target="I-D.birrane-dtn-ari"/>. It is expected that most ODM use will be domain- and mission-specific. In ARI form, ODM namespaces are present as a "!" prefixed name or as a negative-value enumeration.</dd>
          </dl>
          <t>
Object types, each with a text-name and enumeration, are defined in an IANA registry by <xref section="9.3" target="I-D.birrane-dtn-ari"/>.
          </t>
          <t>
Object names are text strings and enumerations whose value is determined by the creator of the object.
For those objects defined in an ADM, the structure of the object name is given in <xref target="sec-obj-metadata"/>.
          </t>
          <section anchor="sec-value-objref-params">
            <name>Parameters</name>
            <t>
Parameterization is used in the AMM to enable expressive autonomous function and reduce the amount of traffic communicated between Managers and Agents.
In the AMM, most objects can be parameterized and the meaning of parameterization for each object type is defined in <xref target="sec-obj"/> with behaviors related to parameters defined in <xref target="sec-proc"/>.
            </t>
            <t>
There are two notions of parameters defined in the AMM, which take their name from computer programming vernacular used for discussing function declarations and function calls, those are: formal parameters and actual parameters.
Formal parameters are discussed in <xref target="sec-obj-metadata"/> and actual parameters are discussed here in relation to the object reference.
            </t>
            <t>
Actual parameters represent the data values passed to a parameterized AMM Object at runtime.
They "fulfill" the parameter requirements defined by the formal parameters for that object.
Each object type can have a slightly different notion of how its parameters affect its processing activities. 
            </t>
            <t>
An actual parameter MUST specify a value and MAY specify a type. 
If a type is provided it MUST match the type provided by the formal parameter.
            </t>
            <t>
There are two ways in which the value of an actual parameter can be used:
            </t>
            <dl>
              <dt anchor="param-by-value">Parameter by Value:</dt>
              <dd>
This method involves directly supplying the value as part of the actual parameter.
It is the most direct method for supplying values.
              </dd>
              <dt anchor="param-by-label">Parameter by Label:</dt>
              <dd>
This method involves supplying the <tt>LABEL</tt> of some other processing-context-specific value and substituting, at runtime, that named value as the value of this parameter.
This method is useful when a parameterized AMM Object contains a value that references another parameterized AMM Object.
The contained object's actual parameter can be given as the <tt>LABEL</tt> of the containing object's parameter. 
In this way, a containing object's parameters can "flow down" to all of the objects it references. 
              </dd>
            </dl>
            <t>
In cases where a formal parameter contains a default value, the associated actual parameter may be omitted. Default values in formal parameters (and, thus, optional actual parameters) are encouraged as they reduce the size of data items communicated between Managers and Agents in a network.
            </t>
          </section>
        </section>
        <section anchor="sec-ari">
          <name>The Application Resource Identifier (ARI)</name>
          <t>
The Application Resource Identifier (ARI) is used to represent AMM values outside of an Agent or Manager (<em>i.e.</em> in messaging between them) and is defined in <xref target="I-D.birrane-dtn-ari"/>.
Another function of the ARI is for diagnostic or configuration purposes within either Managers or Agents.
It is important to make the distinction that within an AMM entity (Agent or Manager) the semantic type of a value is kept, but when exchanged via ARI the semantic type is lost.
The AMM defines type compression and reconstruction rules in <xref target="sec-proc-ari-typing"/> to handle this.
          </t>
        </section>
      </section>
      <section anchor="sec-type-literal">
        <name>Literal Types</name>
        <t>
This section describes the literal type definitions used by the AMM.
By definition, literal values are self-contained and literal types restrict the form and function of those values.
        </t>
        <t>
All literal types within the AMM exit within a flat namespace, but some types have complex relationships with other types beyond the "is a" concept of type inheritance.
Types are defined within an IANA registry by <xref section="9.3" target="I-D.birrane-dtn-ari"/> and explained in this section.
The following subsections divide the types into groups to simplify their explanation, not because of an intrinsic relationship within each group.
        </t>
        <section anchor="sec-type-simple">
          <name>Simple Types</name>
          <t>
Simple types are those which cannot be subdivided and represent an "atomic" value within the AMM type system.
They correspond roughly with the CBOR primitive types <xref section="3.3" target="RFC8610"/>.
The simple types are summarized in <xref target="tab-type-simple"/>.
          </t>
          <table anchor="tab-type-simple">
            <name>Simple Literal Types</name>
            <thead>
              <tr>
                <th>Type</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>
                  <tt>NULL</tt>
                </td>
                <td>The singleton <tt>null</tt> value.</td>
              </tr>
              <tr>
                <td>
                  <tt>BOOL</tt>
                </td>
                <td>A native boolean <tt>true</tt> or <tt>false</tt> value.</td>
              </tr>
              <tr>
                <td>
                  <tt>BYTE</tt>
                </td>
                <td>An 8-bit unsigned integer.</td>
              </tr>
              <tr>
                <td>
                  <tt>INT</tt>
                </td>
                <td>A 32-bit signed integer.</td>
              </tr>
              <tr>
                <td>
                  <tt>UINT</tt>
                </td>
                <td>A 32-bit unsigned integer.</td>
              </tr>
              <tr>
                <td>
                  <tt>VAST</tt>
                </td>
                <td>A 64-bit signed integer.</td>
              </tr>
              <tr>
                <td>
                  <tt>UVAST</tt>
                </td>
                <td>A 64-bit unsigned integer.</td>
              </tr>
              <tr>
                <td>
                  <tt>REAL32</tt>
                </td>
                <td>A 32-bit <xref target="IEEE.754-2019"/> floating point number.</td>
              </tr>
              <tr>
                <td>
                  <tt>REAL64</tt>
                </td>
                <td>A 64-bit <xref target="IEEE.754-2019"/> floating point number.</td>
              </tr>
              <tr>
                <td>
                  <tt>TEXTSTR</tt>
                </td>
                <td>A text string composed of (unicode) characters.</td>
              </tr>
              <tr>
                <td>
                  <tt>BYTESTR</tt>
                </td>
                <td>A byte string composed of 8-bit values.</td>
              </tr>
              <tr>
                <td>
                  <tt>TP</tt>
                </td>
                <td>An absolute time point (TP).</td>
              </tr>
              <tr>
                <td>
                  <tt>TD</tt>
                </td>
                <td>A relative time difference (TD) with a sign.</td>
              </tr>
              <tr>
                <td>
                  <tt>LABEL</tt>
                </td>
                <td>A text label of a parent object parameter. This is only valid in a nested parameterized ARI.</td>
              </tr>
              <tr>
                <td>
                  <tt>CBOR</tt>
                </td>
                <td>A byte string containing an encoded CBOR item. The structure is opaque to the Agent but guaranteed well-formed for the ADM using it.</td>
              </tr>
              <tr>
                <td>
                  <tt>LITTYPE</tt>
                </td>
                <td>An integer value representing one of the code points in this Literal Types table.</td>
              </tr>
            </tbody>
          </table>
          <t>
The following subsections discuss nuances in sub-groups of these simple types.
          </t>
          <section>
            <name>Discrete Value Types</name>
            <t>
The <tt>NULL</tt> and <tt>BOOL</tt> types are used to limit to specific discrete values.
Because there are CBOR primitive types corresponding exactly with these AMM types, generators of ARIs with these types can always be compressed by eliding the literal type as defined in <xref target="sec-proc-ari-typing"/>.
            </t>
            <t>
The <tt>NULL</tt> type has only a single value, <tt>null</tt>, which is not useful for expressions or type casting but is useful for defining union types which have "optional value" semantics where the <tt>null</tt> value is used to indicate the absence of a normal value.
            </t>
            <t>
The <tt>BOOL</tt> type is useful for <xref target="sec-proc-cast-bool">type casting</xref> where an arbitrary value is treated as "truthy" or "falsey" in a context such as a <xref format="title" target="sec-obj-sbr"/> condition.
            </t>
          </section>
          <section>
            <name>Numeric Types</name>
            <t>
All of the numeric types (<tt>BYTE</tt>, <tt>UINT</tt>, <tt>INT</tt>, <tt>UVAST</tt>, <tt>VAST</tt>, <tt>REAL32</tt>, and <tt>REAL64</tt>) exist within a domain where values can be cast between types (<xref target="sec-proc-cast-bool"/>).
Some cases of implicit casting is done for type promotion as necessary for arithmetic operations.
            </t>
          </section>
          <section>
            <name>Absolute (TP) and Relative (TD) Time Types</name>
            <t>
The <tt>TP</tt> type represents an instant in time in the UTC datum.
When in text form it is formatted in accordance with the <tt>date-time</tt> symbol of <xref section="A" target="RFC3339"/> and always in the "Z" time-offset.
            </t>
            <t>
The <tt>TD</tt> type represents an offset in time from a relative epoch instant, either later than (a positive offset) or earlier than (a negative offset).
When in text form it is formatted in accordance with the <tt>duration</tt> symbol of <xref section="A" target="RFC3339"/> with a positive or negative sign prefix.
The epoch instant of a relative time MUST be unambiguously defined in the context using the time value.
            </t>
            <aside>
              <t>
In cases where a type signature contains an union of <tt>TP</tt> and <tt>TD</tt> (i.e. an option for either type), relative times have some advantages over absolute times: they do not require time to be synchronized across Agents and Managers, and they are more compact in their representation. 
For example, expressing the semantics "run control_one 10 seconds after receiving it" or "run control_two 20 seconds after running control_one" is more appropriate using relative times than absolute times.
              </t>
            </aside>
          </section>
        </section>
        <section anchor="sec-type-collections">
          <name>Collections</name>
          <t>
AMM objects, or parameters associated with those objects, often need to represent groups of related data or more complex nesting of data.
These are the literal types for collections, which can only be present in a typed-literal ARI form.
          </t>
          <t>
The AMM defines two collection literal types, AC and AM, and allows ADMs to combine these literal types with a complex pattern syntax to create semantic types constraining their contents (<em>e.g.</em>, for macros and expressions in <xref target="typedef-expr"/>).
          </t>
          <section anchor="sec-type-ac">
            <name>ARI Collection (AC)</name>
            <t>
An ARI Collection (AC) is an ordered list of ARIs.
            </t>
            <t>
ACs are used when there exists a need to refer to multiple AMM objects as a single unit.
For example, when defining a Report Template, the definition has an AC that defines the ordered ARIs whose values constitute that report. 
            </t>
          </section>
          <section>
            <name>ARI Map (AM)</name>
            <t>
An ARI Map (AM) is a mapping from a set of literal-value "key" ARI to arbitrary-valued "value" ARI.
<cref>TBD</cref>
            </t>
          </section>
        </section>
        <section>
          <name>Custom Literal Types</name>
          <t>
When an application requires a more complex or specialized literal type than one already available the preferred design procedure is as follows:
          </t>
          <ol>
            <li>
If an existing ADM already defines a semantic typedef (see <xref target="sec-obj-typedef"/>) it is RECOMMENDED to import that ADM and use its typedef.
            </li>
            <li>
Otherwise, when it is possible to use an ADM-defined semantic typedef to achieve the desired goals it is RECOMMENDED to do so.
            </li>
            <li>
Otherwise, when the desired behavior cannot be accomplished by a semantic typedef, it is RECOMMENDED to use the opaque <tt>CBOR</tt> type with interface documentation to explain the syntax of the encoded CBOR item.
            </li>
            <li>
Otherwise, the application MAY make use of the private-use block of literal type code points.
            </li>
          </ol>
          <t>
Implementing a custom literal type requires implementation effort on both an Agent and its associated Manager(s) as well as being more opaque to diagnostic tools and middleboxes.
          </t>
        </section>
      </section>
      <section anchor="sec-type-semantic">
        <name>Semantic Types</name>
        <t>
While literal types control the basic syntax and domain of AMM values, the concept of semantic type is to provide a means to augment literal types by expanding (via union), narrowing (via restrictions), and adding human-friendly attributes.
        </t>
        <t>
Semantic types can be defined in two ways: a named <xref format="title" target="sec-obj-typedef"/> or an anonymous type.
Because this document defines the ADM syntax as an extension of YANG module syntax, the pre-existing <tt>type</tt> statement logic from YANG is used in the AMM.
        </t>
        <t>
When a "type" is needed for an AMM value in an object definition it SHALL be either one of the literal types, a namespace-qualified semantic type, or an anonymous semantic type just for that value.
        </t>
      </section>
      <section anchor="sec-obj">
        <name>AMM Objects</name>
        <t>
This section identifies the types of objects that make up the AMM and which are instantiated within each ADM and ODM.
Each object type is defined by its logical structure and its behavior in "execution" and "evaluation" contexts within Agents.
Each type can allow or disallow parameters within objects and, due to processing behaviors, can either allow or disallow use within an ADM or ODM.
        </t>
        <t>
Unless explicitly specified in the object type subsection, an object SHALL NOT be parameterized.
        </t>
        <section anchor="sec-obj-metadata">
          <name>Common Object Fields</name>
          <t>
Every object type in the AMM includes a set of fields providing annotative or otherwise user-friendly descriptive information for the object.
This information may be used as documentation (for example, only present in ADMs and on operator consoles) and/or encoded and transmitted over the wire as part of a management protocol.
          </t>
          <t>
The metadata supported by the AMM for all objects is as follows:
          </t>
          <dl newline="true">
            <dt>Name:</dt>
            <dd>
An object name is a text string associated with the object, but does not constitute the sole identifier for the object.
Names provide human-readable and/or user-friendly ways to refer to objects with the text form of an ARI.
Each object definition SHALL contain a name field.
An object's name SHALL NOT change between ADM revisions.
Each name SHALL conform to the <tt>id-text</tt> ABNF symbol of <xref section="4" target="I-D.birrane-dtn-ari"/>.
Within each namespace and object type, the name of an object SHALL be unique.
            </dd>
            <dt>Enumeration:</dt>
            <dd>
An object enumeration is an integer associated with the object, which identifies the object just like its name.
Object enumerations provide a stable and concise identifier for the binary encoded form of an ARI.
Each object definition SHOULD contain an enumeration field.
An object's enumeration SHALL NOT change between ADM revisions.
When present, each enumeration SHALL be an unsigned integer value.
Within each namespace and object type, the enumeration of an object SHALL be unique.
            </dd>
            <dt>Status:</dt>
            <dd>
Each object definition MAY contain a status field.
The valid status values of an object are the same as the valid status values for an ADM in <xref target="sec-adm-metadata"/>.
In the absence of a status field, the status of the object SHALL be considered the same as the status of the ADM which contains it.
            </dd>
            <dt>Reference:</dt>
            <dd>
Each object definition MAY contain a reference field.
A reference is a text string referring to a specification or other document which details the source or purpose of the object.
            </dd>
            <dt>Description:</dt>
            <dd>
Each object definition MAY contain a description field.
A description is a text string explaining the purpose or usage of the object in a human-readable format.
There is no minimum or maximum size of description text for an object.
The description serves as documentation for the object and SHOULD be the same regardless of how the object might be parameterized.
For example, the description of a CTRL object should document the purpose of the CTRL in a way that is independent of the value of any particular parameter value passed to that CTRL. 
            </dd>
          </dl>
          <t>
Formal parameters define a method to customize an AMM object.
When used by an object definition, it's formal Parameters SHALL be an ordered list of individual formal parameter definitions.
Each formal parameter SHALL include type and name.
Each formal parameter MAY include an optional default value.
The application of default parameters and relationship of <xref target="sec-value-objref-params">actual parameters</xref> to formal parameters is defined in <xref target="sec-proc-params"/>.
          </t>
        </section>
        <section anchor="sec-obj-typedef">
          <name>Semantic Type Definition (TYPEDEF)</name>
          <t>
An ADM can define a semantic type definition (TYPEDEF) to give a name to a <xref target="sec-type-semantic">semantic type</xref>.
This TYPEDEF name can then be used as a type anywhere else in the same ADM or another one which imports it.
          </t>
          <t>
The definition of a TYPEDEF consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Type:</dt>
            <dd>
A TYPEDEF definition SHALL include the type being named, as described in <xref target="sec-type-semantic"/>.
The type of a TYPEDEF is fixed and SHALL NOT change between ADM revisions.
Because this document defines the ADM syntax as an extension of YANG module, the pre-existing <tt>typedef</tt> syntax and logic from YANG is used.
            </dd>
          </dl>
          <t>
As defined in this document, TYPEDEFs and semantic types can only be defined within an ADM.
Future capability could allow the use of TYPEDEFs within ODMs.
          </t>
        </section>
        <section anchor="sec-obj-edd">
          <name>Externally Defined Data (EDD)</name>
          <t>
Externally defined data (EDD) objects, as defined in the DTNMA, represent data values that are produced based on a source external to the Agent itself.
The <xref format="title" target="sec-proc-prod"/> occurs at the moment the value is needed, by either an <xref format="title" target="sec-proc-eval"/> or a <xref format="title" target="sec-proc-rpt"/>.
The actual value could come from outside of the Agent proper, or be derived from data outside of the Agent.
          </t>
          <t>
The value production of an EDD SHOULD be nilpotent and have no side-effects in the processor.
This property is not enforced by the Agent but requires consideration of the ADM designers, see <xref target="auth_consid"/>.
          </t>
          <t>
For values managed entirely within the Agent use a <xref format="title" target="sec-obj-var"/> or for constant-values use a <xref format="title" target="sec-obj-const"/>.
For complex tabular data, use an EDD with a type which produces a <xref format="title" target="typedef-tbl"/>.
          </t>
          <t>
The definition of an EDD consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
An EDD definition MAY include ARI parameters to be used when the EDD is used to produce a value.
Parameterized objects are discussed in <xref target="auth_consid"/>.
The parameters of an EDD are fixed and SHALL NOT change between ADM revisions.
            </dd>
            <dt>Type:</dt>
            <dd>
An EDD definition SHALL include the type of the value produced by the object, as described in <xref target="sec-type-semantic"/>.
The type of an EDD is fixed and SHALL NOT change between ADM revisions.
            </dd>
          </dl>
          <t>
As defined in this document, EDDs can only be defined within an ADM.
Future capability could allow the use of EDDs within ODMs.
          </t>
        </section>
        <section anchor="sec-obj-const">
          <name>Constant (CONST)</name>
          <t>
A Constant (CONST) represents a named literal value, but unlike an <xref format="title" target="sec-obj-edd"/> or <xref format="title" target="sec-obj-var"/> a CONST always produces the same value.
Examples include common mathematical values such as PI or well-known time epochs such as the UNIX Epoch.
A CONST typed to produce a simple value can be used within an expression (see <xref target="sec-proc-eval"/>), where the object is used to produce a value at the moment of evaluation.
A CONST can also be typed to produce an EXPR value to evaluate, or MAC value to execute.
          </t>
          <t>
The definition of a CONST consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Type:</dt>
            <dd>
A CONST definition SHALL include the type of the value produced by the object, as described in <xref target="sec-type-semantic"/>.
The type of a CONST is fixed and SHALL NOT change between ADM revisions.
            </dd>
            <dt>Value:</dt>
            <dd>
A CONST definition SHALL include the literal value produced during evaluation.
            </dd>
          </dl>
          <t>
As defined in this document, CONSTs can only be defined within an ADM.
Allowing network operators to define constants dynamically means that a Constant could be defined, removed, and then re-defined at a later time with a different value, which defeats the purpose of having Constants.
When adding new "fixed" values to an ODM, a <xref format="title" target="sec-obj-var"/> MUST be used instead of a Constant.
          </t>
        </section>
        <section anchor="sec-obj-ctrl">
          <name>Control (CTRL)</name>
          <t>
A Control (CTRL) represents a predefined function that can be executed on an Agent.
Controls are not able to be defined as part of dynamic network configuration since their execution is typically part of the firmware or other implementation outside of the Agent proper.
          </t>
          <t>
The execution of a CTRL SHOULD be idempotent and have no effect if executed multiple times in sequence.
This property is not enforced by the Agent but requires consideration of the ADM designers, see <xref target="auth_consid"/>.
          </t>
          <t>
Controls can be executed in a "one shot" manner as part of messaging from a Manager to an Agent.
Network operators that wish to autonomously execute functions on an Agent may use a <xref format="title" target="sec-obj-sbr"/> or <xref format="title" target="sec-obj-tbr"/>.
When an execution involves the ordered sequence of controls, a <xref format="title" target="typedef-mac"/> SHOULD be used instead of a more fragile use of CTRL directly.
          </t>
          <t>
The definition of a CONST consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
              <t>
A CTRL definition MAY include ARI parameters to be used when the CTRL is executed.
Parameterized objects are discussed in <xref target="auth_consid"/>.
              </t>
            </dd>
            <dt>Result:</dt>
            <dd>
A CTRL definition MAY include the definition of a result.
The result SHALL have a name and a type.
The result MAY have a default value.
The result of a CTRL is separate from the execution status as being successful or failed.
            </dd>
          </dl>
          <t>
As defined in this document, CTRLs can only be defined within an ADM.
Future capability could allow the use of CTRLs within ODMs if there was some mechanism to bind a CTRL definition to some platform-specific execution specification (<em>e.g.</em>, a command line sequence).
          </t>
        </section>
        <section anchor="sec-obj-oper">
          <name>Operator (OPER)</name>
          <t>
An Operator (OPER) represents a user-defined, typically mathematical, function that operates within the evaluation of an <xref format="title" target="typedef-expr"/>.
It is expected that operators are implemented in the firmware of an Agent.
          </t>
          <t>
The AMM separates the concepts of Operators and Controls to prevent side-effects in Expression evaluation (e.g. to avoid constructs such as <tt>A = B + GenerateReport()</tt>).
For this reason, Operators are given their own object type and Controls do not interact with operators. 
          </t>
          <t>
The definition of an OPER consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
An OPER definition MAY include ARI parameters to be used when the OPER is evaluated.
Parameterized objects are discussed in <xref target="auth_consid"/>.
The parameters of an OPER are distinct from the operands from the expression stack. 
            </dd>
            <dt>Operands:</dt>
            <dd>
An OPER definition MAY include definitions of operand values to be popped from the expression stack when the OPER is evaluated.
Each operand SHALL consist of a name, a type, and a cardinality.
Any non-trivial OPER will have one or more operands.
An OPER can have a non-fixed operand count which is based on a parameter value (<em>e.g.</em>, an operator can average the top <em>N</em> values from the stack, where <em>N</em> is a parameter).
            </dd>
            <dt>Result:</dt>
            <dd>
An OPER definition SHALL include definition of a result value to be pushed onto the expression stack after the OPER is evaluated.
The result SHALL have a name and a type.
The result SHALL NOT have a default value.
            </dd>
          </dl>
          <t>
As defined in this document, OPERs can only be defined within an ADM.
Future capability could allow the use of OPERs within ODMs if there was some mechanism to bind an OPER definition to some platform-specific evaluation specification.
          </t>
        </section>
        <!--
        <section title="Report Template (RPTT)">
          <t>
A Report Template (RPTT) is the ordered list of ARIs that describe how values will be represented in a corresponding Report (see <xref section="9.4.2" target="I-D.ietf-dtn-dtnma"/>).
RPTTs can be viewed as a schema that describes how to generate and interpret a Report; they contain no values and are either defined in an ADM or configured between Managers and Agents in an ODM.
Reports themselves are ephemeral and not represented in the AMM directly, see <xref target="sec-proc-rpt"/>.
          </t>
          <t>
                FIXME: Is this true? 
                Since a RPTT may contain other RPTTs, implementations MUST
                implement some mechanism to prevent the definition of
                circular references.
          </t>
          <t>
                RPTTs are defined by an ARI, the report template
                definition, and a description, as follows.
          </t>
          <t>
The definition of an RPTT consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
An RPTT definition MAY include ARI parameters to be used when the RPTT is reported upon.
Parameterized objects are discussed in <xref target="auth_consid"/>.
The parameters of a RPTT are fixed and SHALL NOT change between ADM revisions.
            </dd>
            <dt>Items:</dt>
            <dd>
An RPTT definition SHALL include definitions of all reported items.
Each item SHALL be present as an ARI, possibly parameterized within the RPTT parameters.
Each item SHALL contain a literal value or an object-reference to one of the following types: CONST, EDD, VAR, RPTT, TBLT. FIXME: added TBLT
Any non-trivial RPTT will have one or more items.
The items of a RPTT are fixed and SHALL NOT change between ADM revisions.
            </dd>
          </dl>
          <t>
RPTTs can be be defined either within an ADM or an ODM.
When defined in an ODM the restrictions on fixed parameters and items are relaxed, but this leaves more possibility of a disagreement between Agent and Manager about the contents of an associated Report.
          </t>
          <t>
When evaluating a RPTT into a Report, the behaivor SHALL be nilpotent and have no side-effects in the processor.
          </t>
        </section>
-->
        <section anchor="sec-obj-sbr">
          <name>State-Based Rule (SBR)</name>
          <t>
A State-Based Rule (SBR) is a form of autonomy in which the Agent performs an action upon the change of state to meet a specific condition.
The execution model of the SBR is to evaluate the Condition (as often as necessary to handle changes in its expression evaluation) and when it evaluates to a <xref target="sec-proc-cast-bool">truthy</xref> value and it has been no shorter than the Minimum Interval since the last execution, the Action is executed.
When the Maximum Count of executions is reached the TBR is disabled.
The execution occurs concurrently with any time processing and may take longer than the Minimum Interval, so it is possible that multiple executions are requested to overlap in time.
          </t>
          <t>
Each SBR has an enabled state to allow rules to be retained in an ADM or ODM but not enabled during Manager-controlled time periods or under certain Manager-desired conditions.
See <xref target="sec-agentadm"/> for details about what SBR-related controls are in the Agent ADM.
          </t>
          <t>
The definition of an SBR consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Action:</dt>
            <dd>
An SBR definition SHALL include an action in the form of a <xref format="title" target="typedef-mac"/>.
When triggered, the action execution SHALL be executed in accordance with <xref target="sec-proc-exec"/> in an execution context with no parameters.
            </dd>
            <dt>Condition:</dt>
            <dd>
An SBR definition SHALL include a condition in the form of an <xref format="title" target="typedef-expr"/>.
The condition SHALL be evaluated in accordance with <xref target="sec-proc-eval"/> in an evaluation context with no parameters.
The result of the condition SHALL be cast to a <tt>BOOL</tt> value after evaluation and used to determine when to execute the action of the SBR.
            </dd>
            <dt>Minimum Interval:</dt>
            <dd>
An SBR definition SHALL include a minimum execution interval in the form of a non-negative <tt>TD</tt> value.
The interval MAY be zero to indicate that there is no minimum.
This is <em>not</em> a limit on the interval of evaluations of the condition.
This value can be used to limit potentially high processing loads on an Agent.
            </dd>
            <dt>Maximum Count:</dt>
            <dd>
An SBR definition SHALL include a maximum execution count in the form of a non-negative <tt>UVAST</tt> value.
The count sentinel value zero SHALL be interpreted as having no maximum.
This is <em>not</em> a limit on the number of evaluations of the condition.
            </dd>
            <dt>Initial Enabled:</dt>
            <dd>
An SBR definition MAY include an initial value for its enabled state.
If not provided, the initial enabled state SHALL be <tt>true</tt>.
            </dd>
          </dl>
          <!--
          <ul>
            <li>
                     Starting 2 hours from receipt, whenever Variable V1 &gt; 10, 
                     produce a Report Entry for Report Template R1 no more 
                     than 20 times.                                    
                  </li>
            <li>
                     Starting at some future absolute time, whenever Variable 
                     V2 != Variable V4, run Macro M1 no more than 36 times.
                  </li>
          </ul>
-->
        </section>
        <!--
        <section anchor="sec-obj-tblt">
          <name>Tabular Report Template (TBLT)</name>
          <t>
A Tabular Report Template (TBLT) is the ordered list of column definitions that describe how values will be represented in a corresponding Tabular Report (see <xref section="9.4.2" target="I-D.ietf-dtn-dtnma"/>).
          </t>
          <t>
The processing behavior of a TBLT is similar to that of an <xref format="title" target="sec-obj-edd"/> in that the evaluation of a TBLT into a Table occurs outside of the Agent proper.
The evaluation of a TBLT into a Tabular Report SHALL be nilpotent and have no side-effects in the processor.
          </t>
          <t>
The definition of a TBLT consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
An TBLT definition MAY include ARI parameters to be used when the TBLT is reported upon.
Parameterized objects are discussed in <xref target="auth_consid"/>.
The parameters of a TBLT are fixed and SHALL NOT change between ADM revisions.
            </dd>
            <dt>Columns:</dt>
            <dd>
An TBLT definition SHALL include definitions of all reported columns.
Each column SHALL consist of a name, a type, and a cardinality.
Any non-trivial TBLT will have one or more columns.
The columns of a TBLT are fixed and SHALL NOT change between ADM revisions.
            </dd>
          </dl>
          <t>
TBLTs can be be defined either within an ADM or an ODM.
When defined in an ODM the restrictions on fixed parameters and columns are relaxed, but this leaves more possibility of a disagreement between Agent and Manager about the contents of an associated Tabular Report.
          </t>
        </section>
-->
        <section anchor="sec-obj-tbr">
          <name>Time-Based Rule (TBR)</name>
          <t>
A Time-Based Rule (TBR) is a form of autonomy in which the Agent performs an action at even intervals of time.
The execution model of the TBR is to start a timer at the Start Time of the TBR ticking at an even Period; each time the timer expires the Action is executed.
When the Maximum Count of executions is reached the TBR is disabled.
The execution occurs concurrently with any time processing and may take longer than the TBR Period, so it is possible that multiple executions are requested to overlap in time.
          </t>
          <t>
Each TBR has an enabled state to allow rules to be retained in an ADM or ODM but not enabled during Manager-controlled time periods or under certain Manager-desired conditions.
See <xref target="sec-agentadm"/> for details about what TBR-related controls are in the Base ADM.
          </t>
          <t>
The definition of an SBR consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Action:</dt>
            <dd>
An SBR definition SHALL include an action in the form of a <xref format="title" target="typedef-mac"/>.
When triggered, the action execution SHALL be executed in accordance with <xref target="sec-proc-exec"/> in an execution context with no parameters.
            </dd>
            <dt>Start Time:</dt>
            <dd>
An SBR definition SHALL include a start time in the form of a <xref target="typedef-time"><tt>TIME</tt></xref> value.
A relative start time SHALL be interpreted relative to the absolute time at which the Agent is initialized (for ADM rules) or the rule is created (for ODM rules).
The start time MAY be the relative time zero to indicate that the TBR is always active.
This is <em>not</em> a limit on the interval of evaluations of the condition.
            </dd>
            <dt>Period:</dt>
            <dd>
A TBR definition SHALL include a period in the form of a positive <tt>TD</tt> value.
The period SHALL NOT be zero but any non-zero small period is valid.
            </dd>
            <dt>Maximum Count:</dt>
            <dd>
A TBR definition SHALL include a maximum execution count in the form of a non-negative <tt>UVAST</tt> value.
The count sentinel value zero SHALL be interpreted as having no maximum.
This is <em>not</em> a limit on the number of evaluations of the condition.
            </dd>
            <dt>Initial Enabled:</dt>
            <dd>
A TBR definition MAY include an initial value for its enabled state.
If not provided, the initial enabled state SHALL be <tt>true</tt>.
            </dd>
          </dl>
          <!--
          <ul>
            <li>
                     Starting 2 hours from receipt, produce a Report for 
                     Report Template R1 every 10 hours ending after 20 times.                                    
                  </li>
            <li>
                     Starting at the given absolute time, run Macro M1 every
                     24 hours ending after 365 times.
                  </li>
          </ul>
-->
        </section>
        <section anchor="sec-obj-var">
          <name>Variable (VAR)</name>
          <t>
A Variable (VAR) is a stateful store of a value in an Agent.
The evaluation of a VAR is similar to an EDD except that all the behavior of a VAR is entirely within an Agent, while the ultimate source of an EDD value is outside of the Agent.
The evaluation of a VAR into a value SHALL be nilpotent and have no side-effects in the processor.
          </t>
          <t>
A VAR has an initializer, which is used at Agent initialization and to reset the VAR, but the VAR is otherwise stateful and will retain its last value between any actions which edit it.
          </t>
          <t>
The definition of a VAR consists of the following:
          </t>
          <dl newline="true">
            <dt>Name, Enumeration, Status, Reference, Description:</dt>
            <dd>As defined in <xref format="title" target="sec-obj-metadata"/>.</dd>
            <dt>Parameters:</dt>
            <dd>
A VAR definition MAY include ARI parameters to be used when the VAR is evaluated.
Parameterized objects are discussed in <xref target="auth_consid"/>.
Parameters for a VAR are only meaningful when the VAR contains a value with actual parameters themselves containing a <tt>LABEL</tt> value.
            </dd>
            <dt>Type:</dt>
            <dd>
An VAR definition SHALL include the data type of the value produced during evaluation, as described in <xref target="sec-type-semantic"/>.
The type of a VAR is fixed and SHALL NOT change between ADM revisions.
            </dd>
            <dt>Initializer:</dt>
            <dd>
An VAR definition MAY include an initializer in the form of an <xref format="title" target="typedef-expr"/>.
The only times the initializer are evaluated are at <xref format="title" target="sec-proc-init"/> and when a CTRL is used to reset the state of the VAR.
            </dd>
          </dl>
          <aside>
            <t>
NOTE: It is possible to specify an expression that evaluates to a type different than the VAR itself.
For example, if an EXPR adds two single-precision floating point numbers, the VAR MAY have an integer type associated with it.
The VAR initialization will always be <xref target="sec-proc-cast">cast</xref> to the type of the VAR before assignment.
            </t>
          </aside>
        </section>
        <!--
        <section title="Common Object Processing">
          <t>
               This section describes the handling and exchange of AMM objects 
               between Agents and Managers in a network.
            </t>
          <t>
               Managers must:
            </t>
          <ul>
            <li> 
                     Store the ARI and definitions for both network-specific 
                     and ADM-defined AMM Objects.
                  </li>
            <li> 
                     Send requests to Agents to add, list, describe, and remove 
                     custom AMM object definitions.
                  </li>
            <li> 
                     Verify and interpret reports against report templates and 
                     tables against table templates when receiving these objects 
                     from an Agent. 
                  </li>
            <li> 
                     Encode ARIs in Objects to Agents, and decode ARIs from
                     Agents.
                  </li>
            <li>
                     Provide actual parameters when sending parameterized
                     objects to an Agent.
                  </li>
          </ul>
          <t>
               Agents must:
            </t>
          <ul>
            <li> 
                     Store the ARI for all ADM-defined AMM objects.
                  </li>
            <li> 
                     Calculate the value of an AMM object when required, such
                     as when generating a Report or evaluating an Expression. 
                  </li>
            <li> 
                     Implement Controls in firmware and run Controls and
                     Macros with appropriate parameters when necessary in the 
                     context of Manager direction and Rule execution.
                  </li>
            <li> 
                     Communicate "return" values from Controls back to 
                     Managers as Reports where appropriate. 
                  </li>
            <li> 
                     Persist custom AMM object definitions.
                  </li>
            <li> 
                     Add, remove, list, and describe custom AMM objects as
                     requested by Managers.
                  </li>
            <li> 
                     Calculate the value of applying an Operator to a given set
                     of operands, such as when evaluating an Expression.
                  </li>
            <li> 
                     Populate Reports and Tables for transmission to Managers
                     when required.
                  </li>
            <li> 
                     Run the actions associated with SBRs and TBRs in accordance 
                     with their definitions.
                  </li>
            <li> 
                     Calculate the value of VARs when required, such as during 
                     Rule evaluation, calculating other VAR values, and 
                     generating Reports. 
                  </li>
          </ul>
        </section>
-->
      </section>
    </section>
    <section anchor="sec-adm">
      <name>Application Data Models (ADMs)</name>
      <t>
An ADM is a logical entity for defining static AMM object instances, which are discussed in detail in <xref target="sec-obj"/>.
Each ADM exists as a separate namespace for its contained objects, but allows importing object <em>names</em> from other ADMs to reuse them.
Each Agent can support any number of ADMs at one time (subject to implementation limitations) and each Manager can operate with ADMs of different revisions to support diverse Agents.
      </t>
      <t>
The following subsections define what is present in an ADM generally and what objects necessary to operate a DTNMA Agent are present in two base ADMs.
      </t>
      <section anchor="sec-adm-defn">
        <name>ADM Definitions</name>
        <t>
An ADM is "static" in the sense that it is revision-controlled and a released revision of an ADM does not change.
Besides AMM object definitions there are metadata and handling rules for the ADM itself, which are discussed in this section.
        </t>
        <section anchor="sec-adm-metadata">
          <name>ADM Metadata</name>
          <t>
This section explains the purposes of the metadata fields of an ADM, while the profile of <xref target="sec-yang"/> defines a syntax for how these fields fit into a YANG module.
          </t>
          <dl newline="true">
            <dt>Name:</dt>
            <dd>
Each ADM definition SHALL contain a name field.
An ADM's name SHALL NOT change between ADM revisions.
The name SHALL conform to the <tt>id-text</tt> ABNF symbol of <xref section="4" target="I-D.birrane-dtn-ari"/>.
            </dd>
            <dt>Enumeration:</dt>
            <dd>
An ADM enumeration is an integer associated with the object, which identifies the object just like its name.
ADM enumerations provide a stable and concise identifier for the binary encoded form of an ARI.
Each ADM definition SHALL contain an enumeration field.
An ADM's enumeration SHALL NOT change between ADM revisions.
The enumeration SHALL be an unsigned integer value.
            </dd>
            <dt>Revision History:</dt>
            <dd>
Each ADM SHALL contain a history of dated revisions.
At least one revision SHALL be present and mark the date at which the ADM was released for use.
During development and testing an ADM need not have updated revisions, only when a release occurs should a revision be added.
            </dd>
            <dt>Status:</dt>
            <dd>
Each ADM definition SHOULD contain a status field.
The valid status value of an ADM SHALL be identical to the Status field of YANG <xref section="7.21.2" target="RFC7950"/>. 
In the absence of a status field, the status of the ADM SHALL be considered the same as the status of the ADM which contains it.
            </dd>
            <dt>Reference:</dt>
            <dd>
Each ADM definition SHOULD contain a reference field.
A reference is a text string referring to a specification or other document which details the source or purpose of the ADM.
            </dd>
            <dt>Description:</dt>
            <dd>
Each ADM definition SHOULD contain a description field.
A description is a text string explaining the purpose or usage of the ADM in a human-readable format.
            </dd>
            <dt>Features:</dt>
            <dd>
Each ADM definition MAY contain a set of feature definitions, see <xref target="sec-adm-features"/> for details.
Each feature SHALL have a name that is unique within the namespace of the ADM.
Each name SHALL conform to the <tt>id-text</tt> ABNF symbol of <xref section="4" target="I-D.birrane-dtn-ari"/>.
            </dd>
          </dl>
        </section>
        <section anchor="sec-adm-features">
          <name>Features and Conformance</name>
          <t>
Following in the pattern of YANG features <xref section="5.6.2" target="RFC7950"/> and SMIv2 conformance groups <xref target="RFC2580"/>, the AMM has the concept of ADM features and Agent conformance to those features.
Each feature is a simple qualified name and each object in an ADM can be conditional on the conformance to a set of features.
          </t>
        </section>
      </section>
      <section anchor="sec-ammadm">
        <name>Contents of an DTNMA ADM</name>
        <t>
The base DTNMA ADM is a necessary part of the AMM typing, execution, and evaluation models.
Rather than having some Agent logic defined purely by specification, this document uses a base ADM to define semantic types and controls needed for normal Agent operations.
The needed types are still set by specification and are unchanging within an ADM revision, but this avoids having a separate, intermediate typing system between the AMM-defined semantic types and the ARI-defined literal types.
This is also in-line with how the SMIv2 <xref target="RFC2578"/> and NETCONF/YANG <xref target="RFC6991"/> both rely on base modules for some core behavior.
        </t>
        <section anchor="sec-baseadm-simple">
          <name>Simple Semantic Types</name>
          <t>
The most basic use of a semantic type is to provide additional meaning to simple types.
None of these types associates a unit with the value, which it is expected that a derived type or an anonymous type (at the point of use) would add for additional clarity.
          </t>
          <t>
These are summarized below:
          </t>
          <dl>
            <dt><tt>counter32</tt> and <tt>counter64</tt>:</dt>
            <dd>
An unsigned integer value with an arbitrary initial value which increments over time and wraps around the maximum value.
These correspond with the same names defined in SMIv2 and YANG <xref target="RFC6021"/>.
            </dd>
            <dt><tt>gauge32</tt> and <tt>gauge64</tt>:</dt>
            <dd>
An integer value sampling some measurement which can increase or decrease arbitrarily over time.
These correspond with the same names defined in SMIv2 and YANG <xref target="RFC6021"/>.
            </dd>
            <dt><tt>timestamp</tt>:</dt>
            <dd>
An absolute time at which an event happened.
This corresponds with the same name defined in SMIv2 and YANG <xref target="RFC6021"/>.
            </dd>
          </dl>
        </section>
        <section anchor="sec-baseadm-unions">
          <name>Type Unions</name>
          <t>
All of the literal types defined in <xref target="I-D.birrane-dtn-ari"/> have a flat structure, with some types sharing the same CBOR primitive encoding but having the concept of a derived "base" of another type.
In order to allow types to fit into a more logical taxonomy, the base ADM defines some specific semantic typedefs to group literal types.
These groups are not a strict logical hierarchy and are intended only to simplify the effort of an ADM designer when choosing type signatures.
          </t>
          <t>
These are summarized below:
          </t>
          <dl>
            <dt anchor="typedef-typeref"><tt>TYPE-REF</tt>:</dt>
            <dd>The union of <tt>LITTYPE</tt> and <tt>TYPEDEF-REF</tt> types.</dd>
            <dt anchor="typedef-integer"><tt>INTEGER</tt>:</dt>
            <dd>The union of <tt>BYTE</tt>, <tt>UINT</tt>, <tt>INT</tt>, <tt>UVAST</tt>, and <tt>VAST</tt> types.</dd>
            <dt anchor="typedef-float"><tt>FLOAT</tt>:</dt>
            <dd>The union of <tt>REAL32</tt> and <tt>REAL64</tt> types.</dd>
            <dt anchor="typedef-numeric"><tt>NUMERIC</tt>:</dt>
            <dd>The union of <tt>INTEGER</tt> and <tt>FLOAT</tt> types.</dd>
            <dt><tt>PRIMITIVE</tt>:</dt>
            <dd>The union of <tt>NONE</tt>, <tt>BOOL</tt>, <tt>NUMERIC</tt>, <tt>TEXTSTR</tt>, and <tt>BYTESTR</tt> types.</dd>
            <dt anchor="typedef-time"><tt>TIME</tt>:</dt>
            <dd>The union of <tt>TP</tt> and <tt>TD</tt> types.</dd>
            <dt anchor="typedef-simple"><tt>SIMPLE</tt>:</dt>
            <dd>The union of <tt>PRIMITIVE</tt>, and <tt>TIME</tt> types.</dd>
            <dt><tt>LITERAL</tt>:</dt>
            <dd>The union of <tt>SIMPLE</tt>, <tt>LITTYPE</tt>, <tt>LABEL</tt>, <tt>CBOR</tt>, <tt>AC</tt>, and <tt>AM</tt> types. This matches all values that can be in a literal value ARI. </dd>
            <dt anchor="typedef-valueref"><tt>VALUE-REF</tt>:</dt>
            <dd>The union of <tt>CONST-REF</tt>, <tt>EDD-REF</tt>, and <tt>VAR-REF</tt> reference types. This matches any reference to an object that can <xref target="sec-proc-prod">produce a value</xref>.</dd>
          </dl>
        </section>
        <section anchor="typedef-expr">
          <name>Expression (EXPR)</name>
          <t>
An Expression (EXPR) is an ordered collection of references to Operators or operands.
An EXPR takes the form of a semantic typedef refining an AC to be a list of ARIs referencing OPERs, ARIs referencing evaluate-able objects (see <xref target="sec-proc-eval"/>), or literal value ARIs (with <xref format="title" target="sec-type-simple"/>).
These operands and operators form a mathematical expression that is used to compute a resulting value. 
          </t>
          <t>
The evaluation procedure of an EXPR is defined in <xref target="sec-proc-eval"/>.
Expressions are used within an ADM for defining the initializer of a <xref format="title" target="sec-obj-var"/> and for defining the condition of a <xref format="title" target="sec-obj-sbr"/>.
          </t>
          <t>
Since the Expression is an AC, there are no annotative constructs such as parenthesis to enforce certain orders of operation.
To preserve an unambiguous calculation of values, the ARIs that form an Expression MUST be represented in postfix order.
Postfix notation requires no additional symbols to enforce precedence, always results in a more efficient encoding, and post-fix engines can be implemented efficiently in embedded systems. 
          </t>
          <t>
For example, the infix expression <tt>A * (B * C)</tt> is represented as the postfix <tt>A B C * *</tt>.
          </t>
        </section>
        <section anchor="typedef-mac">
          <name>Macro (MAC)</name>
          <t>
A Macro (MAC) is an ordered collection of references to Controls or other Macros.
A Macro takes the form of a semantic typedef refining an AC to be a list of ARIs referencing Controls or objects which produce other Macros.
          </t>
          <t>
The execution procedure of an MAC is defined in <xref target="sec-proc-exec-mac"/>.
Macros are used within an ADM for defining the action of a <xref format="title" target="sec-obj-sbr"/> or <xref format="title" target="sec-obj-tbr"/>.
          </t>
          <t>
In cases where a Macro references another Macro, Agent implementations MUST implement some mechanism for preventing infinite recursions, such as defining maximum nesting levels, performing Macro inspection, and/or enforcing maximum execution times.
          </t>
        </section>
        <section anchor="typedef-rptt">
          <name>Report Template (RPTT)</name>
          <t>
A Report Template (RPTT) is an ordered list of object references or expression values used as a source for generating <xref target="typedef-rpt">report</xref> values.
A RPTT takes the form of a semantic typedef refining an AC to be a list of expressions or references to value-producing objects.
The object which produces an RPTT can itself be parameterized so that the RPTT flows down parameters as described in <xref target="param-by-label"/>.
          </t>
          <t>
A RPTT can be viewed as a schema that defines how to generate and interpret a Report; they contain no values and are either defined in an ADM or configured between Managers and Agents in an ODM.
Reports themselves are ephemeral and not represented in the AMM object model directly, see <xref target="typedef-rpt"/>.
The procedure for reporting on a RPTT is defined in <xref target="sec-proc-rpt-rptt"/>.
          </t>
          <t>
RPTT values <bcp14>SHOULD</bcp14> be used within a CONST where possible.
RPTT values <bcp14>MAY</bcp14> be used within a VAR where necessary.
This makes correlating a RPT value with its associated RPTT easier over time.
          </t>
        </section>
        <section anchor="typedef-rpt">
          <name>Report (RPT)</name>
          <t>
A Report (RPT) is an ordered list of data values populated in conformance to a source object being reported on.
Reports do not have an individual identifier - rather they are uniquely identified by their source and the timestamp at which their data values were collected.
          </t>
          <t>
A RPT takes the form of a semantic typedef refining an AC to a sequence of the following:
          </t>
          <dl newline="true">
            <dt>Source:</dt>
            <dd>The source of the report in the form of an ARI with an object-reference for one of the following types: CONST, EDD, VAR, or CTRL. If the source was parameterized, this ARI SHALL contain the actual parameters used at the time of reporting.</dd>
            <dt>Generation Time:</dt>
            <dd>The timestamp of the time at which the report items were sampled in the form of an ARI containing a literal <tt>TP</tt> value.</dd>
            <dt>Correlator:</dt>
            <dd>Either a <tt>BYTESTR</tt>, if the report originated from an execution with a correlator value, or the <tt>null</tt> value.</dd>
            <dt>Items:</dt>
            <dd>
              <t>
A list of ARIs corresponding to the source object, with cardinality according to the following:
              </t>
              <ul>
                <li>For a <tt>VALUE-REF</tt> source the item list SHALL be the result of <xref target="sec-proc-rpt-valueref">reporting</xref> on that object.</li>
                <li>For a CTRL-REF source there SHALL be a single value representing the Result of the execution. A result of <tt>undefined</tt> indicates a failure executing the CTRL.</li>
              </ul>
            </dd>
          </dl>
          <t>
RPT values <bcp14>SHALL NOT</bcp14> be used directly within any value-producing object.
Values within a RPT are generated by an Agent during <xref target="sec-proc-rpt">reporting</xref>.
          </t>
        </section>
        <section anchor="typedef-tbl">
          <name>Tabular Report (TBL)</name>
          <t>
A Tabular Report (TBL) is a collection of values which are logically structured as a two dimensional table of rows and columns.
Similar to <xref format="title" target="typedef-rpt"/> values, tables are instantiated dynamically as part of evaluation and not intended to be user-input.
          </t>
          <t>
Also similar to RPT values, a TBL can only be interpreted within the context of a Tabular Report Template defined within an ADM.
The TBLT takes the form of a structured type definition on a value-producing object which defines the columns of the table, including each of their column names and types and optional constraints on the number of rows in the TBL.
          </t>
          <t>
A TBL takes the form of a semantic typedef refining an AC to a sequence of the following:
          </t>
          <dl newline="true">
            <dt>Column Count:</dt>
            <dd>
The number of columns in the associated TBLT. 
This is used to interpret the flat list of table items that follow.
            </dd>
            <dt>Items:</dt>
            <dd>
The items of the table flattened in row-major order.
The number of items is the product of the number of rows and columns in the table.
            </dd>
          </dl>
          <t>
TBL values <bcp14>SHOULD</bcp14> be used only within an EDD.
Values within a TBL are generated by an Agent during <xref target="sec-proc-prod">value production</xref>.
          </t>
        </section>
      </section>
      <section anchor="sec-agentadm">
        <name>Contents of an Agent ADM</name>
        <t>
While the DTNMA ADM described in <xref target="sec-ammadm"/> contains definitions of static aspects of the AMM, the DTNMA Agent ADM is needed to include necessary dynamic aspects of the operation of an Agent.
This separation is also helpful in order to allow the dynamic behaviors of an Agent to be modified over time while the AMM definitions stay stable and unchanging.
        </t>
        <section anchor="sec-agentadm-introspect">
          <name>Agent State Introspection</name>
          <t>
The Agent ADM contains the following EDD objects used to introspect the Agent's state, all of which can change over time.
          </t>
          <ul>
            <li>
The ADMs supported by the Agent, including the unique name and revision of each.
By indicating specific revision and supported <tt>feature</tt> set, the contained objects in each ADM can be derived.
Because of this, the ADM-contained objects do not require additional introspection.
            </li>
            <li>
The set of SBRs and TBRs in the Agent's ODMs, along with controls to ensure a specific object is either present or absent.
These are all conditioned on whether the Agent actually supports the built-in rule feature.
            </li>
            <li>
The set of VARs in the Agent's ODMs, along with controls to ensure a specific object is either present or absent.
            </li>
          </ul>
        </section>
        <section anchor="sec-agentadm-opers">
          <name>Basic Operators</name>
          <t>
<cref>TBD defining boolean, bitwise, and numeric operators</cref>
          </t>
        </section>
      </section>
    </section>
    <section anchor="sec-odm">
      <name>Operational Data Models (ODMs)</name>
      <t>
An ODM is a logical entity for containing AMM objects, similar to an <xref target="sec-adm">ADM</xref> but in an ODM the objects are not static.
An ODM's objects can be added, removed, and (with some restrictions) modified during the runtime of an Agent.
Like an ADM, each ODM exists as a separate namespace for its contained objects and an Agent can contain any number of ODMs.
      </t>
      <t>
Some object types, those which require implementation outside of the Agent proper, are not available to be created in an ODM.
These include the CTRL, EDD, and OPER.
      </t>
      <t>
The actions for inspecting and manipulating the contents of an ODM are available through EDDs and CTRLs of the <xref target="sec-agentadm-introspect">Agent ADM</xref>.
      </t>
    </section>
    <section anchor="sec-proc">
      <name>Processing Activities</name>
      <t>
This section discusses logic and requirements for processing of AMM objects and values.
Each subsection is a separate class of processing that is performed by an Agent.
      </t>
      <t>
A Manager (or any other entity) <bcp14>MAY</bcp14> perform some of the same processing, <em>e.g.</em> evaluating an expression, in order to validate values or configurations before sending them to an Agent.
That kind of behavior is effectively creating a "digital twin" of the managed Agent to ensure that the processing will behave as expected before it is sent.
For this reason, the subject noun used in all of these activities is the "processor".
      </t>
      <section anchor="sec-proc-init">
        <name>Agent Initialization</name>
        <t>
The initialization of the Agent state can be associated with a power-on event or, due to the use of volatile memory, can be an explicit activity initiated from outside the Agent runtime.
If volatile memory is used the contents of the ODMs on an Agent will be present for the initialization procedure; otherwise the ODMs will be considered empty or absent.
        </t>
        <t>
The procedure to initialize an Agent is as follows:
        </t>
        <ol>
          <li>
            <t>
All ADM-defined VAR objects SHALL have their value set to one of the following:
            </t>
            <ul>
              <li>
If an Initializer is defined for the VAR, the value is the result of evaluating the associated Initializer expression and then <xref target="sec-proc-cast">casting</xref> to the VAR type.
              </li>
              <li>
Otherwise, the value is <tt>undefined</tt>.
              </li>
            </ul>
            <t>
Any ODM-defined VAR objects MAY retain their state.
            </t>
          </li>
          <li>
All ADM-defined TBR and SBR objects SHALL have their Enabled state set to the Initial Enabled value.
Any ODM-defined TBR and SBR objects MAY retain their Enabled state.
Any rules which are enabled are ready for processing.
          </li>
        </ol>
      </section>
      <section anchor="sec-proc-resolve">
        <name>ARI Resolving</name>
        <t>
Within an ADM, ARIs present in the various fields of object definitions are URI References, which can take the form of Relative URIs (see <xref section="4.2" target="RFC3986"/>).
Any ARIs within an ADM definition SHALL be handled as URI References and resolved in accordance with the procedure of <xref section="5" target="RFC3986"/> with the following used as a Base URI:
        </t>
        <ul>
          <li>
For ARIs within a single AMM object definition, the non-parameterized ARI of that object SHALL be the Base URI.
This includes ARIs used in nested structures under the object definition; the object is the anchor point.
          </li>
          <li>
For all other ARIs, the default Base URI <tt>ari:/</tt> SHALL be the Base URI.
This means that all ARIs within an ADM <em>do not</em> require a URI scheme part.
          </li>
        </ul>
      </section>
      <section anchor="sec-proc-deref">
        <name>Dereferencing</name>
        <t>
An <xref target="sec-value-objref">object-reference value</xref> contains an identity and a parameter part.
Dereferencing an OBJ-REF uses the identity to look up a specific defined object available to the agent.
        </t>
        <t>
The process of dereferencing a value is as follows:
        </t>
        <ol>
          <li>
The value has to contain an object reference.
If the value is not an object reference, this procedure stops and is considered failed.
          </li>
          <li>
The OBJ-REF namespace (whether text or enumeration) is used to search for a defined ADM or ODM namespace.
If no corresponding namespace is available, this procedure stops and is considered failed.
          </li>
          <li>
Within the namespace the object type and object name (whether text or enumeration) is used to search for a specific defined object.
If no corresponding object is available, this procedure stops and is considered failed.
          </li>
        </ol>
      </section>
      <section anchor="sec-proc-params">
        <name>Parameter Handling</name>
        <t>
An <xref target="sec-value-objref">object-reference value</xref> contains an identity and a parameter part.
The parameter part of an OBJ-REF represents the <xref target="sec-value-objref-params">actual parameters</xref> being used.
        </t>
        <t>
The process to validate and reconcile provided actual parameters against an object's formal parameters is as follows:
        </t>
        <ol>
          <li>
If the object has formal parameters differing in size from the actual parameters, this procedure stops and is considered failed.
          </li>
          <li>
            <t>
For each actual parameter, the processor performs the following:
            </t>
            <t>
If the value is a <tt>TYPEDEF-REF</tt> and the value itself has a parameter, the original value is replaced by the result of a <xref target="sec-proc-cast-typedef">type cast</xref> on the parameter value.
If the cast fails this procedure stops and is considered failed.
            </t>
          </li>
          <li>
            <t>
For each correlated pair of single formal and actual parameter, the processor performs the following:
            </t>
            <ol>
              <li>
                <t>
If the actual parameter is <tt>undefined</tt> and the formal parameter defines a default value, that default replaces the actual parameter value.
                </t>
                <t>
If the actual parameter is still <tt>undefined</tt>, this procedure stops and is considered failed.
FIXME: should this pass through without failure? That's the ECMAscript way.
                </t>
              </li>
              <li>
The actual parameter is cast to the type of the formal parameter in accordance with <xref target="sec-proc-cast"/>.
If the cast fails, this procedure stops and is considered failed.
              </li>
            </ol>
          </li>
        </ol>
        <t>
An implementation MAY perform deferred "lazy" processing of any of the above steps, causing a failure when the actual parameter value is needed.
One caveat about deferred validation is that it will not fail if the parameter is unused, which is not necessarily a problem but could mask other issues in whatever generated the parameters.
        </t>
      </section>
      <section anchor="sec-proc-prod">
        <name>Value Production</name>
        <t>
Value production can be thought of as a common behavior used for <xref format="title" target="sec-proc-exec"/>, <xref format="title" target="sec-proc-eval"/>, and <xref format="title" target="sec-proc-rpt"/> activities.
Within the AMM the following entities have a value production procedure: CONST, EDD, and VAR object references.
        </t>
        <section anchor="sec-proc-exec-const-var">
          <name>CONST and VAR References</name>
          <t>
Both CONST and VAR objects act as a store of a single literal value within the Agent.
Formal parameters on either CONST or VAR objects are applicable only when the objects store a value which itself contains parameters with at least one <tt>LABEL</tt> type.
          </t>
          <t>
The value production for these are as follows:
          </t>
          <ol>
            <li>
The processor dereferences the OBJ-REF in accordance with <xref target="sec-proc-deref"/>.
If the dereference fails, this procedure stops and is considered failed.
            </li>
            <li>
The processor verifies that the OBJ-REF actual parameters, if any, are consistent with the formal parameters of the object from which production is requested in accordance with <xref target="sec-proc-params"/>.
For this procedure it is consistent to have no actual parameters but defined formal parameters, that case is handled below.
If there is inconsistency, this procedure stops and is considered failed.
            </li>
            <li>
              <t>
When no actual parameters are present (regardless of formal parameters), the stored value is considered to be the produced value and this procedure is complete.
              </t>
              <t>
When actual parameters are present, the the stored value is augmented into the produced value by:
              </t>
              <ol>
                <li>
Substituting any <tt>LABEL</tt> actual parameters in the value, recursively in the case of a <xref target="sec-type-collections">collection</xref> value.
This augmentation has no effect on the stored value, it occurs only in the produced value.
                </li>
                <li>
It is valid for an actual parameter to have no substitution occur, but it is not valid for a <tt>LABEL</tt> in the value to not have a corresponding actual parameter and in such case this procedure stops and is considered failed.
                </li>
              </ol>
            </li>
          </ol>
        </section>
        <section anchor="sec-proc-exec-edd">
          <name>EDD References</name>
          <t>
For EDD object references, the actual parameters are used by the underlying implementation to produce the value in an arbitrary way.
The produced value is typically either a <xref target="typedef-simple"><tt>SIMPLE</tt></xref> value or a <xref target="typedef-tbl">Tabular Report</xref>.
          </t>
          <t>
The value production for these are as follows:
          </t>
          <ol>
            <li>
The processor dereferences the OBJ-REF in accordance with <xref target="sec-proc-deref"/>.
If the dereference fails, this procedure stops and is considered failed.
            </li>
            <li>
The processor verifies that the OBJ-REF actual parameters, if any, are consistent with the formal parameters of the object from which production is requested in accordance with <xref target="sec-proc-params"/>.
If there is inconsistency, this procedure stops and is considered failed.
            </li>
            <li>
              <t>
The processor passes the execution on to the underlying implementation of the EDD or TBLT being produced from.
              </t>
              <t>
The context given to the implementation is the following:
              </t>
              <dl newline="true">
                <dt>Object Identity:</dt>
                <dd>This gives visibility into the OBJ-REF which was dereferenced during the production.</dd>
                <dt>Parameters:</dt>
                <dd>The set of actual parameters augmented for the production.</dd>
                <dt>Result Storage:</dt>
                <dd>The result of the production is placed here before completion.</dd>
              </dl>
              <t>
The initial state of the Result Storage is the <tt>undefined</tt> value.
It is an implementation matter and <xref target="auth_consid">author consideration</xref> to enforce that the produced value is consistent with the type of the object.
              </t>
            </li>
          </ol>
        </section>
      </section>
      <section anchor="sec-proc-exec">
        <name>Execution</name>
        <t>
Within the AMM only two entities have an execution procedure: controls and macros.
Controls are executed by reference, while macros are executed both by value and by reference.
        </t>
        <section anchor="sec-proc-exec-valueref">
          <name>Value-Producing Object References</name>
          <t>
The execution of a <xref target="typedef-valueref"><tt>VALUE-REF</tt></xref> producing a value of any type is as follows:
          </t>
          <ol>
            <li>
The value is produced from the OBJ-REF in accordance with <xref target="sec-proc-prod"/>.
This step includes substitution of any <tt>LABEL</tt> parameters within the value.
            </li>
            <li>
              <t>
If the value is an <xref target="typedef-mac"><tt>MAC</tt></xref> type, this value is executed in accordance with <xref target="sec-proc-exec-mac"/>.
              </t>
              <t>
Otherwise, the execution is considered failed.
              </t>
            </li>
          </ol>
        </section>
        <section anchor="sec-proc-exec-ctrl">
          <name>CTRL References</name>
          <t>
The execution of an OBJ-REF referencing a <xref format="title" target="sec-obj-ctrl"/> is as follows:
          </t>
          <ol>
            <li>
The processor dereferences the OBJ-REF in accordance with <xref target="sec-proc-deref"/>.
If the dereference fails, this procedure stops and is considered failed.
            </li>
            <li>
The processor verifies that the OBJ-REF actual parameters, if any, are consistent with the formal parameters of the CTRL being executed in accordance with <xref target="sec-proc-params"/>.
If there is inconsistency, this procedure stops and is considered failed.
            </li>
            <li>
              <t>
The processor passes the execution on to the underlying implementation of the CTRL being executed.
              </t>
              <t>
The context given to the implementation is the following:
              </t>
              <dl newline="true">
                <dt>Manager:</dt>
                <dd>The manager which directly caused this execution, if available, is provided as context.</dd>
                <dt>Object Identity:</dt>
                <dd>This gives visibility into the OBJ-REF which was dereferenced during the execution.</dd>
                <dt>Parameters:</dt>
                <dd>The set of actual parameters augmented for the execution.</dd>
                <dt>Result Storage:</dt>
                <dd>The result of the execution is placed here before completion.</dd>
              </dl>
              <t>
The initial state of the Result Storage is taken from the default result the CTRL, if defined, or <tt>null</tt> otherwise.
              </t>
            </li>
          </ol>
          <t>
If the execution procedure fails, the result value SHALL be treated as the <tt>undefined</tt> value for the purposes of any subsequent reporting.
          </t>
        </section>
        <section anchor="sec-proc-exec-mac">
          <name>MAC Values</name>
          <t>
The execution of a <xref format="title" target="typedef-mac"/> value, which is structured as an AC, is as follows:
          </t>
          <ol>
            <li>
The processor iterates through all items of the AC recursively, replacing any <tt>VALUE-REF</tt> with their value produced in accordance with <xref target="sec-proc-prod"/>.
If any dereference fails this procedure stops and is considered failed.
            </li>
            <li>
              <t>
From this point on the AC contains only <tt>CTRL-REF</tt> values or nested AC with <tt>CTRL-REF</tt>.
The processor iterates through all items of the AC recursively, in depth-first order, and performs the following:
              </t>
              <t>
If the item is an <tt>CTRL-REF</tt> it is executed in accordance with <xref target="sec-proc-exec-ctrl"/>.
If the execution fails, this procedure stops and is considered failed.
              </t>
              <t>
Otherwise, this procedure stops and is considered failed.
              </t>
            </li>
          </ol>
          <t>
One effect of this procedure is that if any referenced MAC values cannot be produced the procedure fails before any CTRL is executed.
Another effect of this procedure is that if any referenced CTRL fails during execution the processing fails immediately and subsequent CTRLs or MACs are not executed.
          </t>
          <aside>
            <t>
The <xref target="sec-agentadm">Base ADM</xref> includes a wrapper CTRL "catch" which is used to ignore possible failures of specific executions and allow MAC processing to continue.
            </t>
          </aside>
        </section>
      </section>
      <section anchor="sec-proc-eval">
        <name>Evaluation</name>
        <t>
Within the AMM the following entities have an evaluation procedure: references to value-producing objects, OPERs, and TYPEDEFs and and EXPR values.
        </t>
        <t>
For the purposes of these procedures, it is important to distinguish between an EXPR <em>value</em> and a reference to a value-producing object which is typed to produce an <tt>EXPR</tt> value.
        </t>
        <section anchor="sec-proc-eval-valueref">
          <name>Value-Producing Object References</name>
          <t>
The evaluation of a <xref target="typedef-valueref"><tt>VALUE-REF</tt></xref> producing a value of any type is as follows:
          </t>
          <ol>
            <li>
The value is produced from the OBJ-REF in accordance with <xref target="sec-proc-prod"/>.
This step includes substitution of any <tt>LABEL</tt> parameters within the value.
            </li>
            <li>
              <t>
If the value is an <xref target="typedef-expr"><tt>EXPR</tt></xref> type, this value is considered to be a sub-expression and is evaluated in accordance with <xref target="sec-proc-eval-expr"/>.
              </t>
              <t>
Otherwise, the produced value is considered to be the evaluation result.
              </t>
            </li>
          </ol>
        </section>
        <section anchor="sec-proc-eval-oper">
          <name>OPER References</name>
          <t>
This procedure applies only during the evaluation of a containing <xref target="sec-proc-eval-expr">expression</xref>; an OPER cannot be evaluated in isolation.
          </t>
          <t>
The evaluation of an OBJ-REF referencing a <xref format="title" target="sec-obj-oper"/> is as follows:
          </t>
          <ol>
            <li>
The processor verifies that the actual parameters, if any, are consistent with the formal parameter associated with the OPER being evaluated.
If there is inconsistency, this procedure stops and is considered failed.
            </li>
            <li>
              <t>
The processor passes the evaluation on to the underlying implementation of the OPER being evaluated.
              </t>
              <t>
The context available to the implementation is the following:
              </t>
              <dl newline="true">
                <dt>Object Identity:</dt>
                <dd>This gives visibility into the OBJ-REF which was dereferenced during the evaluation.</dd>
                <dt>Parameters:</dt>
                <dd>The set of actual parameters augmented for the evaluation.</dd>
                <dt>Expression Stack:</dt>
                <dd>The operands are popped from this stack and the result is pushed here before completion.</dd>
              </dl>
            </li>
          </ol>
          <t>
If the evaluation procedure fails, the failure SHALL propagate up to any expression evaluation.
          </t>
        </section>
        <section anchor="sec-proc-eval-typedef">
          <name>TYPEDEF References</name>
          <t>
This procedure applies only during the evaluation of a containing <xref target="sec-proc-eval-expr">expression</xref>; a TYPEDEF cannot be evaluated in isolation.
The evaluation of a TYPEDEF reference is handled similarly to a unary OPER but it occurs entirely within the Agent and does not rely on an object-specific implementation.
          </t>
          <t>
The evaluation of an OBJ-REF referencing a <xref format="title" target="sec-obj-typedef"/> is as follows:
          </t>
          <ol>
            <li>
If the TYPEDEF-REF itself has no parameters, the input value is popped from the stack.
If the TYPEDEF-REF itself has one parameter, the input value is that parameter.
If the TYPEDEF-REF itself has more than parameter, this procedure stops and is considered failed.
            </li>
            <li>
The result value is a <xref target="sec-proc-cast-typedef">type cast</xref> on the input value.
If the cast fails this procedure stops and is considered failed.
            </li>
            <li>The result value is pushed onto the stack.</li>
          </ol>
        </section>
        <section anchor="sec-proc-eval-expr">
          <name>EXPR Values</name>
          <t>
The evaluation of an <xref format="title" target="typedef-expr"/> value, which is structured as an AC, is as follows:
          </t>
          <ol>
            <li>
An empty value stack is initialized for this evaluation.
            </li>
            <li>
              <t>
For each item of the AC, recursively, the processor performs the following:
              </t>
              <t>
If the value is a <tt>VALUE-REF</tt>, the original value is replaced by the value produced in accordance with <xref target="sec-proc-prod"/>.
If the production fails this procedure stops and is considered failed.
              </t>
            </li>
            <li>
              <t>
From this point on the AC is treated as a Reverse Polish Notation (RPN) sequence, where the following is performed on each item in the AC in sequence:
              </t>
              <t>
If the item is an <tt>OPER-REF</tt> it is evaluated in accordance with <xref target="sec-proc-eval-oper"/>.
If the evaluation fails, this procedure stops and is considered failed.
              </t>
              <t>
Otherwise, the item is pushed onto the stack.
              </t>
            </li>
            <li>
If the value stack is empty or has more than one item, this procedure stops and is considered failed.
Otherwise, the result of the evaluation is the single literal value in the stack.
            </li>
          </ol>
          <t>
One effect of this procedure is that if any referenced values cannot be produced the procedure fails before any OPER is evaluated.
Another effect of this procedure is that if any referenced OPER fails during evaluation or any value production fails the EXPR processing fails immediately and subsequent OPER-REFs, EXPRs, or <tt>VALUE-REF</tt> references are not evaluated.
          </t>
        </section>
      </section>
      <section anchor="sec-proc-rpt">
        <name>Reporting</name>
        <t>
Within the AMM the following entities have a reporting context: CONST, EDD, and VAR objects and RPTT values.
The value-producing objects are reported-on by reference, while RPTT are reported-on both by value and by reference.
        </t>
        <section anchor="sec-proc-rpt-valueref">
          <name>Value-Producing Object References</name>
          <t>
The reporting on a <xref target="typedef-valueref"><tt>VALUE-REF</tt></xref> producing a value of any type is as follows:
          </t>
          <ol>
            <li>
The value is produced from the OBJ-REF in accordance with <xref target="sec-proc-prod"/>.
This step includes substitution of any <tt>LABEL</tt> parameters within the value.
            </li>
            <li>
              <t>
If the value is an <xref target="typedef-rptt"><tt>RPTT</tt></xref> type, this value is used to generate report items in accordance with <xref target="sec-proc-rpt-rptt"/>.
              </t>
              <t>
Otherwise, the produced value is used as the single RPT item.
              </t>
            </li>
            <li>
The <xref target="typedef-rpt">RPT value</xref> is produced by combining: the source ARI used for this procedure, the current timestamp, and the items generated in the previous step.
            </li>
          </ol>
        </section>
        <section anchor="sec-proc-rpt-rptt">
          <name>RPTT Values</name>
          <t>
The reporting on a <xref format="title" target="typedef-rptt"/> value, which is structured as an AC, is as follows:
          </t>
          <ol>
            <li>
An empty item list is initialized for this template.
            </li>
            <li>
              <t>
The processor iterates through all items of the AC, performing the following:
              </t>
              <t>
If the item is an <tt>EXPR</tt> value it is replaced by the result of evaluation in accordance with <xref target="sec-proc-eval"/>.
If the evaluation fails the <tt>undefined</tt> value is used as a substitute.
              </t>
              <t>
Otherwise, if the item is a <tt>VALUE-REF</tt> it is replaced by the value produced in accordance with <xref target="sec-proc-prod"/>.
If the production fails the <tt>undefined</tt> value is used as a substitute.
              </t>
              <t>
Otherwise, the result of the production is the value appended to the item list.
              </t>
            </li>
          </ol>
          <t>
Because this procedure acts on an RPTT value and not an object reference, the report itself cannot be assembled within this context.
One effect of this procedure is that if any item of the RPTT cannot be reported on, the <tt>undefined</tt> value is used as a sentinel and the other report items are still generated.
          </t>
        </section>
      </section>
      <section anchor="sec-proc-cast">
        <name>Type Casting</name>
        <t>
The type system of the AMM allows conversions of values between different literal and semantic types in a way which is supposed to preserve the "meaning" of the value.
        </t>
        <t>
In some cases, casting is performed implicitly by the Agent while other cases the casting is explicitly part of an expression.
One example of implicit casting is during <xref format="title" target="sec-proc-params"/> to ensure each processed parameter meets the formal parameter type signature.
Another example of implicit casting is for numeric operators in the <xref target="sec-agentadm-opers">Agent ADM</xref>.
        </t>
        <section anchor="sec-proc-cast-bool">
          <name>BOOL Type</name>
          <t>
The AMM has the concepts of "truthy" and "falsey" as being the result of casting to <tt>BOOL</tt> type.
Similar to the <tt>ToBoolean()</tt> function from <xref target="ECMA-262"/>, the AMM casting treats the following as falsey and every other value as truthy: 
          </t>
          <ul>
            <li>
              <tt>undefined</tt>
            </li>
            <li>
              <tt>null</tt> value of <tt>NULL</tt></li>
            <li>
              <tt>false</tt> value of <tt>BOOL</tt></li>
            <li>Zero value of <tt>BYTE</tt>, <tt>UINT</tt>, <tt>INT</tt>, <tt>UVAST</tt>, and <tt>VAST</tt></li>
            <li>Positive and negative zero, and NaN values of <tt>REAL32</tt> and <tt>REAL64</tt></li>
            <li>Empty value of <tt>TEXTSTR</tt> and <tt>BYTESTR</tt></li>
          </ul>
          <t>
When casting a value to <tt>BOOL</tt> type, the processor SHALL use the result value <tt>false</tt> if the original value is falsey and <tt>true</tt> otherwise.
          </t>
        </section>
        <section anchor="sec-proc-cast-numeric">
          <name>NUMERIC Types</name>
          <t>
The casting of a value to a <tt>NUMERIC</tt> type is intended to easily allow mixed-type expressions while keeping the number of operators and parameter unions small.
          </t>
          <t>
When casting a value to an <tt>INTEGER</tt> type from any other <tt>NUMERIC</tt> type, the processor SHALL perform the following:
          </t>
          <ol>
            <li>If the input is one of the <tt>FLOAT</tt> types and is not finite, the cast is considered failed.</li>
            <li>If the input is one of the <tt>FLOAT</tt> types, the value is truncated to an integer by rounding toward zero.</li>
            <li>If the input value is outside the domain of the output type, the cast is considered failed.</li>
          </ol>
          <t>
When casting a value to an <tt>FLOAT</tt> type from any other <tt>NUMERIC</tt> type, the processor SHALL perform the following:
          </t>
          <ol>
            <li>If the input value is outside the domain of the output type, the cast is considered failed.</li>
          </ol>
          <section>
            <name>Numeric Promotion</name>
            <t>
While the earlier discussion of numeric type casting is about converting from an input type to an output type, the concept of a type promotion is about finding a "least compatible type" which can accommodate most, if not all, of the input type range.
Casting to a promoted type is called an "up" cast, and from a promoted type a "down" cast.
            </t>
            <t>
The promotion order for <tt>NUMERIC</tt> types is as follows:
            </t>
            <ul>
              <li>
A promoted type has a larger span of values (the difference between largest and smallest representable value).
            </li>
              <li>
A promoted type can gain signed-ness but not lose it.
            </li>
              <li>
A promoted type can lose precision for some values.
            </li>
            </ul>
            <t>
This promotion logic does not guarantee that an up-cast will always succeed (<em>e.g.</em> some large <tt>UVAST</tt> values will not fit within a <tt>VAST</tt> or <tt>REAL32</tt>) but does provide a strict ordering for finding a compatible type between two <tt>NUMERIC</tt> values.
The "least compatible type" between two types SHALL be defined as the smallest up-cast that will accommodate the input types, as indicated in <xref target="tab-numeric-promotion"/>.
This is almost a strict ordering except for the cast of <tt>INT</tt> and <tt>UVAST</tt> to <tt>VAST</tt> to accommodate both the signed-ness and the size of the inputs.
            </t>
            <table anchor="tab-numeric-promotion">
              <name>NUMERIC Type Promotion</name>
              <thead>
                <tr>
                  <th/>
                  <th>BYTE</th>
                  <th>UINT</th>
                  <th>INT</th>
                  <th>UVAST</th>
                  <th>VAST</th>
                  <th>REAL32</th>
                  <th>REAL64</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <th>BYTE</th>
                  <td>BYTE</td>
                  <td>UINT</td>
                  <td>INT</td>
                  <td>UVAST</td>
                  <td>VAST</td>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>UINT</th>
                  <td/>
                  <td>UINT</td>
                  <td>INT</td>
                  <td>UVAST</td>
                  <td>VAST</td>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>INT</th>
                  <td/>
                  <td/>
                  <td>INT</td>
                  <td>VAST</td>
                  <td>VAST</td>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>UVAST</th>
                  <td/>
                  <td/>
                  <td/>
                  <td>UVAST</td>
                  <td>VAST</td>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>VAST</th>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td>VAST</td>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>REAL32</th>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td>REAL32</td>
                  <td>REAL64</td>
                </tr>
                <tr>
                  <th>REAL64</th>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td/>
                  <td>REAL64</td>
                </tr>
              </tbody>
            </table>
          </section>
        </section>
        <section anchor="sec-proc-cast-typedef">
          <name>Semantic Types</name>
          <t>
Unlike literal type casting, which has the potential to change the form of the value itself, casting to a semantic type is meant to either affirm or add an association between an AMM value and a TYPEDEF object.
All of this processing is performed independently of any literal-type-specific handling, so none of it needs to be specialized to specific TYPEDEF objects.
          </t>
          <t>
The cast of an input value to a TYPEDEF is as follows:
          </t>
          <ol>
            <li>
The underlying literal types usable with a TYPEDEF are obtained by recursively flattening the TYPEDEF union(s) down to literal types and removing duplicate literal types after the first instance of them.
This defines a priority list of acceptable literal types for the result.
Because a TYPEDEF union is unchanging within an ADM (see <xref target="sec-obj-typedef"/>) a processor <bcp14>MAY</bcp14> cache this flattened type list.
            </li>
            <li anchor="step-cast-literal">
The input value is cast to each literal type in the list, and the first successful cast is taken as the literal type of the result value.
If none of the literal types can successfully cast the input value, this procedure stops and is considered failed.
            </li>
            <li>
The result value is associated with the the TYPEDEF being cast to, and that is the result of this procedure.
            </li>
          </ol>
          <aside>
            <t>
Because the processing in Step <xref format="counter" target="step-cast-literal"/> could successfully match multiple literal types for an input value, the ordering of that list (and thus the ordering of the union members which flattened to produce that list) is significant.
            </t>
          </aside>
        </section>
      </section>
      <section anchor="sec-proc-ari-typing">
        <name>Translating ARIs and Semantic Types</name>
        <t>
The procedures in this section allow AMM values, which can have a <xref target="sec-type-semantic">semantic type</xref>, to be translated into and out of the <xref target="sec-ari">ARI syntax</xref>, which has no semantic type information.
They also describe a way to use type-less literal values to give further compression of values in certain circumstances.
        </t>
        <t>
The compression of removing type information is possible only when the context in which the value is being used has a specific semantic or literal type associated with it.
For example, when a formal object parameter or a report item is typed to either a literal type or a semantic type that doesn't represent a type union then a value being used for the parameter or item can only have that specific type; any other value type will be mismatched and invalid.
Another way of looking at this compression is when the value has the same type as its context requires, then the value's type is redundant and can be elided without loss of information.
        </t>
        <t>
In addition to compression by eliding semantic type within a context, there are also some literal types which have values which only exist in that type.
For example, the <tt>BOOL</tt> value <tt>true</tt> exists only within that type while the <tt>UINT</tt> value <tt>5</tt> is also within the domain of <tt>INT</tt> and several others.
        </t>
        <t>
For the procedures below, the contexts which provide type information SHALL be: all formal parameters, <tt>VALUE-REF</tt> values, report template items, tabular columns.
        </t>
        <t>
When translating from an AMM value into an ARI, the processor performs the following:
        </t>
        <ol>
          <li>
If the use context is associated with a TYPEDEF and the value is associated with an ambiguous or incompatible TYPEDEF, the ARI form <bcp14>SHALL</bcp14> be wrapped in a TYPEDEF-as-cast ARI.
An ambiguous type is one where the presence of the inner type cast produces a different result than if the cast were absent.
An incompatible type is one where the presence of the inner cast results in a failure of the outer cast.
          </li>
          <li>
If the use context is associated with a single literal type (no unions) and the literal type is present in Table 2 "Literal Implied Types" of <xref target="I-D.birrane-dtn-ari"/>, the ARI form <bcp14>MAY</bcp14> have its literal type removed.
          </li>
        </ol>
        <t>
When translating from an ARI into an AMM value, the processor performs the following: 
        </t>
        <ol>
          <li>If the use context is associated with a type and the value is associated with a different TYPEDEF or no TYPEDEF, the value <bcp14>SHALL</bcp14> be cast to the context type in accordance with <xref target="sec-proc-cast"/>.</li>
        </ol>
      </section>
    </section>
    <!--
        <section title="Numeric Promotions">
          <t>
               When attempting to evaluate operators of different types, 
               an Agent may need to promote operands until 
               they are of the correct type. For example, if an Operator is 
               given both an INT and a REAL32, the INT should be promoted to a
                REAL32 before the Operator is applied.   
            </t>
          <t>
               Listing legal promotion rules is mandatory for ensuring that 
               behavior is similar across multiple implementations of Agents 
               and Managers. The listing of legal promotions in the AMM are 
               listed in <xref target="num_promo"/>. In this Figure, operands 
               are listed across the top row and down the first column. The
               resultant type of the promotion is listed in the table at their 
               intersection.
           </t>
          <figure align="center" anchor="num_promo" suppress-title="false" title="Numeric Promotions">
            <artwork align="center" xml:space="preserve">
            INT     UINT     VAST     UVAST     REAL32   REAL64  
   INT    | INT    | INT    | VAST   | UNK    | REAL32 | REAL64 |
   UINT   | INT    | UINT   | VAST   | UVAST  | REAL32 | REAL64 |
   VAST   | VAST   | VAST   | VAST   | VAST   | REAL32 | REAL64 |
   UVAST  | UNK    | UVAST  | VAST   | UVAST  | REAL32 | REAL64 |
   REAL32 | REAL32 | REAL32 | REAL32 | REAL32 | REAL32 | REAL64 |
   REAL64 | REAL64 | REAL64 | REAL64 | REAL64 | REAL64 | REAL64 |
               </artwork>
          </figure>
          <t>
                The AMM does not permit promotions between non-numeric types, and numeric
                promotions not listed in this section are not allowed. Any attempt
                to perform an illegal promotion SHOULD result in an error.
           </t>
        </section>
        <section title="Numeric Conversions">
          <t>
                  Variables, Expressions, and Predicates are typed values.  When 
               attempting to assign a value of a different type, a numeric 
               conversion must be performed. Any numeric type may be converted 
               to any other numeric type in accordance with the C rules for 
               arithmetic type conversions.
           </t>
        </section>
      </section>
    </section>
-->
    <section anchor="sec-yang">
      <name>YANG Module Profile</name>
      <t>
This section provides an ADM syntax in the form of a YANG module conforming to a profile of <xref target="RFC7950"/> defined in this section.
      </t>
      <t>
It is not required that this encoding be used for transmission of ADM information over the wire in the context of a network deployment.
Since the AMM is designed to allow for multiple encodings, the expression of ADMs in a YANG module is intended to support translation to other encodings without loss of information.
      </t>
      <t>
Some aspects of this YANG profile restrict the allowable definitions to conform with <xref target="sec-obj"/> and by doing so make YANG modules defining ADMs incompatible with YANG modules intended for NETCONF, RESTCONF, or other applications.
Because of this, YANG modules defining ADMs SHALL be managed separately from the "YANG Module Names" sub-registry of <xref target="IANA-YANG"/>.
See the ADM sub-registry defined in <xref section="9.3" target="I-D.birrane-dtn-ari"/> for registration of ADM modules.
For the remainder of this section, a YANG module defining an ADM will be referred to as an "ADM module" and a YANG module for any other purpose will be referred to as a "Legacy module" to differentiate it.
      </t>
      <t>
After explanation of extensions in <xref target="sec-yang-extensions"/>, the following minimal ADM module will be expanded upon for further examples.
      </t>
      <sourcecode markers="true" name="example-adm.yang" type="yang">
module "example-adm" {
  yang-version 1.1;
  namespace "ari:/example-adm";
  prefix "example-adm";

  import "ietf-amm" {
    prefix "amm";
  }

  organization "Example Org.";
  description "Example module.";
  amm:enum "4294967296";
}
</sourcecode>
      <section anchor="sec-yang-proc">
        <name>Inherited YANG Module Processing</name>
        <t>
The benefit of using the pre-existing YANG syntax is to take advantage of both tools that process YANG modules as well as the syntax and semantics provided by YANG.
        </t>
        <section anchor="sec-yang-proc-reuse">
          <name>Direct Reuse</name>
          <t>
The following statements and behaviors of YANG are usable within an ADM with no modification:
          </t>
          <dl>
            <dt>Modules and Submodules:</dt>
            <dd>
The existing concepts and syntax of modules and submodules defined in <xref section="5.1" target="RFC7950"/> is unchanged for ADM modules.
Because ADM modules occupy a separate ecosystem than Legacy modules, there will not be any cross-imports between the two ecosystems.
There is no harm in including an ADM module in a Legacy module store, but it will have no entities usable with NETCONF, <em>etc.</em>
            </dd>
            <dt>Module Importing:</dt>
            <dd>
The existing concept and syntax of importing a module namespace, to reference objects in the other module, defined in <xref section="5.1.1" target="RFC7950"/> is unchanged for ADM modules.
Because the import includes a specific revision, the ARI references to objects in that other module do not need any ADM revision information.
            </dd>
            <dt>File Layout:</dt>
            <dd>
The existing file naming defined in <xref section="5.2" target="RFC7950"/> is unchanged for ADM modules.
Because ADM modules occupy a separate ecosystem than Legacy modules, their file stores SHALL be kept separate.
            </dd>
            <dt>Namespaces:</dt>
            <dd>
Although an ADM module has no use for an XML namespace as defined in <xref section="5.3" target="RFC7950"/>, the "namespace" statement is preserved for tool compatibility.
For ADM modules, the "namespace" statement argument SHALL be the text-form ARI referencing the ADM itself.
For example, the ADM "example-adm" will have a namespace of <tt>ari:/example-adm</tt> which is valid YANG.
            </dd>
            <dt>Name Resolution:</dt>
            <dd>
The existing name resolution logic described in <xref section="5.4" target="RFC7950"/> is unchanged for ADM modules.
Because ADM modules are a flat object namespace, the complexity of namespaces is significantly simplified compared to Legacy modules.
            </dd>
            <dt>Reusable Groups:</dt>
            <dd>
The existing group reuse logic described in <xref section="4.2.6" target="RFC7950"/> is unchanged for ADM modules.
Because ADM modules are a flat object namespace, the utility of group reuse in an ADM module is limited to formal parameters, <tt>VALUE-REF</tt> definitions, and table columns.
            </dd>
          </dl>
        </section>
        <section anchor="sec-yang-proc-restrict">
          <name>Restrictions and Exclusions</name>
          <t>
Because of the different interpretation of data definitions for an ADM module, the following restrictions are used to limit pre-existing valid YANG syntax within an ADM module:
          </t>
          <dl>
            <dt>Built-In Types:</dt>
            <dd>
Because ADM modules have data that ultimately follows the <xref target="sec-value">AMM value</xref> model, the built-in types listed in <xref section="4.2.4" target="RFC7950"/> do not directly apply to ADM modules.
In order to maintain some amount of tool compatibility, the <xref target="sec-ammadm">Base ADM</xref> treats AMM literal types as YANG typedefs.
An ADM module SHALL NOT use any YANG built-in type or any typedef defined outside of an ADM module.
As defined in this document, there is no direct deterministic mapping between Legacy module typing and ADM module typing.
            </dd>
            <dt>Node Structure:</dt>
            <dd>
The data node statements "container", "leaf", "leaf-list", "list" have modified interpretations for this profile as defined in <xref target="sec-yang-nodes"/>.
The data node statements "anydata", or "anyxml" have no use in an ADM module and SHALL NOT be present.
            </dd>
            <dt>Configuration Versus State:</dt>
            <dd>
Because of the different semantics of an ADM module from a Legacy module, there is no concept of a labeling of some data as "configuration" and other as "state".
An ADM module SHALL NOT contain any "config" statements.
            </dd>
            <dt>Node Presence Versus Value:</dt>
            <dd>
Rather than being an extrinsic notion of presence or absence, AMM objects can use type unions with the <tt>NULL</tt> type to indicate optional values and AMM values can use the <tt>null</tt> value to represent that state.
In the case of formal parameters, the use of a "default" statement is used to indicate behavior when an actual parameter is <tt>undefined</tt>.
In any case, the AMM value is always present when defined in the structure of an AMM object.
An ADM module SHALL NOT contain any "mandatory" statements.
            </dd>
            <dt>Nested Object Definitions:</dt>
            <dd>
Because of the flat structure of an ADM, the nesting allowed and encouraged by <xref section="5.5" target="RFC7950"/>, are not allowed to be present in an ADM module.
An ADM module SHALL contain all AMM object definitions at the top (module) level.
            </dd>
            <dt>XPath Expressions:</dt>
            <dd>
The ADM module makes no use of XML or XPath in its definitions or logical constraints, so the behaviors described in <xref section="6.4" target="RFC7950"/> and in statements containing XPath expressions ("must", "when", "path", "augment") do not apply to ADM modules.
All references in an ADM module take the form of an ARI.
            </dd>
            <dt>NETCONF Operations:</dt>
            <dd>
Because an ADM module will not be used for modeling in NETCONF and related protocols, the statements associated with NETCONF operations ("action", "notification", "rpc") <bcp14>SHALL NOT</bcp14> be present in an ADM module.
            </dd>
            <dt>Extending Models:</dt>
            <dd>
Because the transport of AMM values takes the form of an ARI, which does not include identity information the way XML elements do, the concept of extending an existing Legacy model by another model as described in <xref section="4.2.8" target="RFC7950"/> cannot apply to an ADM.
The model extension "augment" statement SHALL NOT be present in an ADM module.
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-yang-nodes">
        <name>YANG Node Interpretations</name>
        <t>
Rather than fully redefine a data model for ADM module use, this profile reinterprets existing YANG node structure of <xref section="4.2.2" target="RFC7950"/> in the context of the AMM.
        </t>
        <t>
One difference in how the nodes are interpreted for an ADM module is related to the arguments to the node statements as identifiers.
While Legacy modules have been used to model data for XML representation for NETCONF (or equivalent representations for equivalent protocols), in the AMM values do not have explicit identifiers.
Because of this, data node identifiers in ADM modules are for local processing only and never appear in messages between Agents and Managers.
They are still valuable and are used by parameter handling procedures and in report and table visualization tools.
        </t>
        <t>
The AMM interpretation of YANG nodes is defined in the following subsections.
        </t>
        <section>
          <name>Leaf Nodes</name>
          <t>
A leaf node is used to indicate the presence of an AMM value of a specific literal or semantic type.
A leaf can either be top-level, to define the type of an object or parameter, or can be nested within a container node to define an AMM value within an AC.
As stated earlier, leaf nodes are always mandatory but can be typed to have a union with the <tt>NULL</tt> type in order to represent optional values.
          </t>
          <t>
The substatements of "type", "units", "status", "reference", and "description" are valid in this profile.
The "default" substatement applies only in certain circumstances, notably <xref target="sec-proc-params">formal parameters</xref> and has no effect otherwise.
          </t>
        </section>
        <section>
          <name>Leaf-List Nodes</name>
          <t>
A leaf-list node is used to indicate the presence of an AMM value of a specific literal or semantic type.
Because this node corresponds with multiple AMM values, this node applies only within a container node (see <xref target="sec-yang-nodes-container"/>).
          </t>
          <t>
The substatements of "min-elements", "max-elements", "type", "units", "status", "reference", and "description" are valid in this profile.
          </t>
        </section>
        <section anchor="sec-yang-nodes-container">
          <name>Container Nodes</name>
          <t>
A container node is used to indicate the presence of an AMM value that is an <xref format="title" target="sec-type-ac"/> with a constrained internal structure (specified by child nodes).
          </t>
          <t>
The substatements of "leaf", "leaf-list", "container", "status", "reference", and "description" are valid in this profile.
The leaf, leaf-list, and container substatements are interpreted as specification of the AC contents.
This profile disallows definition of nested tables, so the "list" substatement is not valid.
          </t>
        </section>
        <section>
          <name>List Nodes</name>
          <t>
A list node is used to define the structure of a table within a TBLT, which is used to produce a <xref format="title" target="typedef-tbl"/>.
Each leaf node within a list corresponds to a single column of the table.
          </t>
          <t>
The substatements of "key", "unique", "min-elements", "max-elements", "leaf", "container", "status", "reference", and "description" are valid in this profile.
The leaf and container substatements are interpreted as specification of the column content, being either a single value or an AC respectively.
          </t>
        </section>
        <section>
          <name>Choices</name>
          <t>
Although this profile makes no specific prohibitions against the use of the "choice" statement as a data node, it is expected that a choice will have limited utility in an ADM module.
Most alternative specifying can be done with semantic types containing type unions; leaving the only use of a choice between a simple value and an structured AC.
          </t>
        </section>
        <section>
          <name>Grouping and Uses</name>
          <t>
The mechanisms of "grouping" and "uses" statements are allowed with an ADM module unchanged, however because an ADM does not allow nested object structure the utility of grouping/uses is more limited.
One contrived example is a situation where sets of parameters are reused between multiple objects, which can define the formal parameters in a grouping statement and each "parameters" can apply "uses" substatement to pull in those formal parameter nodes.
          </t>
        </section>
      </section>
      <section anchor="sec-yang-extensions">
        <name>ADM Module Extensions</name>
        <t>
In order to provide syntax necessary for <xref format="title" target="sec-obj"/> definitions this document defines, via the <xref target="sec-yang-ammadm">DTNMA ADM</xref>, the following extensions for ADM modules.
        </t>
        <section>
          <name>The <tt>amm:enum</tt> Statement</name>
          <t>
This statement is used to apply an integer enumeration to an ADM module or object, which enables the compressed form of ARI discussed in <xref section="3.1" target="I-D.birrane-dtn-ari"/>.
The argument to this statement is an integer in the YANG range <tt>0..2^31-1</tt> to fit within the ARI syntax.
There are no substatements defined in this profile.
          </t>
        </section>
        <section>
          <name>The <tt>amm:parameters</tt> Statement</name>
          <t>
This statement is used to define the set of formal parameters that apply to the parent object.
There is no argument to this statement.
          </t>
          <t>
The substatements under this are an ordered sequence of formal parameter definitions, each a choice between data node statements interpreted according to <xref target="sec-yang-nodes"/>.
The parameters list itself does not contain metadata statements.
          </t>
          <table>
            <name>amm:parameters Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>leaf</td>
                <td>0..n</td>
              </tr>
              <tr>
                <td>container</td>
                <td>0..n</td>
              </tr>
              <tr>
                <td>choice</td>
                <td>0..n</td>
              </tr>
              <tr>
                <td>uses</td>
                <td>0..n</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of the parameters statement is below, where there are three defined parameters two of which have default values.
          </t>
          <sourcecode type="yang">
  amm:parameters {
    leaf first {
      type amm:uint {
        range "3..10";
    }
    leaf second {
      type amm:textstr;
      default "\"value\"";
    }
    container third {
      leaf-list _ {
        type amm:uint;
      }
      default "/AC/(3,5,8)"
  }
</sourcecode>
        </section>
        <section>
          <name>The <tt>amm:const</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-const"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, optional formal parameters, and a single <xref target="sec-yang-nodes">node</xref> that represents the produced value of the CONST.
The node statement SHALL contain a <tt>default</tt> value, which is the constant represented by this object.
          </t>
          <table>
            <name><tt>amm:const</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:parameters</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <th colspan="2">One data node:</th>
              </tr>
              <tr>
                <td>leaf</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>container</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>choice</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>uses</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of a simple-typed CONST is below.
          </t>
          <sourcecode type="yang">
  amm:const pi32 {
    leaf _ {
      type amm:real32;
      default "3.14159";
    }
    description "A truncated value of Pi.";
  }
</sourcecode>
          <t>
Another example of a semantic-typed <xref target="typedef-mac">MAC-valued</xref> CONST is below.
          </t>
          <sourcecode type="yang">
  amm:const do_thing {
    container {
      leaf-list _ {
        type amm:MAC-item;
      }
      default "/AC/(../CTRL/first,../CTRL/second(2))";
    }
    description "Execute two controls in sequence.";
  }
</sourcecode>
        </section>
        <section>
          <name>The <tt>amm:ctrl</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-ctrl"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, optional formal parameters, and an optional execution result.
If the <tt>amm:result</tt> substatement is present it SHALL contain a default value, used to initialize the Result Storage for the <xref target="sec-proc-exec-ctrl">execution procedure</xref>.
If the <tt>amm:result</tt> substatement is omitted the assumed result type SHALL be <tt>NULL</tt> with a default value of <tt>null</tt>.
          </t>
          <table>
            <name><tt>amm:ctrl</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:parameters</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:result</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of a single-parameter CTRL is below.
          </t>
          <sourcecode type="yang">
  amm:ctrl reset_count {
    parameters {
      leaf src {
        type amm:textstr;
        description "The name of the source.";
      }
    }
    result {
      leaf previous {
        type amm:UVAST;
        description "The value just before reset.";
      }
    }
    description "This control resets counts for the given source.";
  }
</sourcecode>
          <section>
            <name>The <tt>amm:result</tt> Statement</name>
            <t>
The result statement contains a single node which represents the result expected from executing a CTRL or evaluating an OPER.
            </t>
            <table>
              <name><tt>amm:result</tt> Substatements</name>
              <thead>
                <tr>
                  <th>Substatement</th>
                  <th>Cardinality</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>leaf</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>container</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>choice</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>uses</td>
                  <td>0..1</td>
                </tr>
              </tbody>
            </table>
          </section>
        </section>
        <section>
          <name>The <tt>amm:edd</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-edd"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, optional formal parameters, and a single <xref target="sec-yang-nodes">node</xref> that represents the produced value of the EDD.
The node substatement SHALL NOT contain a default value.
          </t>
          <table>
            <name><tt>amm:edd</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:parameters</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <th colspan="2">One data node:</th>
              </tr>
              <tr>
                <td>leaf</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>container</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>choice</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>uses</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of a simple-typed EDD is below.
          </t>
          <sourcecode type="yang">
  amm:edd tx_count {
    leaf _ {
      type amm:counter64;
      unit "frames";
    }
    description "The count of the number of frames sent.";
  }
</sourcecode>
        </section>
        <section>
          <name>The <tt>amm:oper</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-oper"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, optional formal parameters, an operands list, and an evaluation result.
          </t>
          <table>
            <name><tt>amm:edd</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:parameters</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>operands</td>
                <td>1</td>
              </tr>
              <tr>
                <td>result</td>
                <td>1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of an arithmetic OPER is below.
          </t>
          <sourcecode type="yang">
  amm:oper add {
    operands {
      leaf val_a {
        type amm:NUMERIC;
      }
      leaf val_b {
        type amm:NUMERIC;
      }
    }
    result {
      leaf _ {
        type amm:NUMERIC;
      }
    }
    description "Sum together the two operands.";
  }
</sourcecode>
          <t>
A more complex "variadic" OPER with parameters is below.
Also note the anonymous semantic type used to restrict the parameter.
          </t>
          <sourcecode type="yang">
  amm:oper sum {
    parameters {
      leaf count {
        type amm:UINT {
          range "1..max";
        }
        description "The number of operands to pop."
      }
    }
    operands {
      leaf-list value {
        type amm:NUMERIC;
        description
          "This is not within a container, so does not represent an AC;
          it is multiple operands.";
      }
    }
    result {
      leaf sum {
        type amm:NUMERIC;
      }
    }
    description "Sum together a sequence from the stack.";
  }
</sourcecode>
          <section>
            <name>The <tt>amm:operands</tt> Statement</name>
            <t>
This statement is used to define the set of operands that apply to the parent object.
There is no argument to this statement.
The node substatement SHALL NOT contain a default value.
            </t>
            <table>
              <name><tt>amm:operands</tt> Substatements</name>
              <thead>
                <tr>
                  <th>Substatement</th>
                  <th>Cardinality</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>leaf</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>leaf-list</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>container</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>choice</td>
                  <td>0..1</td>
                </tr>
                <tr>
                  <td>uses</td>
                  <td>0..1</td>
                </tr>
              </tbody>
            </table>
          </section>
        </section>
        <section>
          <name>The <tt>amm:sbr</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-sbr"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, the action to execute upon trigger, and rule control fields defined below.
          </t>
          <table>
            <name><tt>amm:sbr</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:action</td>
                <td>1</td>
              </tr>
              <tr>
                <td>amm:condition</td>
                <td>1</td>
              </tr>
              <tr>
                <td>amm:min-interval</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:max-count</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:init-enabled</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of an SBR with some default fields is below.
          </t>
          <sourcecode type="yang">
  amm:sbr enable_safe_mode {
    amm:action "TBD";
    amm:condition "(../EDD/sensor,../VAR/min_threshold,/ietf-amm/OPER/lessthan)";
    description "Enable safe mode below threshold.";
  }
</sourcecode>
          <section>
            <name>The <tt>amm:min-interval</tt> Statement</name>
            <t>
This statement is used to define the Minimum Interval field of <xref format="title" target="sec-obj-sbr"/> objects.
The argument to this statement is the text form of a <tt>TD</tt> value.
If not present, the default value of zero (meaning no minimum) is used.
            </t>
          </section>
          <section>
            <name>The <tt>amm:max-count</tt> Statement</name>
            <t>
This statement is used to define the Maximum Count field of <xref format="title" target="sec-obj-sbr"/> and <xref format="title" target="sec-obj-tbr"/> objects.
The argument to this statement is the text form of a <tt>UVAST</tt> value.
If not present, the default value of zero (meaning no limit) is used.
            </t>
          </section>
          <section>
            <name>The <tt>amm:init-enabled</tt> Statement</name>
            <t>
This statement is used to define the Initial Enabled state of <xref format="title" target="sec-obj-sbr"/> and <xref format="title" target="sec-obj-tbr"/> objects.
The argument to this statement is the text form of a <tt>BOOL</tt> value.
If not present, the default value of <tt>true</tt> is used.
            </t>
          </section>
        </section>
        <section>
          <name>The <tt>amm:tbr</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-tbr"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, the action to execute upon trigger, and rule control fields defined below.
          </t>
          <table>
            <name><tt>amm:tbr</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:action</td>
                <td>1</td>
              </tr>
              <tr>
                <td>amm:start</td>
                <td>1</td>
              </tr>
              <tr>
                <td>amm:period</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:max-count</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:init-enabled</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of an TBR with some default fields is below.
          </t>
          <sourcecode type="yang">
  amm:tbr tlm_rule {
    amm:action "(../CTRL/first,/adm2/CTRL/other)";
    amm:period "/TD/PT30s";
    description "Generate telemetry reports.";
  }
</sourcecode>
          <section>
            <name>The <tt>amm:start</tt> Statement</name>
            <t>
This statement is used to define the Start field of <xref format="title" target="sec-obj-tbr"/> objects.
The argument to this statement is the text form of a <xref target="typedef-time"><tt>TIME</tt></xref> value.
If not present, the default value of zero (meaning start immediately) is used.
            </t>
          </section>
        </section>
        <section>
          <name>The <tt>amm:var</tt> Statement</name>
          <t>
This statement is used to define a <xref format="title" target="sec-obj-var"/> object.
The argument to this statement is the name of the AMM object.
          </t>
          <t>
The substatements under this are the common object metadata, optional formal parameters, a single <xref target="sec-yang-nodes">node</xref> that represents the stored-and-produced value of the VAR, and an optional initializer expression.
The node substatement SHALL NOT contain a default value.
          </t>
          <table>
            <name><tt>amm:var</tt> Substatements</name>
            <thead>
              <tr>
                <th>Substatement</th>
                <th>Cardinality</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>if-feature</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:enum</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:parameters</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>status</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>reference</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>description</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>amm:initializer</td>
                <td>0..1</td>
              </tr>
              <tr>
                <th colspan="2">One data node:</th>
              </tr>
              <tr>
                <td>leaf</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>container</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>choice</td>
                <td>0..1</td>
              </tr>
              <tr>
                <td>uses</td>
                <td>0..1</td>
              </tr>
            </tbody>
          </table>
          <t>
An example of a simple-typed VAR with an initializer value is below.
          </t>
          <sourcecode type="yang">
  amm:var min_threshold {
    leaf _ {
      type amm:real32;
      unit "meters";
    }
    amm:initializer "1e4";
    description "The lower threshold to enable safe mode.";
  }
</sourcecode>
          <section>
            <name>The <tt>amm:initializer</tt> Statement</name>
            <t>
This statement is used to define an initial variable state as either an AMM value or an <xref format="title" target="typedef-expr"/>.
The argument to this statement is the text form of the ARI encoding the expression.
            </t>
            <t>
The initializer is used as part of the <xref format="title" target="sec-proc-init"/> procedure and when new VAR objects are defined in an ODM.
            </t>
          </section>
        </section>
      </section>
      <!--
        <section title="Table Template (TBLT) Encoding">
          <t>
               The TBLT JSON object is comprised of four elements: "name", "columns", 
               and "description". The description of these elements is as follows:

               <list hangIndent="8" style="hanging"><t>
                     Name
                     The identifier of the table template data item. This MUST be unique across all
                     name elements for TBLTs in the ADM.
                  </t><t>
                     Columns
                     This is a JSON array of elements, with each element representing
                     the definition of the type of information represented in each column.
                     Each column is described using the same encoding as a TNV
                     described in  <xref target="tnv_types"/>.
                  </t><t>
                     Description
                     A string description of the kind of data represented by this data item.
                  </t></list>
            </t>
          <t>
               The following is an example of a JSON encoding of an TBLT object.
           </t>
          <figure>
            <artwork>"name":"keys",                                          
"columns": [{"type":"STR","name":"ciphersuite_names"}], 
"description": "This table lists supported cipher suites."
                  </artwork>
          </figure>
        </section>
        <section title="Report Template Encoding">
          <t>
               The RPTT JSON object is comprised of four elements: "name", "parmspec", 
               "definition", and "description". The description of these elements is as follows:

               <list hangIndent="8" style="hanging"><t>
                     Name
                     The identifier of the report template. This MUST be unique across all
                     name elements for RPTTs in the ADM.
                  </t><t>
                     ParmSpec
                     This optional item describes parameters for this report. This is
                     encoded as an array where each element in the array is encoded as
                     a formal parameter in accordance with <xref target="fp_enc"/>.
                  </t><t>
                     Definition
                     This is an array of data elements that represent the ordered set of
                     information associated with the report. Each element in the array
                     is encoded as a data item shorthand in accordance with <xref target="aid_json_enc"/>.
                     
                     Report item elements MAY use reference parameters in their definition.
                     In those cases, the reference parameters in the definition list MUST
                     match report entry parameter names from the ParmSpec element in the
                     report template definition.
                  </t><t>
                     Description
                     A string description of the kind of data represented by this data item.
                  </t></list>
            </t>
          <t>
               The following is an example of a JSON encoding of an RPTT object.
           </t>
          <figure>
            <artwork>{                                                  
   "name": "default_report",                       
   "parmspec": [{                                  
      "type": "STR",                               
      "name": "endpoint_id"                        
   }],                                             
   "definition": [                                 
     {                                             
        "ns": "DTN:bp",
                             "nm": "Edd.edd_using_a_parm",    
        "ap": [{                                
           "type": "PARMNAME",                    
           "value": "endpoint_id"                  
        }]                                         
     },                                            
     {  
                             "ns": "DTN:bp",                                            
        "nm": "Edd.edd_with_default ",   
        "ap": [{                                
           "type": "INT",                          
           "value": ""}                            
        ]},                                        
     {  "ns": "DTN:bp",                                            
        "nm": "Edd.edd_with_no_parms ",  
        "ap": []                                
     }                                             
   ]                                               
   "description": "A default report."              
}
                  </artwork>
          </figure>
        </section>
      </section>
      -->
      <section anchor="sec-adm-module">
        <name>ADM Module Contents</name>
        <t>
An ADM module is identified, as defined in <xref target="sec-yang-proc-reuse"/>, by the module "namespace" having an "ari" scheme.
Within an ADM module, this profile makes restrictions in <xref target="sec-yang-proc-restrict"/> which are formalized in the following table of allowed module substatements. This table is adapted from <xref section="7.1." target="RFC7950"/>.
        </t>
        <table>
          <name>ADM <tt>module</tt> Substatements</name>
          <thead>
            <tr>
              <th>Substatement</th>
              <th>Cardinality</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>yang-version</td>
              <td>1</td>
            </tr>
            <tr>
              <td>namespace</td>
              <td>1</td>
            </tr>
            <tr>
              <td>prefix</td>
              <td>1</td>
            </tr>
            <tr>
              <td>include</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>import</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>status</td>
              <td>0..1</td>
            </tr>
            <tr>
              <td>reference</td>
              <td>0..1</td>
            </tr>
            <tr>
              <td>organization</td>
              <td>0..1</td>
            </tr>
            <tr>
              <td>description</td>
              <td>0..1</td>
            </tr>
            <tr>
              <td>revision</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>extension</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>feature</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>deviation</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:enum</td>
              <td>1</td>
            </tr>
            <tr>
              <td>typedef</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:const</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:ctrl</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:edd</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:oper</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:sbr</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:tbr</td>
              <td>0..n</td>
            </tr>
            <tr>
              <td>amm:var</td>
              <td>0..n</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="auth_consid" title="ADM Author Considerations">
      <t>
         The AMM model provides multiple ways to represent certain types of
         data. This section provides informative guidance on how to express
         application management constructs efficiently when authoring an
         ADM document.
      </t>
      <dl>
        <dt>Use Parameters for Dynamic Information:</dt>
        <dd>
               Parameters provide a powerful mechanism for expressing associative
               look-ups of EDD data. EDDs SHOULD be parameterized when the definition
               of the EDD is dependent upon run-time information. For example, if
               requesting the number of bytes through a specific endpoint, the
               construct num_bytes("endpoint_name") is simpler to understand and
               more robust to new endpoint additions than attempting to enumerate the
               number and name of potential endpoints when defining the ADM.
          </dd>
        <dt>Do Not Use Parameters for Static Information:</dt>
        <dd>
          <t>
               Parameters incur bandwidth and processing costs (such as type
               checking) and should only be used where necessary. 
               If an EDD object can be parameterized, but the set of parameters
               is known and unchanging it may be more efficient to define
               multiple non-parameterized EDD objects instead. For example, consider
               a single parameterized EDD object reporting the number of bytes 
               of data received for a specific, known set of priorities and a
               request to report on those bytes for the "low", "med", and "high"
               priorities. Below are two ways to represent these data: using
               parameters and not using parameters.
          </t>
          <figure align="center">
            <artwork align="center"> +------------------------+------------------------+
 |   Parameterized EDDs   | Non-Parameterized EDDs |
 +------------------------+------------------------+
 | num_bytes_by_pri(low)  | num_bytes_by_low_pri   |
 | num_bytes_by_pri(med)  | num_bytes_by_med_pri   |
 | num_bytes_by_pri(high) | num_bytes_by_high_pri  |
 +------------------------+------------------------+
                  </artwork>
          </figure>
          <t>
               The use of parameters in this case only incurs the
               overhead of type checking, parameter encoding/decoding, and 
               associative lookup. This situation should be avoided when 
               deciding when to parameterize AMM objects.
          </t>
        </dd>
        <dt>Use Tables for Related Data:</dt>
        <dd>
               In cases where multiple EDD or VAR values are likely to be
               evaluated together, then that information SHOULD be placed in a
               Table Template rather than defining multiple EDD and VAR objects.
               By making a Table Template, the relationships among various
               data values are preserved. Otherwise, Managers would need to
               remember to query multiple EDD and/or VAR objects together which
               is burdensome, but also results in high bandwidth and processor
               utilization.
            </dd>
      </dl>
    </section>
    <section anchor="IANA" title="IANA Considerations">
      <t>
        This document does not define or modify any existing IANA registries.
        It does rely on the ARI-defined sub-registries defined in <xref target="IANA-DTNMP"/> by <xref section="9.3" target="I-D.birrane-dtn-ari"/>.
      </t>
    </section>
    <section anchor="Security" title="Security Considerations">
      <t>
         This document does not describe any on-the-wire encoding or other
         messaging syntax. It is assumed that the exchange of AMM objects
         between Agents and Managers occurs within the context of an 
         appropriate network environment. 
      </t>
      <t>
         This AMM model may be extended to include the concept of Access
         Control Lists (ACLs) to enforce roles and responsibilities
         among Managers in the network. This access control would be
         implemented separately from network security mechanisms.
      </t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="IANA-DTNMP" target="https://www.iana.org/assignments/TBD/">
          <front>
            <title>Delay-Tolerant Networking (DTN) Management Protocol</title>
            <author>
              <organization>IANA</organization>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="IEEE.754-2019" target="https://ieeexplore.ieee.org/document/8766229" xml:base="https://bib.ietf.org/public/rfc/bibxml-misc/reference.IEEE.754-2019.xml">
          <front>
            <title>IEEE Standard for Floating-Point Arithmetic</title>
            <author>
              <organization abbrev="IEEE">Institute of Electrical and Electronics Engineers</organization>
              <address>
                <postal>
                  <country>USA</country>
                  <city>New York</city>
                </postal>
                <uri>http://www.ieee.org</uri>
              </address>
            </author>
            <date day="18" month="July" year="2019"/>
            <abstract>
              <t>This standard specifies interchange and arithmetic formats and methods for binary and decimal floating-point arithmetic in computer programming environments. This standard specifies exception conditions and their default handling. An implementation of a floating-point system conforming to this standard may be realized entirely in software, entirely in hardware, or in any combination of software and hardware. For operations specified in the normative part of this standard, numerical results and exceptions are uniquely determined by the values of the input data, sequence of operations, and destination formats, all under user control.</t>
            </abstract>
          </front>
          <seriesInfo name="IEEE" value="IEEE 754-2019"/>
          <seriesInfo name="DOI" value="10.1109/IEEESTD.2019.8766229"/>
        </reference>
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC3986" target="https://www.rfc-editor.org/info/rfc3986" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="L. Masinter" initials="L." surname="Masinter"/>
            <date month="January" year="2005"/>
            <abstract>
              <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>
        <reference anchor="RFC3339" target="https://www.rfc-editor.org/info/rfc3339" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3339.xml">
          <front>
            <title>Date and Time on the Internet: Timestamps</title>
            <author fullname="G. Klyne" initials="G." surname="Klyne"/>
            <author fullname="C. Newman" initials="C." surname="Newman"/>
            <date month="July" year="2002"/>
            <abstract>
              <t>This document defines a date and time format for use in Internet protocols that is a profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="3339"/>
          <seriesInfo name="DOI" value="10.17487/RFC3339"/>
        </reference>
        <reference anchor="RFC7950" target="https://www.rfc-editor.org/info/rfc7950" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7950.xml">
          <front>
            <title>The YANG 1.1 Data Modeling Language</title>
            <author fullname="M. Bjorklund" initials="M." role="editor" surname="Bjorklund"/>
            <date month="August" year="2016"/>
            <abstract>
              <t>YANG is a data modeling language used to model configuration data, state data, Remote Procedure Calls, and notifications for network management protocols. This document describes the syntax and semantics of version 1.1 of the YANG language. YANG version 1.1 is a maintenance release of the YANG language, addressing ambiguities and defects in the original specification. There are a small number of backward incompatibilities from YANG version 1. This document also specifies the YANG mappings to the Network Configuration Protocol (NETCONF).</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7950"/>
          <seriesInfo name="DOI" value="10.17487/RFC7950"/>
        </reference>
        <reference anchor="I-D.birrane-dtn-ari" target="https://datatracker.ietf.org/doc/html/draft-birrane-dtn-ari-01" xml:base="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.birrane-dtn-ari.xml">
          <front>
            <title>Asynchronous Resource Identifier</title>
            <author fullname="Edward J. Birrane" initials="E. J." surname="Birrane">
              <organization>The Johns Hopkins University Applied Physics Laboratory</organization>
            </author>
            <author fullname="Emery Annis" initials="E." surname="Annis">
              <organization>The Johns Hopkins University Applied Physics Laboratory</organization>
            </author>
            <author fullname="Brian Sipos" initials="B." surname="Sipos">
              <organization>The Johns Hopkins University Applied Physics Laboratory</organization>
            </author>
            <date day="13" month="March" year="2023"/>
            <abstract>
              <t>This document defines the structure, format, and features of the naming scheme for the objects defined in the Delay-Tolerant Networking (DTN) Application Data Model (ADM), in support of challenged network management solutions described in the Delay- Tolerant Networking Autonomous Management Architecture (AMA). This document defines a new Asynchronous Resource Identifier (ARI), based on the structure of a common URI, meeting the needs for a concise, typed, parameterized, and hierarchically organized set of data elements.</t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-birrane-dtn-ari-01"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="ECMA-262" target="https://262.ecma-international.org/12.0/">
          <front>
            <title>ECMA-262 12th Edition, June 2021. ECMAScript 2021 language specification</title>
            <author>
              <organization showOnFrontPage="true">Ecma International</organization>
            </author>
            <date month="June" year="2021"/>
          </front>
        </reference>
        <reference anchor="IANA-YANG" target="https://www.iana.org/assignments/yang-parameters/">
          <front>
            <title>YANG Parameters</title>
            <author>
              <organization>IANA</organization>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="RFC2578" target="https://www.rfc-editor.org/info/rfc2578" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2578.xml">
          <front>
            <title>Structure of Management Information Version 2 (SMIv2)</title>
            <author fullname="K. McCloghrie" initials="K." role="editor" surname="McCloghrie"/>
            <author fullname="D. Perkins" initials="D." role="editor" surname="Perkins"/>
            <author fullname="J. Schoenwaelder" initials="J." role="editor" surname="Schoenwaelder"/>
            <date month="April" year="1999"/>
            <abstract>
              <t>It is the purpose of this document, the Structure of Management Information Version 2 (SMIv2), to define that adapted subset, and to assign a set of associated administrative values. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="58"/>
          <seriesInfo name="RFC" value="2578"/>
          <seriesInfo name="DOI" value="10.17487/RFC2578"/>
        </reference>
        <reference anchor="RFC2580" target="https://www.rfc-editor.org/info/rfc2580" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2580.xml">
          <front>
            <title>Conformance Statements for SMIv2</title>
            <author fullname="K. McCloghrie" initials="K." role="editor" surname="McCloghrie"/>
            <author fullname="D. Perkins" initials="D." role="editor" surname="Perkins"/>
            <author fullname="J. Schoenwaelder" initials="J." role="editor" surname="Schoenwaelder"/>
            <date month="April" year="1999"/>
            <abstract>
              <t>Collections of related objects are defined in MIB modules. It may be useful to define the acceptable lower-bounds of implementation, along with the actual level of implementation achieved. It is the purpose of this document to define the notation used for these purposes. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="58"/>
          <seriesInfo name="RFC" value="2580"/>
          <seriesInfo name="DOI" value="10.17487/RFC2580"/>
        </reference>
        <reference anchor="RFC6021" target="https://www.rfc-editor.org/info/rfc6021" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6021.xml">
          <front>
            <title>Common YANG Data Types</title>
            <author fullname="J. Schoenwaelder" initials="J." role="editor" surname="Schoenwaelder"/>
            <date month="October" year="2010"/>
            <abstract>
              <t>This document introduces a collection of common data types to be used with the YANG data modeling language. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6021"/>
          <seriesInfo name="DOI" value="10.17487/RFC6021"/>
        </reference>
        <reference anchor="RFC6991" target="https://www.rfc-editor.org/info/rfc6991" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6991.xml">
          <front>
            <title>Common YANG Data Types</title>
            <author fullname="J. Schoenwaelder" initials="J." role="editor" surname="Schoenwaelder"/>
            <date month="July" year="2013"/>
            <abstract>
              <t>This document introduces a collection of common data types to be used with the YANG data modeling language. This document obsoletes RFC 6021.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6991"/>
          <seriesInfo name="DOI" value="10.17487/RFC6991"/>
        </reference>
        <reference anchor="RFC8610" target="https://www.rfc-editor.org/info/rfc8610" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8610.xml">
          <front>
            <title>Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures</title>
            <author fullname="H. Birkholz" initials="H." surname="Birkholz"/>
            <author fullname="C. Vigano" initials="C." surname="Vigano"/>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <date month="June" year="2019"/>
            <abstract>
              <t>This document proposes a notational convention to express Concise Binary Object Representation (CBOR) data structures (RFC 7049). Its main goal is to provide an easy and unambiguous way to express structures for protocol messages and data formats that use CBOR or JSON.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8610"/>
          <seriesInfo name="DOI" value="10.17487/RFC8610"/>
        </reference>
        <reference anchor="I-D.ietf-dtn-dtnma" target="https://datatracker.ietf.org/doc/html/draft-ietf-dtn-dtnma-06" xml:base="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-dtn-dtnma.xml">
          <front>
            <title>DTN Management Architecture</title>
            <author fullname="Edward J. Birrane" initials="E. J." surname="Birrane">
              <organization>Johns Hopkins Applied Physics Laboratory</organization>
            </author>
            <author fullname="Sarah Heiner" initials="S." surname="Heiner">
              <organization>Johns Hopkins Applied Physics Laboratory</organization>
            </author>
            <author fullname="Emery Annis" initials="E." surname="Annis">
              <organization>Johns Hopkins Applied Physics Laboratory</organization>
            </author>
            <date day="9" month="July" year="2023"/>
            <abstract>
              <t>The Delay-Tolerant Networking (DTN) architecture describes a type of challenged network in which communications may be significantly affected by long signal propagation delays, frequent link disruptions, or both. The unique characteristics of this environment require a unique approach to network management that supports asynchronous transport, autonomous local control, and a small footprint (in both resources and dependencies) so as to deploy on constrained devices. This document describes a DTN management architecture (DTNMA) suitable for managing devices in any challenged environment but, in particular, those communicating using the DTN Bundle Protocol (BP). Operating over BP requires an architecture that neither presumes synchronized transport behavior nor relies on query-response mechanisms. Implementations compliant with this DTNMA should expect to successfully operate in extremely challenging conditions, such as over uni-directional links and other places where BP is the preferred transport.</t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-dtn-dtnma-06"/>
        </reference>
      </references>
    </references>
    <section anchor="sec-yang-ammadm">
      <name>YANG Module for AMM Definitions</name>
      <t>
The following is the YANG module implementing the entities described in <xref target="sec-ammadm"/>:
      </t>
      <ul>
        <li>Extensions to support <xref format="title" target="sec-adm-metadata"/> within a YANG module.</li>
        <li>Extensions to support <xref format="title" target="sec-obj"/> within a YANG module.</li>
        <li>The literal and object-reference types of <xref target="sec-ari">ARI</xref> usable as YANG leaf types.</li>
      </ul>
      <sourcecode markers="true" name="ietf-amm.yang" type="yang" originalSrc="modules/ietf-amm.yang">module ietf-amm {
  namespace "ari:/ietf-amm";
  prefix "amm";
  amm:enum "0";

  organization
    "IETF Delay Tolerant Networking Working Group";
  contact
    "WG Web: &lt;http://tools.ietf.org/wg/dtn/&gt;
    WG List: &lt;mailto:dtn@ietf.org&gt;

    WG Chairs: Brian Haberman
               &lt;mailto:brian@innovationslab.net&gt;
               Marc Blanchet
               &lt;mailto:Marc.Blanchet@viagenie.ca&gt;

    Editor: Brian Sipos
            &lt;mailto:brian.sipos@jhuapl.edu&gt;";

  description
    "This module implements the DTN Management Architecture (DTNMA)
    Application Data Model (ADM) base module within YANG";
  reference
    "draft-birrane-dtn-adm";

  revision "2023-06-08" {
    description "Updated for latest AMM contents.";
    reference "draft-birrane-dtn-adm";
  }
  revision "2016-04-01" {
    description "Updated to fix typos.";
    reference "draft-bsipos-dtn-amp-yang";
  }
  revision "2016-03-14" {
    description "Initial draft release.";
    reference "draft-bsipos-dtn-amp-yang";
  }

  /****
   * This section contains extension for AMM object definitions
   ****/

  // This group of extensions are for common behavior for AMM objects
  extension enum {
    argument "value";
    description
      "An enumeration identifies an object within a namespace.
      The argument to this statement is the integer value.";
  }
  extension parameters {
    description
      "A container for the formal parameters for an object.
      Each substatement is a parameter as either a leaf (ARI)
      or container (AC).
      Order of parameters is signifigant within this statement.";
  }

  // This group are AMM object keywords and their parameters
  extension const {
    argument "name";
    description
      "Definition of a CONST within an ADM.
      The argument to this statement is the object name.
      A 'value' substatement must be present.";
  }
  extension value {
    argument "ari";
    description
      "The literal value of a CONST object.
      The argument is the text form of the ARI";
  }

  extension ctrl {
    argument "name";
    description
      "Definition of a CTRL within an ADM.
      The argument to this statement is the object name.";
  }
  extension result {
    description
      "An result value reported as a response to a control.
      The substatement is the result value as either a leaf (ARI)
      or container (AC).
      Each CTRL can have a single optional result.";
  }

  extension edd {
    argument "name";
    description
      "Definition of an EDD within an ADM.
      The argument to this statement is the object name.";
  }

  extension oper {
    argument "name";
    description
      "Definition of an OPER within an ADM.
      The argument to this statement is the object name.";
  }
  extension operands {
    description
      "An individual operand taken from the expression stack
      during evaluation of the OPER.
      Each substatement is an operand as a leaf (ARI).
      Order of operands is signifigant within an object definition.";
  }

  extension var {
    argument "name";
    description
      "Definition of a VAR within an ADM.
      The argument to this statement is the object name.";
  }
  extension init {
    argument "expr";
    description "An EXPR value used to initialize a VAR.";
  }


  /****
   * This section contains ARI (literal and object-reference) value types.
   ****/

  extension int-labels {
    description
      "Type narrowing for an INTEGER to label enum values or bit positions.";
  }
  extension cddl {
    argument "text";
    description
      "Type narrowing for a CBOR item in the form of CDDL syntax.
      The argument to this statement is the actual CDDL text.";
  }

  // Simple literal types as YANG typedefs
  typedef NULL {
    type enumeration {
      enum null {
        description "The only allowed value.";
      }
    }
    description
      "A single-valued type to represent a null value.";
  }
  typedef BOOL {
    type boolean;
    description
      "The same semantics as the YANG 'boolean' type.";
  }
  typedef BYTE {
    type uint8;
    description
      "The same semantics as the YANG 8-bit unsigned type.";
  }
  typedef UINT {
    type uint32;
    description
      "The same semantics as the YANG 32-bit unsigned type.
      Can contain an 'int-labels' substatement for documentation.";
  }
  typedef INT {
    type int32;
    description
      "The same semantics as the YANG 32-bit signed type.
      Can contain an 'int-labels' substatement for documentation.";
  }
  typedef UVAST {
    type uint64;
    description
      "The same semantics as the YANG 64-bit unsigned type.
      Can contain an 'int-labels' substatement for documentation.";
  }
  typedef VAST {
    type int64;
    description
      "The same semantics as the YANG 64-bit signed type.
      Can contain an 'int-labels' substatement for documentation.";
  }
  typedef REAL32 {
    type decimal64 {
      fraction-digits 10;
    }
    description
      "An IEEE-754 float32 value with a text representation in YANG.
      The ARI representation is different than the YANG type used here.
      Allows range restriction.";
  }
  typedef REAL64 {
    type decimal64 {
      fraction-digits 10;
    }
    description
      "An IEEE-754 float64 value with a text representation in YANG.
      The ARI representation is different than the YANG type used here.
      Allows range restriction.";
  }
  typedef TEXTSTR {
    type string;
    description
      "The same semantics as the YANG 'string' type.
      Allows length and pattern restriction.";
  }
  typedef BYTESTR {
    type binary;
    description
      "The same semantics as the YANG 'binary' type.
      Allows length restriction.";
  }
  typedef TP {
    type string;
    description
      "An absolute instant in time.
      The ARI representation is different than the YANG type used here.
      This is represented as either (narrowed RFC 3339) text or
      (fractional) seconds from the DTN epoch.";
  }
  typedef TD {
    type string;
    description
      "A relative time as a difference between two time instants.
      The ARI representation is different than the YANG type used here.
      This is represented as either (narrowed RFC 3339) text or
      (fractional) seconds.";
  }
  typedef LITTYPE {
    type string;
    description
      "An enumeration from IANA table of literal types.";
  }
  typedef LABEL {
    type string {
      pattern "[a-zA-Z_][a-zA-Z0-9_\\-\\.]*";
    }
    description
      "An identifier label which fits the YANG 'identifier' pattern.";
  }
  typedef CBOR {
    type BYTESTR;
    description
      "A bytestr which contains a single well-formed CBOR item.
      Can contain a 'cddl' substatement for documentation.";
  }

  // Complex literals
  typedef AC {
    type string;
    description
      "When present within an ADM this uses the text encoding of an ARI Collection (AC).";
  }
  typedef AM {
    type string;
    description
      "When present within an ADM this uses the text encoding of an ARI Map (AM).";
  }

  // Object references
  typedef OBJ-REF {
    type string;
    description
      "A text representation of an ARI containing an object reference.";
  }
  typedef TYPEDEF-REF {
    type OBJ-REF;
    description "A reference to a TYPEDEF object.";
  }
  typedef CONST-REF {
    type OBJ-REF;
    description "A reference to a CONST object.";
  }
  typedef CTRL-REF {
    type OBJ-REF;
    description "A reference to a CTRL object.";
  }
  typedef EDD-REF {
    type OBJ-REF;
    description "A reference to an EDD object.";
  }
  typedef OPER-REF {
    type OBJ-REF;
    description "A reference to a OPER object.";
  }
  typedef SBR-REF {
    type OBJ-REF;
    description "A reference to an SBR object.";
  }
  typedef TBR-REF {
    type OBJ-REF;
    description "A reference to a TBR object.";
  }
  typedef VAR-REF {
    type OBJ-REF;
    description "A reference to a VAR object.";
  }

  // Named type unions for literals
  typedef TYPE-REF {
    type union {
      type LITTYPE;
      type TYPEDEF-REF;
    }
    description
      "Reference to either a literal type or a typedef.";
  }
  typedef INTEGER {
    type union {
      type BYTE;
      type UINT;
      type INT;
      type UVAST;
      type VAST;
    }
    description
      "Any type which represents a discrete integer.";
  }
  typedef FLOAT {
    type union {
      type REAL32;
      type REAL64;
    }
    description
      "Any type which represents a floating point number.";
  }
  typedef NUMERIC {
    type union {
      type INTEGER;
      type FLOAT;
    }
    description
      "Any type which can be used with numeric expressions.";
  }
  typedef TIME {
    type union {
      type TP;
      type TD;
    }
    description
      "Any type which can be used with time expressions.";
  }
  typedef SIMPLE {
    type union {
      type NULL;
      type BOOL;
      type NUMERIC;
      type TEXTSTR;
      type BYTESTR;
      type TIME;
      type LABEL;
      type CBOR;
    }
    description
      "Any type which contains a single value usable within an expression.";
  }
  typedef COMPLEX {
    type union {
      type AC;
      type AM;
    }
    description
      "A literal type which is not SIMPLE.";
  }
  typedef LITERAL {
    type union {
      type TYPE-REF; //FIXME: is typeref a literal or something else?
      type SIMPLE;
      type COMPLEX;
    }
    description
      "Any type which is represented as a literal ARI.";
  }

  typedef ANY {
    type union {
      type LITERAL;
      type OBJ-REF;
    }
    description
      "Any type representable by an ARI.";
  }
  typedef VALUE-REF {
    type union {
      type CONST-REF;
      type EDD-REF;
      type VAR-REF;
    }
    description
      "A reference to an object which can produce a value.";
  }

  // operational semantic types
  typedef counter32 {
    type UINT;
    description
      "A 32-bit counter with an arbitrary initial value that only increments.
      When the value reaches the upper range it wraps around to zero.
      At least two samples of this value need to be compared over time.";
  }
  typedef counter64 {
    type UVAST;
    description
      "A 64-bit counter with an arbitrary initial value that only increments.
      When the value reaches the upper range it wraps around to zero.
      At least two samples of this value need to be compared over time.";
  }
  typedef gauge32 {
    type INT;
    description
      "A 32-bit value sampling some quantized measurement.
      The value can increase or decrease arbitrarily over time.";
  }
  typedef gauge64 {
    type VAST;
    description
      "A 64-bit value sampling some quantized measurement.
      The value can increase or decrease arbitrarily over time.";
  }
  typedef timestamp {
    type TP;
    description
      "A time point representing the system clock at which a specific
      occurrence happened.
      The specific occurrence must be defined in the description
      of any node defined using this type.";
  }

  // Restrictions on AC item types for specific purposes
  typedef EXPR-item {
    type union {
      type SIMPLE;
      type VALUE-REF;
      type TYPEDEF-REF;
      type OPER-REF;
    }
    description
      "Each item of an EXPR list.
      The value-object must be typed to contain a SIMPLE.";
  }
  grouping EXPR {
    leaf-list _ {
      type EXPR-item;
      description "All items are the same type.";
    }
    description "The contents of an EXPR container.";
  }
  typedef EXEC-REF {
    type union {
      type VALUE-REF;
      type CTRL-REF;
    }
    description
      "A reference to an object which can be executed.
      The value-object must be typed to contain a MAC.";
  }
  grouping MAC {
    leaf-list _ {
      type EXEC-REF;
      description "All items are the same type.";
    }
    description "The contents of a MAC container.";
  }

  grouping RPTT-item {
    choice item {
      case value-ref {
        leaf ref {
          type VALUE-REF;
          description "An object to produce a report value.";
        }
      }
      case expr {
        container expr {
          uses EXPR;
          description "An expression to evaluate into a report value.";
        }
      }
      description
        "Each item references a value-producing object or contains an
        expression to be evaluated.";
    }
    description
      "Each item of a RPTT.";
  }
  grouping RPTT {
    container _ {
      uses RPTT-item;
      description "The sequence of items in the template.";
    }
    description
      "The contents of a report template, encoded as the sequence of items.";
  }
  grouping RPT-items {
    leaf-list item {
      type ANY;
      description "The sequence of items in the report.";
    }
    description
      "The contents of a report, encoded as the sequence of values reported.
      The semantics of each item are contained in the associated RPTT.";
  }
  grouping TBL {
    leaf col-count {
      type UVAST;
      description "The number of columns in the table.";
    }
    leaf-list tbl-item {
      type ANY;
      description
        "All table values listed in row-major order.";
    }
    description
      "The flattened contents of a table.
      The semantics of each column are contained in the associated TBLT.";
  }
  grouping RPT {
    leaf source {
      type OBJ-REF;
      description "Reference to the reported object.";
    }
    leaf generated-at {
      type timestamp;
      description "The generation timestamp.";
    }
    choice entries {
      case value-ref {
        leaf value {
          type ANY;
        }
      }
      case rptt {
        uses RPT-items;
      }
      case tblt {
        uses TBL;
      }
      case ctrl-ref {
        leaf result {
          type ANY;
        }
      }
      description
        "Each report content depends on the reported object.";
    }
    description "The contents of an RPT container.";
  }
}
</sourcecode>
    </section>
    <section anchor="sec-yang-agentadm">
      <name>YANG Module for DTNMA Agents</name>
      <t>
The following is the YANG module implementing the entities described in <xref target="sec-agentadm"/>:
      </t>
      <ul>
        <li>Introspective access to the ADMs supported by the Agent.</li>
        <li>Introspective access to the VARs in ODMs.</li>
        <li>A feature and introspective access to rules in ODMs.</li>
        <li>A report template used to announce presence of an Agent.</li>
        <li>Base helper controls and arithmetic operators</li>
      </ul>
      <sourcecode markers="true" name="ietf-dtnma-agent.yang" type="yang" originalSrc="modules/ietf-dtnma-agent.yang">module ietf-dtnma-agent {
  namespace "ari:/ietf-dtnma-agent";
  prefix "da";

 import "ietf-amm" {
    prefix amm;
  }

  organization
    "IETF Delay Tolerant Networking Working Group";
  contact
    "WG Web: &lt;http://tools.ietf.org/wg/dtn/&gt;
    WG List: &lt;mailto:dtn@ietf.org&gt;

    WG Chairs: Brian Haberman
               &lt;mailto:brian@innovationslab.net&gt;
               Marc Blanchet
               &lt;mailto:Marc.Blanchet@viagenie.ca&gt;

    Editor: Brian Sipos
            &lt;mailto:brian.sipos@jhuapl.edu&gt;";

  description
    "This module implements the DTN Management Architecture (DTNMA)
    Agent core functionality.";
  reference
    "draft-birrane-dtn-adm";

  revision "2023-06-08" {
    description "Updated for latest AMM contents.";
    reference "draft-birrane-dtn-adm";
  }
  amm:enum "0";

  feature rules {
    description
      "Conforming to this feature enables time-based and
      state-based autonomy rules.";
  }

  amm:edd amp_version {
    leaf _ {
      type amm:TEXTSTR;
    }
    description "The version of AMP which this agent supports.";
  }
  amm:edd capability {
    list columns {
      key adm_name;

      leaf adm_name {
        type amm:LABEL;
        description "The module name of the ADM";
      }
      leaf revision {
        type amm:TEXTSTR;
        description "The specific revision the agent supports.";
      }
      container features {
        leaf-list _ {
          type amm:LABEL;
        }
        description
          "The features of the ADM which the agent supports.";
      }
    }
    description
      "A table to indicate the ADM capability of the sending agent.";
  }
  amm:const hello {
    uses amm:RPTT;
    amm:value "(../EDD/amp_version,../EDD/capability)";
    description
      "A report template to indicate the presence of an agent
      on a network.";
  }

  // MAC helper controls
  amm:ctrl if_then_else {
    amm:parameters {
      container condition {
        uses amm:EXPR;
        description "The condition to evaluate.";
      }
      leaf on_truthy {
        type amm:EXEC-REF;
        description "The object to execute when the condition is truthy.";
      }
      leaf on_falsy {
        type union {
          type amm:NULL;
          type amm:EXEC-REF;
        }
        default "null";
        description "An optional execution when the condition is falsey.";
      }
    }
    description
      "Evaluate an expression and follow one of two branches of
      further evaluation.";
  }
  amm:ctrl catch {
    amm:parameters {
      leaf try {
        type amm:EXEC-REF;
        description "The object to execute.";
      }
      leaf on_failure {
        type union {
          type amm:NULL;
          type amm:EXEC-REF;
        }
        default "null";
        description "An optional execution after failure.";
      }
    }
    description
      "Attempt to execute an object, and if there is some failure catch it
      and execute an alternative object.";
  }

  amm:ctrl inspect {
    amm:parameters {
      leaf ref {
        type amm:VALUE-REF;
        description "An object to produce a value from.";
      }
    }
    amm:result {
      leaf val {
        type amm:ANY;
        description "The produced value.";
      }
    }
    description
      "Produce a result value to inspect the agent state.
      This does not perform any EXPR evaluation or RPTT handling.";
  }

  amm:ctrl report_on {
    amm:parameters {
      uses amm:RPTT-item;
    }
    description
      "Generate a report on an object without needing to define a RPTT.
      The parameter is a single item that would be in a RPTT.
      If used for more than one-shot diagnostics, defining a RPTT
      (e.g. in a VAR) is more efficient because the RPTT item would not
      be present in the report.";
  }

  grouping obj-list-params {
    leaf include_adm {
      type amm:BOOL;
      default "false";
      description "If true, listings will include objects from ADMs";
    }
    description "Common parameters for object listing";
  }

  amm:edd typedef_list {
    amm:parameters {
      uses obj-list-params;
    }
    list _ {
      key obj;
      leaf obj {
        type amm:TYPEDEF-REF;
      }
    }
    description
      "A table of TYPEDEF within the agent.";
  }

  // Objects related to VAR handling
  amm:edd var_list {
    amm:parameters {
      uses obj-list-params;
    }
    list _ {
      key obj;
      leaf obj {
        type amm:VAR-REF;
      }
      leaf type {
        type amm:TYPE-REF;
      }
    }
    description
      "A table of VAR within the agent.";
  }
  amm:ctrl var_present {
    amm:parameters {
      leaf obj {
        type amm:VAR-REF;
        description
          "A reference to a VAR within an ODM only.";
      }
      leaf type {
        type amm:TYPE-REF;
        description
          "The type for the VAR object.";
      }
      choice init {
        case without {
          leaf _ {
            type amm:NULL;
          }
        }
        case with {
          container expr {
            uses amm:EXPR;
          }
        }
        default "null";
        description "An optional initializer expression.";
      }
    }
    description
      "Ensure a specific VAR is present.";
  }
  amm:ctrl var_absent {
    amm:parameters {
      leaf obj {
        type amm:VAR-REF;
        description
          "A reference to a VAR within an ODM only.";
      }
    }
    description
      "Ensure a specific VAR is not present.";
  }

  // Objects related to SBR handling
  grouping sbr-fields {
    container action {
      uses amm:MAC;
      description
        "The execution when this rule triggers.";
    }
    leaf start_time {
      type amm:TIME;
    }
    container condition {
      uses amm:EXPR;
    }
    leaf min_interval {
      type amm:TD;
    }
    leaf max_count {
      type amm:UVAST;
    }
  }
  amm:edd sbr_list {
    if-feature rules;
    list _ {
      key obj;

      leaf obj {
        type amm:SBR-REF;
      }
      uses sbr-fields;
    }
  }

  amm:edd tbr_list {
    if-feature rules;
    list _ {
      key obj;

      leaf obj {
        type amm:OBJ-REF;
      }
      container action {
        uses amm:MAC;
        description
          "The execution when this rule triggers.";
      }
      leaf start_time {
        type amm:TIME;
      }
      leaf period {
        type amm:TD;
      }
      leaf max_count {
        type amm:UVAST;
      }
    }
  }

  grouping numeric-unary {
    leaf val {
      type amm:NUMERIC;
      description "The single value.";
    }
  }
  grouping numeric-binary {
    leaf left {
      type amm:NUMERIC;
      description "The left-side operand.";
    }
    leaf right {
      type amm:NUMERIC;
      description "The left-side operand.";
    }
  }
  amm:oper negate {
    amm:operands {
      uses numeric-unary;
    }
    amm:result {
      uses numeric-unary;
    }
    description
      "Negate a value.
      This is equivalent to multiplying by -1 but a shorter
      expression.";
  }
  amm:oper add {
    amm:operands {
      uses numeric-binary;
    }
    amm:result {
      uses numeric-unary;
    }
    description
      "Add two numeric values.
      The operands are cast to the least compatible numeric type
      before the arithmetic.";
  }
  // amm:oper sub
  // amm:oper multiply
  // amm:oper divide
  // amm:oper add

  // amm:oper bit_not
  // amm:oper bit_and
  // amm:oper bit_or
  // amm:oper bit_xor

  // amm:oper bool_not
  // amm:oper bool_and
  // amm:oper bool_or
  // amm:oper bool_xor

  // amm:oper compare_eq
  // amm:oper compare_ne
  // amm:oper compare_gt
  // amm:oper compare_ge
  amm:oper compare_lt {
    amm:operands {
      uses numeric-binary;
    }
    amm:result {
      uses numeric-unary;
    }
    description
      "Compare two operands by value.
      The result is true if the left value is less than the right.
      The operands are cast to the least compatible numeric type
      before the comparison.";
  }
  amm:oper compare_le {
    amm:operands {
      uses numeric-binary;
    }
    amm:result {
      uses numeric-unary;
    }
    description
      "Compare two operands by value.
      The result is true if the left value is less than or
      equal to the right.
      The operands are cast to the least compatible numeric type
      before the comparison.";
  }
}
</sourcecode>
    </section>
    <section anchor="sec-examples">
      <name>Examples</name>
      <t>
For the sake of adhering to the proper syntax for ARIs, all of the example reports are timestamped at 2023-01-01T00:00:00Z.
      </t>
      <sourcecode type="uri">
ari:/dtnma-agent/CTRL/report_on(/example-adm/EDD/intvalue)
</sourcecode>
      <t>
Executing that results in a report containing the following:
      </t>
      <sourcecode type="uri">
(
  /example-adm/EDD/intvalue,
  /TP/20230101T000000Z,
  /INT/10
)
</sourcecode>
      <t>
If the produced value has a semantic type which is ambiguous within the EDD type, the report would instead contain:
      </t>
      <sourcecode type="uri">
(
  /example-adm/EDD/intvalue,
  /TP/20230101T000000Z,
  /example-adm/TYPEDEF/mycounter(/INT/10)
)
</sourcecode>
      <t>
For a similar CONST that contains an RPTT value, the report would contain:
      </t>
      <sourcecode type="uri">
(
  ../EDD/intvalue,
  ../EDD/boolvalue
)
</sourcecode>
      <sourcecode type="uri">
(
  /example-adm/CONST/report1,
  /TP/20230101T000000Z,
  /INT/10,
  /true
)
</sourcecode>
    </section>
  </back>
</rfc>
