<?xml version="1.0" encoding="UTF-8"?>
<?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-ietf-dtn-amm-04" ipr="trust200902" submissionType="IETF" symRefs="true" tocInclude="true" version="3" xml:lang="en">
  <front>
    <title abbrev="DTNMA AMM">DTNMA Application Management Model (AMM) and Data Models</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-dtn-amm-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>United States of America</country>
        </postal>
        <phone>+1 443 778 7423</phone>
        <email>Edward.Birrane@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>
    <author fullname="Justin Ethier" initials="J." surname="Ethier">
      <organization abbrev="JHU/APL">The Johns Hopkins University Applied Physics Laboratory</organization>
      <address>
        <email>Justin.Ethier@jhuapl.edu</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 model that captures the information necessary to asynchronously manage applications within the Delay-Tolerant Networking Management Architecture (DTNMA).
This model provides a set of common managed object types, data types and structures, and a template for information needed within each application data model.
The built-in definitions are made to be extensible by applications without needing to modify core Agent or Manager behavior.
      </t>
    </abstract>
  </front>
  <middle>
    <section>
      <name>Introduction</name>
      <t>
The Delay-Tolerant Networking Management Architecture (DTNMA) <xref target="RFC9675"/> 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 types and literal-value types used in the DTNMA in a concrete way.
          </li>
          <li>
An object model, instantiating the AMM meta-model, which is used by static Application Data Models (ADMs) and dynamic Operational Data Models (ODMs) within an Agent.
          </li>
        </ol>
        <t>
This document does not define any specific encodings of AMM values or of ADM or ODM contents.
In order to communicate data models and values between DTNMA Agents and Managers in a network, they must be encoded for transmission.
Specific encoding details are outside of the scope of this document, but they are discussed in <xref target="sec-ari"/> and <xref target="sec-adm"/>.
        </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 "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in <xref target="RFC2119"/>.
        </t>
        <t>
The terms "Actor", "Agent", "Manager", "Rule", "State-Based Rule", and "Time-Based Rule" are used without modification from the definitions provided in <xref target="RFC9675"/>.
        </t>
        <t>
Additional terms defined in this document are the following.
        </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, namespace, or literal value defined in <xref target="I-D.ietf-dtn-ari"/>.
The text form of an ARI is 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 specific syntax used to express the contents of that ADM, as defined in another document.
          </dd>
          <dt>Operational Data Model (ODM):</dt>
          <dd>
The set of dynamically-defined objects created and controlled by Managers in the network.
There is currently no specific syntax used to express the entire contents of an ODM outside of data from introspection reports generated by an Agent.
          </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.
A namespace is identified by its organization ID, model ID, and (for ADMs) a specific model revision.
A namespace reference is also a form of <xref target="sec-value-nsref">AMM value</xref> as realized in ARI syntax.
          </dd>
          <dt>Identity Object (IDENT):</dt>
          <dd>
An object type used as an extensible form of enumerated value as defined in <xref target="sec-obj-ident"/>.
These objects have no specific state within an Agent and are characterized entirely by their identity.
          </dd>
          <dt>Built-In Type:</dt>
          <dd>
The set of value types which form the baseline of the AMM typing system as defined in <xref target="sec-type-builtin"/>.
These include sized integer types, text and byte strings in <xref target="sec-type-simple"/>, more complex nested containers in <xref target="sec-type-container"/> and object references in <xref target="sec-type-objref"/>.
          </dd>
          <dt>Semantic Type:</dt>
          <dd>
This is a means of combining, constraining, or annotating existing built-in types or TYPEDEF types as defined in <xref target="sec-type-semantic"/>.
A typical expected use of semantic type is to annotate the use of an integer counter type with an engineering unit.
A semantic type on its own does not have an intrinsic identifier, but can be used in a TYPEDEF to give it identifiers.
          </dd>
          <dt>Type Definition (TYPEDEF):</dt>
          <dd>
An object type used to associate a name and enumeration, in a specific object namespace, with a semantic type as defined in <xref target="sec-obj-typedef"/>.
These objects have no specific state within an Agent and are characterized entirely by their identity and semantic type.
          </dd>
          <dt>Value Production:</dt>
          <dd>
An activity performed within an Agent as defined in <xref target="sec-proc-prod"/>.
The target of a production can be an <xref target="sec-value-objref">object reference</xref> to any <xref target="sec-conops-values">value-producing object</xref>.
A convenience semantic type is defined for valid production targets in <xref target="typedef-valueobj"/>.
          </dd>
          <dt>Constant (CONST):</dt>
          <dd>
An object type used for <xref format="title" target="sec-proc-prod"/> and defined in <xref target="sec-obj-const"/>.
These objects have state maintained by an Agent.
Constant objects can be used to store macro values, report template values, threshold values for rule expressions, <em>etc.</em>
          </dd>
          <dt>Variable (VAR):</dt>
          <dd>
An object type used for <xref format="title" target="sec-proc-prod"/> and defined in <xref target="sec-obj-var"/>.
These objects have state maintained by an Agent.
          </dd>
          <dt>Externally Defined Data (EDD):</dt>
          <dd>
An object type used for <xref format="title" target="sec-proc-prod"/> and defined in <xref target="sec-obj-edd"/>.
These objects have state obtained by an Agent from an Application.
          </dd>
          <dt>Execution:</dt>
          <dd>
An activity performed within an Agent as defined in <xref target="sec-proc-exec"/> as directed by a Manager or as the action of a triggered Rule.
A Manager can trigger execution by sending an <xref format="title" target="sec-type-execset"/> values to an Agent through some <xref format="none" target="sec-conops-msg">transport binding</xref>.
A convenience semantic type is defined for valid execution targets in <xref target="typedef-exec-tgt"/>.
          </dd>
          <dt>Control (CTRL):</dt>
          <dd>
An object type used for <xref format="title" target="sec-proc-exec"/> and defined in <xref target="sec-obj-ctrl"/>.
These objects have execution behavior triggered by an Agent into an Application.
A set of general purpose built-in controls is defined in the <xref target="sec-agentadm">Agent ADM</xref>.
          </dd>
          <dt>Macro (MAC):</dt>
          <dd>
A semantic type for values used during <xref format="title" target="sec-proc-exec"/> as defined in <xref target="typedef-mac"/>.
Macros are used to control ordering of execution items and limit execution failures (an item of a macro which fails to execute will skip any following items).
Macros are expected to be stored in CONST objects but can be present in any <xref target="sec-conops-values">value-producing object</xref>.
          </dd>
          <dt>Agent State:</dt>
          <dd>
            <t>
The Agent state is the aggregation of all of the states of its <xref target="sec-obj-ctrl"/> and <xref target="sec-obj-var"/> objects (within both ADMs and ODMs) and the hidden states which would be produced by <xref target="sec-obj-edd"/> objects.
These states can be used with <xref format="title" target="sec-proc-eval"/> to trigger <xref target="sec-obj-sbr"/> actions.
            </t>
            <t>
Ephemeral values (such as EXECSET values waiting to be executed or RPTSET values waiting to be sent) are not considered part of this definition of the agent state.
However, such ephemeral information can be reflected by EDDs in the <xref target="sec-agentadm">Agent ADM</xref> that count or list Agent queue contents.
            </t>
          </dd>
          <dt>Agent Timeline:</dt>
          <dd>
An Agent timeline is used for internal bookkeeping of future events.
One purpose of timeline events is to trigger actions for enabled <xref target="sec-obj-tbr"/> objects.
Another purpose is to support built-in "waiting" controls in the <xref target="sec-agentadm">Agent ADM</xref>.
          </dd>
          <dt>Evaluation:</dt>
          <dd>
An activity performed within an Agent as defined in <xref target="sec-proc-eval"/>.
The target of an evaluation can be the predicate of a <xref format="title" target="sec-obj-sbr"/> object used for autonomy, or an item within a <xref format="title" target="typedef-rptt"/> value during <xref format="title" target="sec-proc-rpt"/>.
A convenience semantic type is defined for valid evaluation targets in <xref target="typedef-eval-tgt"/>.
          </dd>
          <dt>Operator (OPER):</dt>
          <dd>
An object type used for <xref format="title" target="sec-proc-eval"/> and defined in <xref target="sec-obj-ctrl"/>.
These objects have evaluation behavior triggered by an Agent into an Application.
A set of general purpose built-in operators is defined in the <xref target="sec-agentadm">Agent ADM</xref>.
          </dd>
          <dt>Expression (EXPR):</dt>
          <dd>
A semantic type for values used during <xref format="title" target="sec-proc-eval"/> as defined in <xref target="typedef-expr"/>.
Expressions are used to TBD.
Expressions are expected to be stored as TBR predicates and in CONST objects but can be present in any <xref target="sec-conops-values">value-producing object</xref>.
          </dd>
          <dt>Reporting:</dt>
          <dd>
An activity performed within an Agent as defined in <xref target="sec-proc-rpt"/>.
The target of reporting is always a <xref format="title" target="typedef-rptt"/> containing items to evaluate into one report of a <xref format="title" target="sec-type-rptset"/>.
The trigger for reporting is either a built-in control in the <xref target="sec-agentadm">Agent ADM</xref> or the completion of execution of an <xref format="title" target="sec-type-execset"/> target when a nonce value is included.
          </dd>
          <dt>Report Template (RPTT):</dt>
          <dd>
A semantic type for values used during <xref format="title" target="sec-proc-rpt"/> as defined in <xref target="typedef-rptt"/>.
Report templates are lists of items used as a schema for report contents.
Report templates are expected to be stored in CONST objects but can be present in any <xref target="sec-conops-values">value-producing object</xref>.
          </dd>
          <dt>Report:</dt>
          <dd>
A report is the output of the <xref format="title" target="sec-proc-rpt"/> activity and kept within <xref format="title" target="sec-type-rptset"/> values.
An Agent sends its reports to a specific Manager through some <xref format="none" target="sec-conops-msg">transport binding</xref>.
          </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="RFC9675"/>, 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>
      <figure align="center" anchor="fig-models">
        <name>Data Model Relationships</name>
        <artwork align="center" xml:space="preserve">
     +-----------------+
     |       AMM       |
     |  (object types) |
     +-----------------+
              ^
 instantiates |
              |
     +--------+--------+
     |    Namespace    |
     |   (instances)   |
     +--------^--------+
              | subclass
      +-------+-------+
      |               |
+-----+-----+   +-----+-----+
|    ADM    |   |    ODM    |
+-----------+   +-----------+
           </artwork>
      </figure>
      <t>
The AMM defines a strict separation between long-lived object instances and ephemeral value instances.
While an Agent hosts the 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-value-object"/>.
      </t>
      <figure align="center" anchor="fig-value-object">
        <name>AMM Value and Object Relationships</name>
        <artwork align="center" xml:space="preserve">
 +-------------+                                  
 |  AMM Value  |                                  
 |  (in ARI)   |                                  
 +------^------+                                  
subclass|                                         
        |  +-----------+                          
        +--|  Literal  |                          
        |  |           |                          
        |  +-----------+                          
        |                                         
        |  +-----------+             +-------------+
        +--|   Object  | references  |    Object   |
        |  | Reference |------------>|  (in model) |
        |  +-----------+             +-------------+
        |                                         
        |  +-----------+             +-------------+
        +--| Namespace | references  |  Namespace  |
           | Reference |------------>|   (model)   |
           +-----------+             +-------------+
        </artwork>
      </figure>
      <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-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 logical structure of AMM values is defined in <xref target="sec-value"/>, which is used as the basis for <xref format="title" target="sec-conops-proc"/> activities and for the basis of <xref format="title" target="sec-conops-msg"/> contents.
Values are realized and encoded according to a separate ARI specification of <xref target="I-D.ietf-dtn-ari"/>.
        </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.
        </t>
        <dl>
          <dt><xref format="title" target="sec-value-literal"/>:</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 ADMs or ODMs and produced directly by the Agent implementing the model.
The name, data type, and value of the constant are fixed and cannot be changed during its lifetime (see <xref target="sec-auth-consid-const"/>).
            </t>
            <t>
An example of a constant would be defining the numerical value <em>pi</em> to some predetermined precision.
Another typical example of a constant is the definition of a <xref target="typedef-rptt">report template</xref> or <xref target="typedef-mac">macro</xref>.
            </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 model.
While the name and data type constant, the value can change over time due to controls acting upon the Agent or changes from the application itself.
One standard interface is an ADM-defined initial state value with a control available to reset to that initial state.
Another standard interface is a control to set a variable to a specific value, based upon evaluating an expression within the Agent at runtime.
            </t>
            <t>
An example of a manager-controlled variable would be a threshold value used to compare against a sensor value in a rule predicate.
Another example is a variable which configures some algorithm within the associated application, and changes to the variable state are reflected in changes within the application.
            </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, the instantaneous data rate from a modem, or introspection on the configured state of an application.
            </t>
          </dd>
        </dl>
        <t>
Within this comparison table, "internal" means values are managed by the Agent itself and "external" means the source of values is outside the Agent.
        </t>
        <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>
                <xref format="none" target="sec-obj-const">CONST</xref>
              </td>
              <td>
                <xref format="none" target="sec-obj-var">VAR</xref>
              </td>
            </tr>
            <tr>
              <th>External</th>
              <td>
                <xref format="none" target="sec-value-literal">
                  <em>Literal</em>
                </xref>
              </td>
              <td>
                <xref format="none" target="sec-obj-edd">EDD</xref>
              </td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="sec-conops-proc">
        <name>Agent Processing</name>
        <t>
Based on the reasoning described in <xref target="RFC9675"/>, 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 built-in types available (see <xref target="sec-type-builtin"/>) 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-convert"/> 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>
                <xref format="none" target="sec-obj-ctrl">CTRL</xref>
              </td>
              <td><xref format="none" target="typedef-mac">MAC</xref>, <xref format="none" target="sec-type-execset">EXECSET</xref></td>
            </tr>
            <tr>
              <td>Evaluation</td>
              <td><xref format="none" target="sec-obj-oper">OPER</xref>, <xref format="none" target="sec-obj-typedef">TYPEDEF</xref></td>
              <td>
                <xref format="none" target="typedef-expr">EXPR</xref>
              </td>
            </tr>
            <tr>
              <td>Reporting</td>
              <td>
                <em>N/A</em>
              </td>
              <td><xref format="none" target="typedef-rptt">RPTT</xref>, <xref format="none" target="sec-type-rptset">RPTSET</xref></td>
            </tr>
            <tr>
              <td>Value Production</td>
              <td><xref format="none" target="sec-obj-const">CONST</xref>, <xref format="none" target="sec-obj-edd">EDD</xref>, <xref format="none" target="sec-obj-var">VAR</xref></td>
              <td>
                <em>N/A</em>
              </td>
            </tr>
            <tr>
              <td>Type Matching and Conversion</td>
              <td>
                <xref format="none" target="sec-obj-typedef">TYPEDEF</xref>
              </td>
              <td>
                <xref format="none" target="sec-type-builtin">ARITYPE</xref>
              </td>
            </tr>
            <tr>
              <td>Rule Autonomy</td>
              <td><xref format="none" target="sec-obj-sbr">SBR</xref>, <xref format="none" target="sec-obj-tbr">TBR</xref></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.
Because each message is based on ARI value types, they can be implemented in Agent and Manager by encoding the associated ARI according to a network-specific transport binding.
        </t>
        <t>
The choice of encoding form, framing, or transport are implementation matters outside of this specific document.
A specific message framing and an initial binding to the Bundle Protocol are defined in <xref target="I-D.ietf-dtn-amp"/>.
        </t>
        <dl>
          <dt>Execution:</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 <xref target="typedef-mac">MAC value</xref>.
The form of this message is an <xref format="title" target="sec-type-execset"/> value.
This type of message is only sent from Manager to Agent.
Each message can contain multiple execution targets but all must be associated with the same nonce value.
It is an implementation detail whether a Manager sends fewer messages with more targets or more timely messages with fewer targets.
          </dd>
          <dt>Reporting:</dt>
          <dd>
This message carries the reports generated by <xref format="title" target="sec-proc-rpt"/> activities and as the result of <xref format="title" target="sec-proc-exec"/> when the Manager provides a correlator nonce.
The form of this message is an <xref format="title" target="sec-type-rptset"/> value.
This type of message is only sent from Agent to Manager.
Each message can contain multiple report containers but all must be associated with the same nonce value.
It is an implementation detail whether an Agent sends fewer messages with more reports or more timely messages with fewer reports.
          </dd>
        </dl>
        <t>
In addition to the ARI values being conveyed in those messages, transport bindings need to include endpoint identity information for each message.
Each transport binding <bcp14>SHALL</bcp14> convey a destination endpoint identity with each transmitted message.
Each transport binding <bcp14>SHALL</bcp14> ensure that transmitted messages are associated with an authenticated source endpoint identity.
Each transport binding <bcp14>SHALL</bcp14> require that received messages are associated with an authenticated source endpoint identity.
Each transport binding <bcp14>SHALL</bcp14> convey an authenticated source endpoint identity with each received message.
The form of an endpoint identity and means by which an identity is authenticated are transport-specific and outside the scope of this document.
        </t>
        <t>
In addition to the data messaging above, if a transport binding provides the Agent or Manager with information about the reachability of its peer Managers or Agents, respectively, the entity <bcp14>SHOULD</bcp14> use that information to queue (and aggregate) messaging to unreachable peers.
        </t>
        <aside>
          <t>
For DTN transports, as expected to be used in <xref target="RFC9675"/>, true destination reachability is not knowable at network edges and this capability is not expected to be useful.
For resource-constrained applications of the DTNMA, reachability information is expected to be more available and useful for queuing.
For example, if all reporting from an agent occurs through a single outgoing data link and that link becomes unavailable then any managers are certainly unreachable.
          </t>
        </aside>
      </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"/>.
One subset of AMM values are object references used to identify (and parameterize) individual AMM objects.
        </dd>
      </dl>
      <section anchor="sec-value">
        <name>AMM Values</name>
        <t>
Values within the AMM have two top-level classes: literal values, and object reference values. 
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-literal">
          <name>Literal Values</name>
          <t>
Literal 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 Literal value serves as its own 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>Built-In 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 built-in types as described in <xref target="sec-type-builtin"/> and they are managed with an IANA registry defined in <xref section="9.3" target="I-D.ietf-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> and a value itself has no direct association with a semantic type outside of a specific context in which that type is used (<em>e.g.</em>, <xref target="sec-proc-type-match"/> and <xref target="sec-proc-convert"/>).
          </t>
        </section>
        <section anchor="sec-value-objref">
          <name>Object Reference Values</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 the following parts: an organization ID, a model ID, an optional model revision date, an object type, an object ID, and object-specific optional parameters.
          </t>
          <t>
The organization ID, model ID, and model revision together identify a single object namespace as discussed in <xref target="sec-value-nsref"/>.
          </t>
          <t>
A registry for organization text names and integer enumerations is defined in <xref section="9.3" target="I-D.ietf-dtn-ari"/>.
This registry makes a reservation for a large number of private-use code points to allow operating domains, missions, and users to define their own non-registered organization space for ADMs and ODMs.
          </t>
          <t>
Object types, each with a text name and integer enumeration, are defined in an IANA registry by <xref section="9.3" target="I-D.ietf-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 three 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, given parameters, and actual parameters.
Formal parameters are discussed in <xref target="sec-obj-metadata"/> while given and actual parameters are discussed here in relation to the object reference.
            </t>
            <t>
Given parameters are part of an object reference and 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>
Given parameters can either be absent, present as a list (with logic equivalent to the built-in <tt>AC</tt> type), or present as a map (with logic equivalent to the built-in <tt>AM</tt> type).
Either form can be used to convert to equivalent actual parameters as discussed below.
            </t>
            <t>
There are two ways in which the value of each given 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 given 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 produces a value that references a parameter of the producing object.
The produced value's given parameter can be given as the <tt>LABEL</tt> of the producing object's formal parameter. 
In this way, a value-producing object's parameters can "flow down" to all of the values that it produces. 
              </dd>
            </dl>
            <t>
In cases where a formal parameter contains a default value, the associated given parameter may be omitted. Default values in formal parameters (and, thus, optional given parameters) are encouraged as they reduce the size of data items communicated between Managers and Agents in a network.
            </t>
            <t>
Finally, actual parameters are the result of applying the <xref format="title" target="sec-proc-params"/> procedure to normalize a set of given parameters based on a set of formal parameters from a processing context.
            </t>
          </section>
        </section>
        <section anchor="sec-value-nsref">
          <name>Namespace Reference Values</name>
          <t>
One form of AMM value is a namespace reference, which is similar to an object reference but only includes the namespace components of the organization ID, model ID, and model revision .
          </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.
          </t>
          <t>
Namespaces, by their existence, <bcp14>SHALL NOT</bcp14> be used as a security mechanism.
An Agent or Manager <bcp14>SHALL NOT</bcp14> infer security information or access control based solely on namespace information.
          </t>
        </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.ietf-dtn-ari"/>.
Another function of the ARI is for diagnostic or configuration purposes within Managers or Agents.
          </t>
        </section>
      </section>
      <section anchor="sec-type-builtin">
        <name>Built-In Value Types</name>
        <t>
This section describes the built-in types used for AMM values, which are those usable directly with ARI syntax.
By definition, literal values are self-contained and literal types restrict the form and function of those values.
        </t>
        <t>
All built-in 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.
Built-in types are defined within the "DTNMA Literal Types" and "DTNMA Object Types" registries of <xref target="IANA-DTNMA"/> 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>
        <t>
These lists of built-in type names are not fixed in any single specification, and require standards action to add to and update URI processors to handle them, so it is expected that this list will be relatively static (compared to the expected rate of addition or changes to ADMs).
        </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>The text name or integer enumeration of a non-object AMM entity (parent object parameter or table column name). This is only valid in a nested parameterized ARI or for specific control parameters.</td>
              </tr>
              <tr>
                <td>
                  <tt>CBOR</tt>
                </td>
                <td>A byte string containing a single encoded CBOR item. The structure is opaque to the Agent but guaranteed well-formed for the ADM using it.</td>
              </tr>
              <tr>
                <td>
                  <tt>ARITYPE</tt>
                </td>
                <td>The text name or integer enumeration of one of the built-in value types (as registered in <xref target="IANA-DTNMA"/>).</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 compacted by eliding the literal type as defined in <xref target="sec-proc-compact"/>.
            </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-convert-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 converted between types (<xref target="sec-proc-convert-numeric"/>).
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 needs to 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-container">
          <name>Containers</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 AMM value containers, which can only be present in a typed-literal ARI form.
          </t>
          <t>
The AMM defines three collection literal types (AC, AM, and TBL) 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 ARI elements.
The contents of an AC can be restricted in size and type by the use of a <xref target="sec-type-semantic">semantic type</xref>.
            </t>
            <t>
An AC is used when there is a need to refer to multiple AMM values 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 anchor="sec-type-am">
            <name>ARI Map (AM)</name>
            <t>
An ARI Map (AM) is a mapping from a set of "key" ARIs to arbitrary-typed "value" ARIs.
AM keys are limited to untyped literals, while the AM values can be any type.
The contents of an AM can be restricted in size and type by the use of a <xref target="sec-type-semantic">semantic type</xref>.
            </t>
            <t>
An AM is used when there is a need to define data structures with complex, optionally present attributes.
For example, as control parameters used to define new objects in an ODM.
            </t>
          </section>
          <section anchor="sec-type-tbl">
            <name>ARI Table (TBL)</name>
            <t>
An ARI Table (TBL) is a collection of values which are logically structured as a two dimensional table of rows and columns, with each cell of the table containing an AMM value.
            </t>
            <t>
Although the contents of a TBL can be handled independently of any data model, the meaning of a TBL can only be interpreted within the context of a Table Template (TBLT) 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 and uniqueness of rows in the TBL.
            </t>
            <t>
A TBL is used when an EDD represents a set or list of complex items as rows in a table.
For example, the Agent ADM reports its own set of supported ADMs and features as a TBL (see the "capability" object).
            </t>
          </section>
          <section anchor="sec-type-execset">
            <name>Execution-Set (EXECSET)</name>
            <t>
An Execution-Set (EXECSET) is a collection of values used as targets for the <xref format="title" target="sec-proc-exec"/> activity.
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.
            </t>
            <t>
The contents of an EXECSET value are as follows:
            </t>
            <dl newline="true">
              <dt>Correlator nonce:</dt>
              <dd>
This field is an optional 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.
The value is limited to match the <xref target="typedef-nonce"><tt>NONCE</tt></xref> type.
              </dd>
              <dt>Targets:</dt>
              <dd>
This is an unordered list of targets to be executed by an Agent.
Each execution target is limited to match the <xref target="typedef-exec-tgt"><tt>exec-tgt</tt></xref> type.
              </dd>
            </dl>
          </section>
          <section anchor="sec-type-rptset">
            <name>Reporting-Set (RPTSET)</name>
            <t>
A Reporting-Set (RPTSET) is a collection of report containers, where each report container consists of a timestamp and an ordered list of data values populated in conformance to a source object being reported on.
Reporting-Set values and reports themselves do not have individual identifiers, rather they are identified by their source and the timestamp at which their data values were collected.
            </t>
            <t>
The contents of an RPTSET value are as follows:
            </t>
            <dl newline="true">
              <dt>Correlator nonce:</dt>
              <dd>
This field is an optional opaque correlator "nonce" which is used to associate report containers with specific EXECSET messages which caused the reports to be generated.
The value is limited to match the <xref target="typedef-nonce"><tt>NONCE</tt> type</xref>.
              </dd>
              <dt>Reference time:</dt>
              <dd>
This field is used as an absolute reference time for all reports contained in the RPTSET.
The value is limited to match the <tt>TP</tt> built-in type.
It is used as an storage optimization when a large number of reports are generated around the same time.
              </dd>
              <dt>Report list:</dt>
              <dd>
The main content of the RPTSET are the reports themselves, which are defined below.
The order of reports within the RPTSET are not significant, and the presence of a report in any particular RPTSET is not significant.
The RPTSET itself is only a container.
              </dd>
            </dl>
            <t>
The contents of each report within a RPTSET are as follows:
            </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: <xref target="typedef-valueobj"><tt>VALUE-OBJ</tt></xref>, or <tt>CTRL</tt>. If the source was parameterized, this ARI <bcp14>SHALL</bcp14> contain the actual parameters used at the time of reporting.
              </dd>
              <dt>Generation Time:</dt>
              <dd>
The timestamp at which the report items were sampled, relative to the Reference Time of the containing RPTSET.
The value is limited to match the <tt>TD</tt> built-in type.
              </dd>
              <dt>Items:</dt>
              <dd>
                <t>
A list of values corresponding to the source object, with cardinality according to the following:
                </t>
                <ul>
                  <li>For a <tt>VALUE-OBJ</tt> source the item list <bcp14>SHALL</bcp14> be the result of <xref target="sec-proc-rpt-valueref">reporting</xref> on that object.</li>
                  <li>For a <tt>CTRL-REF</tt> source there <bcp14>SHALL</bcp14> 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>
          </section>
        </section>
        <section anchor="sec-type-objref">
          <name>Object Reference Types</name>
          <t>
For each of the AMM Object Types there is a corresponding object reference type.
The object type names and enumerations from the "DTNMA Object Types" registry of <xref target="IANA-DTNMA"/> are used as names for the built-in type of the corresponding object reference.
          </t>
          <t>
For example, a reference value for a CTRL object is typed as <tt>CTRL</tt>.
It is important to understand the distinction, illustrated in <xref target="fig-value-object"/>, between the built-in type and the object type both of which have the same name but used in two completely independent contexts.
          </t>
        </section>
        <section anchor="sec-type-valclass">
          <name>Value-Class Types</name>
          <t>
As a special case of built-in type which act as a union or class of types are those listed in <xref target="tab-type-valclass"/>.
These are implemented as a built-in type rather than a semantic type because they behave differently than a <xref target="sec-semtype-union">Type Union</xref> because they will match any value in the associated class and conversions within these types will not affect the value.
          </t>
          <table anchor="tab-type-valclass">
            <name>Value-Class Types</name>
            <thead>
              <tr>
                <th>Type</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>
                  <tt>LITERAL</tt>
                </td>
                <td>Any possible literal value.</td>
              </tr>
              <tr>
                <td>
                  <tt>OBJECT</tt>
                </td>
                <td>Any possible object reference value.</td>
              </tr>
              <tr>
                <td>
                  <tt>NAMESPACE</tt>
                </td>
                <td>Any possible namespace reference value.</td>
              </tr>
            </tbody>
          </table>
        </section>
        <section>
          <name>Custom 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 <bcp14>RECOMMENDED</bcp14> 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 <bcp14>RECOMMENDED</bcp14> to do so.
            </li>
            <li>
Otherwise, when the desired behavior cannot be accomplished by a semantic typedef, it is <bcp14>RECOMMENDED</bcp14> 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 <bcp14>MAY</bcp14> 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 Value Types</name>
        <t>
While built-in 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 constraints), and adding human-friendly annotation (such as references to defining documents, or explanations of purpose).
        </t>
        <t>
Semantic types can be defined in two ways: a named <xref format="title" target="sec-obj-typedef"/> or an anonymous semantic type defined at the point of use (<em>e.g.</em>, within an AMM object definition).
The specific syntax used to define semantic types within an ADM are defined and explained in a separate document.
        </t>
        <t>
When a "type" is needed for an AMM value in an object definition it <bcp14>SHALL</bcp14> be either one of the built-in types, a namespace-qualified semantic type, or an anonymous semantic type just for that value.
        </t>
        <t>
The actual mechanics of semantic typing are based on the classes defined in the following subsections.
        </t>
        <section anchor="sec-semtype-use">
          <name>Named Type Use</name>
          <t>
The simplest case is where an existing named type is referenced to be used in a specific context.
The form of a named type use <bcp14>SHALL</bcp14> be an AMM value containing either an <tt>ARITYPE</tt> literal, for a <xref target="sec-type-builtin">built-in type</xref>, or a <tt>TYPEDEF</tt> object reference, for a data-model-provided <xref target="sec-obj-typedef">semantic type</xref>.
          </t>
          <t>
Even an unconstrained type reference can be used within a TYPEDEF to provide a human-friendly name or associated documentation for the use of a simple type.
While the tooling might not care about direct type use, it can greatly improve human interpretation of a data model.
          </t>
          <t>
An implementation <bcp14>SHALL</bcp14> be able to handle situations where type references create a loop.
This would allow values to follow a recursive structure, but it does not mean the values themselves would be of an indefinite size.
          </t>
          <t>
Within a named type use, annotations can be added which enhance human understanding of the type.
Annotations possible within a named type use <bcp14>SHALL</bcp14> consist of:
          </t>
          <ul>
            <li>
A free-form text reference to a specific document defining the type in more detail.
            </li>
            <li>
A free-form text description of the type, which can be in addition to a reference.
            </li>
            <li>
A units name for <tt>NUMERIC</tt> values to make the interpretation of values more explicit.
            </li>
            <li>
A display hint to enable type-specific handling of values, such as IP addresses within BYTESTR values.
            </li>
          </ul>
          <t>
Within a named type use, constraints can be added to some of the <xref format="title" target="sec-type-simple"/> in order to limit what values are considered valid within the type domain.
Constraints possible within a named type use <bcp14>SHALL</bcp14> consist of:
          </t>
          <ul>
            <li>Limits on ranges of valid <tt>NUMERIC</tt> types</li>
            <li>Limits on length of <tt>TEXTSTR</tt>, <tt>BYTESTR</tt>, or <tt>CBOR</tt></li>
            <li>Labels of enumerated values or bit positions for <tt>INTEGER</tt> types</li>
            <li>Regular expression patterns for <tt>TEXTSTR</tt></li>
            <li>Structural patterns for <tt>CBOR</tt> items using Concise Data Definition Language (CDDL)</li>
          </ul>
        </section>
        <section anchor="sec-semtype-ulist">
          <name>Uniform List</name>
          <t>
This is the case of a list of AMM values within an <xref format="title" target="sec-type-ac"/> where the type of each value is uniform for the whole list.
Only the <tt>AC</tt> type <bcp14>MAY</bcp14> be refined by a uniform list.
Each item of a uniform list <bcp14>SHALL</bcp14> be constrained to a single semantic or built-in type.
The number of items in the list <bcp14>MAY</bcp14> be constrained within a range of valid sizes.
          </t>
        </section>
        <section anchor="sec-semtype-dlist">
          <name>Diverse List</name>
          <t>
This is the case of a list of AMM values within an <xref format="title" target="sec-type-ac"/> where the type of each value is different throughout the list.
Only the <tt>AC</tt> type <bcp14>MAY</bcp14> be refined by a diverse list.
Each part of a uniform list <bcp14>SHALL</bcp14> be constrained as either: an item with a single semantic or built-in type or a <xref target="sec-semtype-seq">Sequence</xref>.
          </t>
        </section>
        <section anchor="sec-semtype-umap">
          <name>Uniform Map</name>
          <t>
This is the case of a map of AMM values within an <xref format="title" target="sec-type-am"/> where the type of each key and each value is uniform for the whole map.
Only the <tt>AM</tt> type <bcp14>MAY</bcp14> be refined by a uniform map use.
          </t>
        </section>
        <section anchor="sec-semtype-tblt">
          <name>Table Template</name>
          <t>
This is the case of a table of AMM values within a <xref format="title" target="sec-type-tbl"/> where each column is annotated with a text name and the type of each value in a column is uniform across all rows.
Only the <tt>TBL</tt> type <bcp14>MAY</bcp14> be refined by a table template.
The number of rows in the table <bcp14>MAY</bcp14> be constrained within a range of valid sizes.
A single "key" column <bcp14>SHOULD</bcp14> be identified as the unique identifier for each row.
One or more column tuples <bcp14>MAY</bcp14> be identified as unique among all rows.
          </t>
        </section>
        <section anchor="sec-semtype-union">
          <name>Type Union</name>
          <t>
This creates a choice between a combination of multiple semantic types.
Each of the types in a union <bcp14>SHOULD</bcp14> be exclusive to avoid ambiguity in interpretation by a value processor.
The order of choices within a union <bcp14>SHALL</bcp14> be used as the order to check for <xref format="title" target="sec-proc-type-match"/> and <xref format="title" target="sec-proc-convert"/> procedures.
          </t>
        </section>
        <section anchor="sec-semtype-seq">
          <name>Sequence</name>
          <t>
This creates a subset of a <xref target="sec-semtype-dlist">Diverse List</xref> which matches multiple sequential elements of the list.
A sequence is similar to a <xref format="title" target="sec-semtype-ulist"/> except that it doesn't specify an AC container, it is used to specify items <em>within</em> a container.
Each item of a sequence <bcp14>SHALL</bcp14> be constrained to a single semantic or built-in type.
The number of items in the sequence <bcp14>MAY</bcp14> be constrained within a range of valid sizes.
          </t>
          <t>
A sequence can also be used with formal parameters to create a form of variadic parameter, where multiple given parameters are matched and combined into a single actual parameter (see <xref target="sec-proc-params"/>).
          </t>
        </section>
      </section>
      <section anchor="sec-obj">
        <name>AMM Object Types</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 <xref format="title" target="sec-proc-prod"/>, <xref format="title" target="sec-proc-exec"/>, or <xref format="title" target="sec-proc-eval"/> 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>
The names for the types of objects defined in this section can be used in two different and separate contexts: as a name for the type of the object itself (written as plain text within this document) when in the context of the AMM object model, or as the name of an <xref target="sec-value-objref">object reference</xref> type (written in typewriter text within this document) when used in the context of the AMM value model.
        </t>
        <t>
Unless explicitly specified in the object type subsection, an object <bcp14>SHALL NOT</bcp14> 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>
              <t>
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 <bcp14>SHALL</bcp14> contain a name field.
An object's name <bcp14>SHALL NOT</bcp14> change between ADM revisions.
Each name <bcp14>SHALL</bcp14> conform to the <tt>id-text</tt> ABNF rule below.
Within each namespace and object type, the name of an object <bcp14>SHALL</bcp14> be unique.
              </t>
              <sourcecode type="abnf">
id-text = (ALPHA / "_") *(ALPHA / DIGIT / "_" / "-" / ".")
              </sourcecode>
            </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 <bcp14>SHOULD</bcp14> contain an enumeration field.
An object's enumeration <bcp14>SHALL NOT</bcp14> change between ADM revisions.
When present, each enumeration <bcp14>SHALL</bcp14> be a non-negative value in the domain of a signed 32-bit integer value.
Within each namespace and object type, the enumeration of an object <bcp14>SHALL</bcp14> be unique.
            </dd>
            <dt>Status:</dt>
            <dd>
Each object definition <bcp14>MAY</bcp14> 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 <bcp14>SHALL</bcp14> be considered the same as the status of the ADM which contains it.
            </dd>
            <dt>Reference:</dt>
            <dd>
Each object definition <bcp14>MAY</bcp14> 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 <bcp14>MAY</bcp14> 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 <bcp14>SHOULD</bcp14> 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 <bcp14>SHALL</bcp14> be an ordered list of individual formal parameter definitions.
Each formal parameter <bcp14>SHALL</bcp14> include type and name.
Each formal parameter <bcp14>MAY</bcp14> 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 <bcp14>SHALL</bcp14> include the type being named, as described in <xref target="sec-type-semantic"/>.
The type of a TYPEDEF is fixed and <bcp14>SHALL NOT</bcp14> change between ADM revisions.
The type <bcp14>SHALL</bcp14> be either a union of other types or a restriction of or annotation upon another type.
            </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-ident">
          <name>Identity Object (IDENT)</name>
          <t>
An ADM can use an identity object (IDENT) to define a unique, abstract, and untyped identity.
The only purpose of an IDENT is to denote its name, parameters, and existence semantics.
This allows an extensible but controlled enumeration of valid AMM values for object parameters and states (<em>e.g.</em>, configuration state within a VAR object).
          </t>
          <t>
Each IDENT object <bcp14>MAY</bcp14> be derived from one or more other base IDENT objects to form a directed graph.
An IDENT which is not derived from any other is referred to as a "root" object.
Any chain of derived IDENT objects <bcp14>SHALL NOT</bcp14> form a loop.
The IDENT base graph provides a means to constrain its use in an <xref target="sec-obj-metadata">object formal parameter</xref> and validate its use in an <xref target="sec-value-objref-params">object reference given parameter</xref>.
          </t>
          <t>
The definition of a IDENT 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 non-abstract IDENT definition <bcp14>MAY</bcp14> include formal parameters to be used when the IDENT is referenced.
An abstract IDENT <bcp14>SHALL NOT</bcp14> include any formal parameters.
Parameterized objects are discussed in <xref target="sec-auth-consid"/>.
The formal parameters of an IDENT are fixed and <bcp14>SHALL NOT</bcp14> change between ADM revisions.
            </dd>
            <dt>Abstract marking:</dt>
            <dd>
A boolean indication of whether this IDENT is considered abstract, meaning it cannot be used as an end value, or not.
The abstract marking of an IDENT <bcp14>MAY</bcp14> change between ADM revisions, but only from abstract to non-abstract.
This ensures that earlier state referencing the IDENT does not become invalidated.
            </dd>
            <dt>Base references:</dt>
            <dd>
An unordered list of object references to other IDENT objects from which this object is derived.
The bases of an IDENT <bcp14>MAY</bcp14> change between ADM revisions, but only to add and not remove base references.
This ensures that earlier state referencing the IDENT does not become invalidated.
            </dd>
          </dl>
          <t>
As defined in this document, IDENTs can only be defined within an ADM.
          </t>
          <t>
The purpose of the abstract marking is to disallow specific objects in an IDENT hierarchy, typically those closest to the root object, from being referenced by values stored in CONST or VAR objects or produced by EDD objects.
It would also be useful in a manager-side user interface to filter-out choices for IDENT objects which are marked as abstract.
IDENT objects marked as abstract are expected to be used as the "base" for semantic types or other IDENT objects.
          </t>
        </section>
        <section anchor="sec-obj-edd">
          <name>Externally Defined Data (EDD)</name>
          <t>
Externally defined data (EDD) objects 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"/> activity.
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 <bcp14>SHOULD</bcp14> 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="sec-auth-consid"/>.
          </t>
          <t>
The value produced by an EDD is allowed to, but not required to, change over time.
Because EDDs can be referenced by condition expressions of <xref target="sec-obj-tbr">Time-Based Rules</xref> or elsewhere, an Agent implementation could be optimized by allowing an EDD to indicate when its produced value <em>would</em> change.
It is an implementation matter for if and how an application can provide that indication.
          </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 an <xref format="title" target="sec-type-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 <bcp14>MAY</bcp14> include formal parameters to be used when the EDD is used to produce a value.
Parameterized objects are discussed in <xref target="sec-auth-consid"/>.
The formal parameters of an EDD are fixed and <bcp14>SHALL NOT</bcp14> change between ADM revisions.
            </dd>
            <dt>Type:</dt>
            <dd>
An EDD definition <bcp14>SHALL</bcp14> 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 <bcp14>SHALL NOT</bcp14> 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 <tt>EXPR</tt> value to evaluate, <tt>MAC</tt> value to execute, or a <tt>RPTT</tt> value to generate reports.
          </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>
A CONST definition <bcp14>MAY</bcp14> include formal parameters to be used during <xref target="sec-proc-prod-const-var">value production</xref>.
Parameterized objects are discussed in <xref target="sec-auth-consid-const-var-params"/>.
Parameters for a CONST are only meaningful when the value uses actual parameters themselves containing one or more <tt>LABEL</tt> type, each referencing a formal parameter identifier.
            </dd>
            <dt>Type:</dt>
            <dd>
A CONST definition <bcp14>SHALL</bcp14> 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 <bcp14>SHALL NOT</bcp14> change for the lifetime of its containing namespace.
            </dd>
            <dt>Value:</dt>
            <dd>
A CONST definition <bcp14>SHALL</bcp14> include the literal value produced during evaluation.
The value of a CONST is fixed and <bcp14>SHALL NOT</bcp14> change for the lifetime of its containing namespace.
            </dd>
          </dl>
          <t>
When a constant is not longer needed it <bcp14>SHALL</bcp14> be marked with a status of "deprecated" or "obsolete" rather than being removed (see <xref target="sec-adm-metadata-status"/> and <xref target="sec-auth-consid-const"/>).
Allowing operators to define constants dynamically in an ODM means that a constant could be defined, removed, and then re-defined at a later time with a different type or value, which defeats the purpose of having constants so is prohibited above.
          </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 <bcp14>SHOULD</bcp14> 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="sec-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"/> <bcp14>SHOULD</bcp14> be used instead of a more fragile use of CTRL directly.
          </t>
          <t>
The definition of a CTRL 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 <bcp14>MAY</bcp14> include formal parameters to be used when the CTRL is executed.
Parameterized objects are discussed in <xref target="sec-auth-consid"/>.
The formal parameters of a CTRL are fixed and <bcp14>SHALL NOT</bcp14> change between ADM revisions.
              </t>
            </dd>
            <dt>Result:</dt>
            <dd>
A CTRL definition <bcp14>MAY</bcp14> include the definition of a result.
The result <bcp14>SHALL</bcp14> have a name and a type.
The result <bcp14>MAY</bcp14> 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 <bcp14>MAY</bcp14> include formal parameters to be used when the OPER is evaluated.
Parameterized objects are discussed in <xref target="sec-auth-consid"/>.
The formal parameters of an OPER are distinct from the operands from the expression stack. 
            </dd>
            <dt>Operands:</dt>
            <dd>
An OPER definition <bcp14>MAY</bcp14> include definitions of operand values to be popped from the expression stack when the OPER is evaluated.
Each operand <bcp14>SHALL</bcp14> 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 <bcp14>SHALL</bcp14> include definition of a result value to be pushed onto the expression stack after the OPER is evaluated.
The result <bcp14>SHALL</bcp14> have a name and a type.
The result <bcp14>SHALL NOT</bcp14> 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 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-convert-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 <bcp14>SHALL</bcp14> include an action in the form of a <xref format="title" target="typedef-mac"/>.
When triggered, the action execution <bcp14>SHALL</bcp14> 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 <bcp14>SHALL</bcp14> include a condition in the form of an <xref format="title" target="typedef-expr"/>.
The condition <bcp14>SHALL</bcp14> be evaluated in accordance with <xref target="sec-proc-eval"/> in an evaluation context with no parameters.
The result of the condition <bcp14>SHALL</bcp14> be converted 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 <bcp14>SHALL</bcp14> include a minimum execution interval in the form of a non-negative <tt>TD</tt> value.
The interval <bcp14>MAY</bcp14> 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 <bcp14>SHALL</bcp14> include a maximum execution count in the form of a non-negative <tt>UVAST</tt> value.
The count sentinel value zero <bcp14>SHALL</bcp14> 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 <bcp14>MAY</bcp14> include an initial value for its enabled state.
If not provided, the initial enabled state <bcp14>SHALL</bcp14> be <tt>true</tt>.
            </dd>
          </dl>
        </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 Agent ADM.
          </t>
          <t>
The definition of a TBR 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>
A TBR definition <bcp14>SHALL</bcp14> include an action in the form of a <xref format="title" target="typedef-mac"/>.
When triggered, the action execution <bcp14>SHALL</bcp14> be executed in accordance with <xref target="sec-proc-exec"/> in an execution context with no parameters.
            </dd>
            <dt>Start Time:</dt>
            <dd>
A TBR definition <bcp14>SHALL</bcp14> include a start time in the form of a <xref target="typedef-time"><tt>TIME</tt></xref> value.
A relative start time <bcp14>SHALL</bcp14> 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 <bcp14>MAY</bcp14> 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 <bcp14>SHALL</bcp14> include a period in the form of a positive <tt>TD</tt> value.
The period <bcp14>SHALL NOT</bcp14> be zero but any non-zero small period is valid.
            </dd>
            <dt>Maximum Count:</dt>
            <dd>
A TBR definition <bcp14>SHALL</bcp14> include a maximum execution count in the form of a non-negative <tt>UVAST</tt> value.
The count sentinel value zero <bcp14>SHALL</bcp14> 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 <bcp14>MAY</bcp14> include an initial value for its enabled state.
If not provided, the initial enabled state <bcp14>SHALL</bcp14> be <tt>true</tt>.
            </dd>
          </dl>
        </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 use of a VAR is similar to an <xref target="sec-obj-edd">EDD</xref> 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.
          </t>
          <t>
The value production of a VAR into a value <bcp14>SHALL</bcp14> be nilpotent and have no side-effects in the processor.
          </t>
          <t>
The value produced by an VAR is allowed to, but not required to, change over time.
Because VARs can be referenced by condition expressions of <xref target="sec-obj-tbr">Time-Based Rules</xref> or elsewhere, an Agent implementation could be optimized by allowing a VAR to indicate when its produced value <em>would</em> change.
It is an implementation matter for if and how an application can provide that indication.
          </t>
          <t>
A VAR has an initializer, which is used at Agent initialization and to reset the VAR (see <xref target="sec-agentadm"/>), but the VAR is otherwise stateful and will retain its last value between any actions which modify 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 <bcp14>MAY</bcp14> include formal parameters to be used during <xref target="sec-proc-prod-const-var">value production</xref>.
Parameterized objects are discussed in <xref target="sec-auth-consid-const-var-params"/>.
Parameters for a VAR are only meaningful when the value uses actual parameters themselves containing one or more <tt>LABEL</tt> type, each referencing a formal parameter identifier.
            </dd>
            <dt>Type:</dt>
            <dd>
An VAR definition <bcp14>SHALL</bcp14> 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 <bcp14>SHALL NOT</bcp14> change between ADM revisions.
            </dd>
            <dt>Initializer:</dt>
            <dd>
An VAR definition <bcp14>MAY</bcp14> include an initializer in the form of an AMM value.
The only times the initializer are needed are at <xref format="title" target="sec-proc-init"/> and when a CTRL is used to reset the state of the VAR.
The initializer of a VAR <bcp14>MAY</bcp14> change between ADM revisions.
            </dd>
          </dl>
          <aside>
            <t>
NOTE: It is possible to specify an initializer value that does not match the type of the VAR.
The VAR initializer will always be <xref target="sec-proc-convert">converted</xref> to the type of the VAR before assignment.
            </t>
          </aside>
        </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 specific syntax for how these fields fit into an ADM module is left to another document.
          </t>
          <dl newline="true">
            <dt>Module Name and Namespace:</dt>
            <dd>
              <t>
Both the module name and its namespace uniquely identify an ADM among all other possible ADMs, both well known and privately used.
The module name takes the form of a file name (specific to the ADM encoding defined outside of this document), while the module namespace takes the form of an <xref target="sec-ari">ARI</xref>.
              </t>
              <t>
These module identifiers are decomposed into two parts, described below: an organization ID part and a model ID part.
A specific ADM encoding can, and likely will, have some amount of redundancy in how the module identifiers and organization-and-model identifiers are encoded.
Because these identifiers are not allowed to change between revisions, any redundancy will at least not affect editing and updating of the ADM over time.
              </t>
            </dd>
            <dt>Organization Name and Enumeration:</dt>
            <dd>
              <t>
Each ADM definition <bcp14>SHALL</bcp14> reference an organization name.
The organization name <bcp14>SHALL NOT</bcp14> change between ADM revisions.
The organization name <bcp14>SHALL</bcp14> conform to the <tt>id-text</tt> ABNF rule of <xref target="sec-obj-metadata"/>.
              </t>
              <t>
Each ADM definition <bcp14>SHALL</bcp14> reference an organization enumeration.
The organization enumeration <bcp14>SHALL NOT</bcp14> change between ADM revisions.
The organization enumeration <bcp14>SHALL</bcp14> be a non-negative value in the domain of a signed 32-bit integer value.
              </t>
            </dd>
            <dt>Model Name and Enumeration:</dt>
            <dd>
              <t>
Each ADM definition <bcp14>SHALL</bcp14> contain a model name.
That name <bcp14>SHALL</bcp14> be unique within the organization.
The model name <bcp14>SHALL NOT</bcp14> change between ADM revisions.
The model name <bcp14>SHALL</bcp14> conform to the <tt>id-text</tt> ABNF rule of <xref target="sec-obj-metadata"/>.
              </t>
              <t>
A model enumeration is an integer, associated with the whole ADM, which identifies the model within its organization just like its name.
Model enumerations provide a stable and concise identifier for the binary encoded form of an ARI.
Each ADM definition <bcp14>SHALL</bcp14> contain a model enumeration.
The model enumeration <bcp14>SHALL NOT</bcp14> change between ADM revisions.
The model enumeration <bcp14>SHALL</bcp14> be a non-negative value in the domain of a signed 32-bit integer value.
              </t>
            </dd>
            <dt>Revision History:</dt>
            <dd>
Each ADM <bcp14>SHALL</bcp14> contain a history of dated revisions.
At least one revision <bcp14>SHALL</bcp14> 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 anchor="sec-adm-metadata-status">Status:</dt>
            <dd>
Each ADM definition <bcp14>SHOULD</bcp14> contain a status field.
The valid status value of an ADM <bcp14>SHALL</bcp14> be one of "current", "deprecated", or "obsolete".
These values are 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 <bcp14>SHALL</bcp14> be considered the same as the status of the ADM which contains it.
            </dd>
            <dt>Reference:</dt>
            <dd>
Each ADM definition <bcp14>SHOULD</bcp14> 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 <bcp14>SHOULD</bcp14> 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 <bcp14>SHALL</bcp14> have a name that is unique within the namespace of the ADM.
The name <bcp14>SHALL</bcp14> conform to the <tt>id-text</tt> ABNF rule of <xref target="sec-obj-metadata"/>.
            </dd>
          </dl>
        </section>
        <section anchor="sec-adm-features">
          <name>Features and Conformance</name>
          <t>
Following in the pattern of YANG features from <xref section="5.6.2" target="RFC7950"/> and SMIv2 conformance groups from <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>
          <t>
In the same way that an Agent instance can choose to implement or omit any particular ADM (assuming its dependencies are satisfied), an Agent instance can choose to implement or omit particular features within an ADM.
This allows more fine-grained control of what an Agent supports at runtime and also provides a standard mechanism for naming and indicating that support.
          </t>
        </section>
      </section>
      <section anchor="sec-ammadm">
        <name>Contents of an AMM ADM</name>
        <t>
This base 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 an "AMM" 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 YANG <xref target="RFC6991"/> and SMIv2 <xref target="RFC2578"/> both rely on base modules for some core behavior.
        </t>
        <section anchor="sec-baseadm-display-hints">
          <name>Display Hint Root</name>
          <t>
Rather than using fixed enumerations for the display hint of a <xref format="title" target="sec-semtype-use"/>, the AMM uses an <xref target="sec-obj-ident">IDENT</xref> hierarchy, where each leaf object represents a specific form of display for one of the built-in types.
The root IDENT object for this hierarchy is defined in this ADM, but the leaf objects will be managed outside the ADM.
This follows the pattern described in <xref target="sec-auth-consid-enum-ident"/> for extensible hints.
          </t>
        </section>
        <section>
          <name>Type Introspection Objects</name>
          <t>
To allow reflecting the contents of semantic types within the AMM value system itself, in order to support type introspection of AMM objects, the AMM defines parameterized IDENT objects used to represent each of the <xref target="sec-type-semantic">semantic types</xref> available in the AMM.
Each of the semantic type objects is derived from a base IDENT object, which is combined with the <tt>ARITYPE</tt> <xref target="sec-type-builtin">built-in type</xref> to produce a TYPEDEF that is able to capture all possible value types available to the AMM.
          </t>
        </section>
        <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 YANG <xref target="RFC6991"/> and SMIv2 <xref target="RFC2578"/>.
            </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 YANG <xref target="RFC6991"/> and SMIv2 <xref target="RFC2578"/>.
            </dd>
            <dt><tt>timestamp</tt>:</dt>
            <dd>
An absolute time at which an event happened.
This corresponds with the same name defined in YANG <xref target="RFC6991"/> and SMIv2 <xref target="RFC2578"/>.
            </dd>
          </dl>
        </section>
        <section anchor="sec-baseadm-container">
          <name>Container Semantic Types</name>
          <t>
This section contains more complex semantic types which constrain the contents of a <xref target="sec-type-container">container</xref> so that the value as a whole has a specific semantic.
          </t>
          <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 <bcp14>SHALL</bcp14> be represented in postfix order.
Postfix notation requires no additional symbols to enforce precedence, always results in a more efficient encoding, and postfix 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"/>.
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 <bcp14>SHALL</bcp14> 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 items for <xref target="sec-type-rptset">report</xref> containers.
A RPTT takes the form of a semantic typedef refining an AC to be a list of references to value-producing objects (<xref target="typedef-valueobj"><tt>VALUE-OBJ</tt></xref>) or expressions (<xref target="typedef-expr"><tt>EXPR</tt></xref>).
An object which produces an RPTT can itself be parameterized so that the object 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 direct values.
RPTT values either defined in an ADM or configured between Managers and Agents in an ODM.
Reports themselves are ephemeral and represented within ARI built-in type <tt>RPTSET</tt>, not as part of the AMM object model.
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.
Rather than having a VAR object's RPTT value changing over time, it is <bcp14>RECOMMENDED</bcp14> to deprecate earlier RPTT-producing CONST objects and create new objects.
            </t>
          </section>
          <section anchor="typedef-exec-tgt">
            <name>Execution Target Type</name>
            <t>
A convenience typedef <tt>exec-tgt</tt> is defined to codify the type of values allowed to be used as input for an <xref format="title" target="sec-proc-exec"/> (or within an <xref format="title" target="sec-type-execset"/> value) or produced by objects referenced as execution targets.
The execution target type is defined to be either a direct <tt>CTRL</tt> reference, a direct <tt>MAC</tt> value, or a reference to a value-producing object which itself is typed as <tt>exec-tgt</tt>.
            </t>
          </section>
          <section anchor="typedef-eval-tgt">
            <name>Evaluation Target Type</name>
            <t>
A convenience typedef <tt>eval-tgt</tt> is defined to codify the type of values allowed to be used as input for an <xref format="title" target="sec-proc-eval"/> activity or produced by objects referenced as evaluation targets.
The execution target type is defined to be either a direct <tt>SIMPLE</tt> value, a direct <tt>EXPR</tt> value, or a reference to a value-producing object which itself is typed as <tt>eval-tgt</tt>.
            </t>
          </section>
        </section>
        <section anchor="sec-baseadm-unions">
          <name>Type Unions</name>
          <t>
All of the literal types defined in <xref target="sec-type-builtin"/> have a flat structure, with some types sharing the same value structure but using distinct built-in type code points to distinguish them (<em>e.g.</em>, both <tt>BYTESTR</tt> and <tt>CBOR</tt> use the same byte-string value).
In order to allow types to fit into a more logical taxonomy, the AMM 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 a model 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>ARITYPE</tt> and <tt>TYPEDEF</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>NULL</tt>, <tt>BOOL</tt>, <tt>NUMERIC</tt>, <tt>TEXTSTR</tt>, and <tt>BYTESTR</tt> types. This matches any untyped literal value.</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. This matches any non-container literal value (typed or untyped).</dd>
            <dt><tt>ANY</tt>:</dt>
            <dd>The union of <tt>LITERAL</tt>, <tt>OBJECT</tt>, and <tt>NAMESPACE</tt> <xref target="sec-type-valclass">value-class types</xref>. This matches all values that can be in an ARI. </dd>
            <dt anchor="typedef-valueobj"><tt>VALUE-OBJ</tt>:</dt>
            <dd>The union of <tt>CONST</tt>, <tt>EDD</tt>, and <tt>VAR</tt> reference types. This matches any reference to an object that can <xref target="sec-proc-prod">produce a value</xref>.</dd>
            <dt anchor="typedef-nonce"><tt>NONCE</tt>:</dt>
            <dd>The union of <tt>BYTESTR</tt>, <tt>UINT64</tt>, and <tt>NULL</tt> types. This is used by EXECSET and RPTSET values to correlate Agent-Manager messages (see <xref target="sec-conops-msg"/>).</dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-agentadm">
        <name>Contents of an Agent ADM</name>
        <t>
While the AMM 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 within an Agent.
          </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>
            <li>
Visibility into the execution state(s) of an Agent, including counters for the total number of successful and failed executions.
            </li>
            <li>
Counters for the total number of messages sent or received by the agent, including reception failures.
            </li>
          </ul>
        </section>
        <section anchor="sec-agentadm-helperctrl">
          <name>Macro Helper Controls</name>
          <t>
The Agent ADM contains a set of controls which implement behaviors to macro execution logic.
          </t>
          <dl>
            <dt>Branching Control:</dt>
            <dd>This control has a condition parameter to evaluate and two optional parameters to define sub-macros, one of which is executed depending upon the condition result truthy-ness.</dd>
            <dt>Failure Catching Control:</dt>
            <dd>This control has one parameter of a macro to execute normally and a second parameter of a macro to execute on the condition that the normal execution fails for some reason.</dd>
            <dt>Waiting Controls:</dt>
            <dd>This family of controls is to be embedded at the start (or anywhere within) a macro and pauses execution to wait on either: a specific absolute time, a relative time from start-of-control, or a condition to evaluate to truthy.</dd>
          </dl>
        </section>
        <section anchor="sec-agentadm-opers">
          <name>Basic Operators</name>
          <t>
The Agent ADM contains a set of operators which provide logical and mathematical functions to macro execution.
          </t>
          <dl>
            <dt>Numeric Operators:</dt>
            <dd>These perform operations related to negation, addition, subtraction, multiplication, division, and remainder (modulo) of their operands. These perform numeric promotion of their operands in accordance with <xref target="sec-proc-convert-numeric-promote"/>.</dd>
            <dt>Boolean Operators:</dt>
            <dd>These perform operations related to boolean NOT, AND, OR, and XOR of their operands. These perform boolean casting of their operands in accordance with <xref target="sec-proc-convert-bool"/>. </dd>
            <dt>Bitwise Operators:</dt>
            <dd>These perform bitwise NOT, AND, OR, and XOR operations on only unsigned integer operands.</dd>
            <dt>Comparison Operators:</dt>
            <dd>These perform pairwise comparison between their operands. Equality and inequality can be performed on any operand types, but ordered comparison (<em>e.g.</em>, greater than) can only be performed on numeric operands.</dd>
            <dt>Table Filtering:</dt>
            <dd>This operator is used to process tables produced within an expression to filter by row contents and specific columns. This is an example of a parameterized operator because the parameters control the filtering while the operand is the table-to-be-filtered.</dd>
          </dl>
        </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 <bcp14>SHALL</bcp14> 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-convert">converting</xref> to the VAR type.
              </li>
              <li>
Otherwise, the value is <tt>undefined</tt>.
              </li>
            </ul>
            <t>
Any ODM-defined VAR objects <bcp14>MAY</bcp14> retain their state.
            </t>
          </li>
          <li>
All ADM-defined TBR and SBR objects <bcp14>SHALL</bcp14> have their Enabled state set to the Initial Enabled value.
Any ODM-defined TBR and SBR objects <bcp14>MAY</bcp14> 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 references (see <xref section="4.2" target="RFC3986"/>).
Any ARIs within an ADM definition <bcp14>SHALL</bcp14> be handled as URI References and resolved in accordance with the procedure of <xref section="5" target="RFC3986"/> with the namespace reference of the containing ADM used as a base URI.
        </t>
        <t>
One side effect of using the namespace reference as a base is that ARIs within an ADM <em>do not</em> require a URI scheme part.
        </t>
      </section>
      <section anchor="sec-proc-deref">
        <name>Dereferencing</name>
        <t>
An <xref format="title" target="sec-value-objref"/> contains an object path and a parameter part.
Dereferencing an <tt>OBJECT</tt> value uses the object path 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 (<em>i.e.</em>, it matches the built-in type <tt>OBJECT</tt>).
If the value is not an object reference, this procedure stops and is considered failed.
          </li>
          <li>
The <tt>OBJECT</tt> value namespace (organization ID, model ID, and model revision) is used to search for a defined ADM or ODM namespace.
A text form organization ID or model ID <bcp14>SHALL</bcp14> be compared within the UTF-8 character set in accordance with <xref target="RFC3629"/>.
An integer form organization ID or model ID <bcp14>SHALL</bcp14> be compared numerically.
If present, a model revision <bcp14>SHALL</bcp14> be compared to the latest revision of an ADM as either UTF-8 text or an internal decoded date form with equivalent comparison behavior.
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.
A text form object name <bcp14>SHALL</bcp14> be compared within the UTF-8 character set in accordance with <xref target="RFC3629"/>.
An integer object name namespace <bcp14>SHALL</bcp14> be compared numerically.
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 format="title" target="sec-value-objref"/> contains an object path and a parameter part.
The parameter part of an <tt>OBJECT</tt> value represents the <xref target="sec-value-objref-params">given parameters</xref> being used.
The given parameters are present either as a (possibly empty) ARI list or an ARI map.
Due to nuances of the AMM value system, the given parameters are not themselves either AC or AM values but similar to untyped ARI values.
        </t>
        <t>
The process to validate and normalize <em>given parameters</em> against an object's <em>formal parameters</em> to produce <em>actual parameters</em> is as follows.
        </t>
        <ol>
          <li>
            <t>
For each formal parameter, the processor performs the following:
            </t>
            <t>
If the given parameters are a list, the formal parameter is correlated to the list by its position in the formal parameters list.
If the given parameters list does not contain a corresponding position the given parameter is treated as the <tt>undefined</tt> value.
If the last formal parameter is a <xref target="sec-semtype-seq">Sequence</xref>, it can correlate with multiple given parameters.
            </t>
            <t>
If the given parameters are a map, the formal parameter is correlated to a map key by either its position (as an integer) or its name (as a text string) but not both.
If both integer and name are present in the given parameters map the procedure stops and is considered failed.
If the given parameters map does not contain a corresponding key the given parameter is treated as the <tt>undefined</tt> value.
            </t>
          </li>
          <li>
If any of the given parameters is not correlated with a formal parameter the procedure stops and is considered failed.
          </li>
          <li>
            <t>
For each correlated pair of formal parameter and given parameter(s), the processor performs the following:
            </t>
            <ol type="a">
              <li>
                <t>
If the given parameter is <tt>undefined</tt> (whether explicitly or implicitly) and the formal parameter defines a default value, that default is used as the actual parameter value.
If there is no default value, the actual parameter is left as the <tt>undefined</tt> value.
                </t>
              </li>
              <li anchor="step-convert-typedef">
                <t>
If the given parameter is a <tt>TYPEDEF</tt> and the object reference itself has a parameter, the given parameter is treated as the result of a <xref target="sec-proc-convert-typedef">type conversion</xref> to the semantic type of the TYPEDEF.
If the conversion fails this procedure stops and is considered failed.
                </t>
              </li>
              <li>
The given parameter is converted to an actual parameter using the type of the formal parameter in accordance with <xref target="sec-proc-convert"/>.
If the conversion fails, this procedure stops and is considered failed.
              </li>
            </ol>
          </li>
        </ol>
        <aside>
          <t>
The <tt>TYPEDEF</tt> conversion behavior in <xref format="none" target="step-convert-typedef">step 3.b</xref> acts as an explicit type cast within a given parameter which allows explicit tie-breaking for type unions in the corresponding formal parameter.
          </t>
        </aside>
        <t>
The actual parameters resulting from this procedure are intended to be able to be looked up by an implementation either by ordinal position in the formal parameters list or by unique name of the formal parameter.
It is an implementation matter whether or not to provide both accessing methods and the specifics of how, for example, and EDD or CTRL runtime accesses actual parameter values.
        </t>
        <t>
An implementation <bcp14>MAY</bcp14> perform deferred "lazy" processing of any of the above steps, causing a failure when the actual parameter value is needed.
One caveat about deferred processing is that it will not fail if the parameter is unused, which is not necessarily a problem but could mask other issues in whatever provided the given 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>
        <t>
This activity relies on an object reference value to have been dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters handled in accordance with <xref target="sec-proc-params"/>.
After that, each of the object types is treated differently as defined in the following subsections.
        </t>
        <section anchor="sec-proc-prod-const-var">
          <name>CONST and VAR Objects</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 objects takes the stored value from the object and augments it by label substitution based on the following:
          </t>
          <ol>
            <li>
The processor identifies all <tt>LABEL</tt> type within the stored value, descending into <xref target="sec-type-container">container</xref> contents and object reference parameter contents as necessary.
            </li>
            <li>
If any <tt>LABEL</tt> text is not present in the formal parameters of the value-producing object then this procedure stops and is considered failed.
            </li>
            <li>
For each <tt>LABEL</tt> value the corresponding actual parameter is not the <tt>undefined</tt> value, the <tt>LABEL</tt> value is replaced by the actual parameter.
            </li>
          </ol>
          <t>
This augmentation has no effect on the stored value, it occurs only in the produced value.
It is valid both for an actual parameter to have no substitution occur with its value and for an <tt>undefined</tt> actual value not be sued in substitution.
          </t>
        </section>
        <section anchor="sec-proc-exec-edd">
          <name>EDD Objects</name>
          <t>
For EDD objects, 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 an <xref target="sec-type-tbl">ARI Table</xref>.
          </t>
          <t>
The value production for these objects occurs outside of the Agent proper within an implementation of the EDD being produced from.
          </t>
          <t>
The context given to the implementation is the following:
          </t>
          <dl newline="true">
            <dt>Object Path:</dt>
            <dd>This gives visibility into the <tt>EDD</tt> object reference which was dereferenced during the production.</dd>
            <dt>Actual Parameters:</dt>
            <dd>The set of actual parameters used for the production.</dd>
            <dt>Result Type and 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="sec-auth-consid">author consideration</xref> to enforce that the produced value is consistent with the type of the object.
          </t>
        </section>
      </section>
      <section anchor="sec-proc-exec">
        <name>Execution</name>
        <t>
Within the AMM only two entities can be the target of an execution procedure: controls and macros.
Controls are executed by reference, while macros are executed both by value and by reference.
This means the execution target value <bcp14>SHALL</bcp14> match the <xref target="typedef-exec-tgt"><tt>exec-tgt</tt></xref> semantic type.
        </t>
        <t>
The procedure for executing is divided into phases to ensure that it does not fail due to invalid references or produced values after some controls have already been executed.
The phases are processed as follows:
        </t>
        <ol>
          <li>
            <t>
In the expansion phase the target value is processed to dereference all references, handle all parameters, and expand any produced values.
            </t>
            <t>
If the target is a literal value, the following is performed:
            </t>
            <ol type="a">
              <li>
The value needs to match the <xref target="typedef-mac"><tt>MAC</tt></xref> semantic type.
If it does not match, this procedure stops and is considered failed.
              </li>
              <li>
The processor then iterates through all elements of the MAC value and performs the expansion step on each in turn.
If any sub-expansion fails, this procedure stops and is considered failed.
              </li>
            </ol>
            <t>
If the target is an object reference, the following is performed:
            </t>
            <ol type="a">
              <li>
The value is dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters are handled in accordance with <xref target="sec-proc-params"/>.
If either fails, this procedure stops and is considered failed.
              </li>
              <li>
If the target object is a value-producing object, a value is produced in accordance with <xref target="sec-proc-prod"/>.
This includes substitution of any <tt>LABEL</tt> parameters within the value.
              </li>
              <li>
The processor then performs the expansion step on the produced value.
If sub-expansion fails, this procedure stops and is considered failed.
              </li>
            </ol>
            <t>
After expansion the target is either a dereferenced CTRL object, or a (possibly nested) macro expanded to contain only dereferenced CTRL objects.
            </t>
          </li>
          <li>
The processor then executes the top-level expanded value as either a macro in accordance with <xref target="sec-proc-exec-mac"/> or as a control in accordance with <xref target="sec-proc-exec-ctrl"/>
          </li>
        </ol>
        <section anchor="sec-proc-exec-mac">
          <name>Expanded MAC Values</name>
          <t>
The execution of an <xref format="title" target="typedef-mac"/> value after expansion is as follows:
          </t>
          <ol>
            <li>
              <t>
The processor iterates through all items of the expanded MAC in 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 the item is an expanded sub-macro and it is executed in accordance with this procedure.
              </t>
            </li>
          </ol>
          <t>
An 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>
        </section>
        <section anchor="sec-proc-exec-ctrl">
          <name>CTRL Objects</name>
          <t>
This activity relies on an object reference value to have been dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters handled in accordance with <xref target="sec-proc-params"/>.
          </t>
          <t>
The execution of a <xref format="title" target="sec-obj-ctrl"/> object occurs outside of the Agent proper within an implementation of the CTRL behavior.
          </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 Path:</dt>
            <dd>This gives visibility into the <tt>CTRL</tt> object reference which was dereferenced during the execution.</dd>
            <dt>Actual Parameters:</dt>
            <dd>The set of actual parameters augmented for the execution.</dd>
            <dt>Result Type and Storage:</dt>
            <dd>The result of the execution is placed here before completion.</dd>
          </dl>
          <t>
The initial state of the Result Storage is the <tt>null</tt> value.
          </t>
          <t>
If the execution fails, the result value <bcp14>SHALL</bcp14> be treated as the <tt>undefined</tt> value for the purposes of any subsequent reporting.
          </t>
          <aside>
            <t>
The <xref target="sec-agentadm">Agent 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>
          <t>
When an execution context is associated with a Manager endpoint and has a Correlator Nonce which is not <tt>null</tt>, after the execution of an individual CTRL has finished (whether successful or not) the processor <bcp14>SHALL</bcp14> generate a RPTSET to be sent to that associated Manager containing:
          </t>
          <dl>
            <dt>Correlator Nonce:</dt>
            <dd>Copied from the execution context</dd>
            <dt>Reference Time:</dt>
            <dd>The current timestamp</dd>
            <dt>Report List:</dt>
            <dd>
              <t>A single report containing:</t>
              <dl>
                <dt>Source:</dt>
                <dd>Copied from the CTRL reference which was executed</dd>
                <dt>Generation Time:</dt>
                <dd>The zero-duration</dd>
                <dt>Items:</dt>
                <dd>A single item copied from the result value, which is <tt>undefined</tt> if execution failed</dd>
              </dl>
            </dd>
          </dl>
          <t>
The generated RPTSET can then be aggregated by the processor in accordance with <xref target="sec-proc-rptset-agg"/>.
Whether or not any aggregation occurs is an implementation matter.
          </t>
        </section>
      </section>
      <section anchor="sec-proc-eval">
        <name>Evaluation</name>
        <t>
Within the AMM the following entities can be the target of an evaluation procedure: references to value-producing objects, OPERs, and TYPEDEFs and <tt>EXPR</tt> or <tt>SIMPLE</tt> literal values.
        </t>
        <aside>
          <t>
For the purposes of these procedures, it is important to distinguish between an <tt>EXPR</tt> <em>value</em> and a reference to a value-producing object which is typed to produce an <tt>EXPR</tt> value.
          </t>
        </aside>
        <t>
The procedure for evaluation is divided into phases to ensure that it does not fail due to invalid references or produced values after some expressions have already been evaluated.
The phases are processed as follows:
        </t>
        <ol>
          <li>
            <t>
In the expansion phase the target value is processed to dereference all references, handle all parameters, and expand any produced values.
            </t>
            <t>
If the target is a literal value, the following is performed:
            </t>
            <ol type="a">
              <li>
The value needs to match the <xref target="typedef-simple"><tt>SIMPLE</tt></xref> or <xref target="typedef-mac"><tt>EXPR</tt></xref> semantic type.
If it does not match, this procedure stops and is considered failed.
              </li>
              <li>
If the value is an EXPR, the processor then iterates through all elements of the EXPR value and performs the expansion step on each in turn.
If any sub-expansion fails, this procedure stops and is considered failed.
              </li>
            </ol>
            <t>
If the target is an object reference, the following is performed:
            </t>
            <ol type="a">
              <li>
The value is dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters are handled in accordance with <xref target="sec-proc-params"/>.
If either fails, this procedure stops and is considered failed.
              </li>
              <li>
If the target object is a value-producing object, a value is produced in accordance with <xref target="sec-proc-prod"/>.
This includes substitution of any <tt>LABEL</tt> parameters within the value.
              </li>
              <li>
The processor then performs the expansion step on the produced value.
If sub-expansion fails, this procedure stops and is considered failed.
              </li>
            </ol>
            <t>
After expansion the target is either a <tt>SIMPLE</tt> value, or a (possibly nested) expression expanded to contain only <tt>SIMPLE</tt> or <tt>ARITYPE</tt> values, or dereferenced OPER or TYPEDEF objects.
            </t>
          </li>
          <li>
            <t>
If the expanded evaluation target is already a <tt>SIMPLE</tt> value, then that is the result of the evaluation.
Otherwise, the expanded expression is evaluated in accordance with <xref target="sec-proc-eval-expr"/>.
            </t>
          </li>
        </ol>
        <section anchor="sec-proc-eval-expr">
          <name>Expanded EXPR Values</name>
          <t>
The reduction of an <xref format="title" target="typedef-expr"/> value after expansion is as follows:
          </t>
          <ol>
            <li>
Any sub-expressions are first reduced to their result values which are substituted back into the corresponding expression item.
If any sub-evaluation fails this procedure stops and is considered failed.
At this point the expression consists of only <tt>SIMPLE</tt> or <tt>ARITYPE</tt>values, the result value of sub-expression reduction, or dereferenced OPER or TYPEDEF objects.
            </li>
            <li>
An empty value stack is initialized for this reduction.
            </li>
            <li>
              <t>
The expression 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>ARITYPE</tt> value or dereferenced OPER or TYPEDEF object it is evaluated in accordance with <xref target="sec-proc-eval-aritype"/>, <xref target="sec-proc-eval-oper"/> or <xref target="sec-proc-eval-typedef"/> respectively.
If the evaluation fails, this procedure stops and is considered failed.
              </t>
              <t>
Otherwise, the item is pushed onto the stack.
              </t>
            </li>
            <li>
After RPN processing 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 <tt>OPER</tt> values, <tt>EXPR</tt> values, or <tt>VALUE-OBJ</tt> references are not evaluated.
          </t>
        </section>
        <section anchor="sec-proc-eval-oper">
          <name>OPER Objects</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 <tt>OBJECT</tt> value referencing a <xref format="title" target="sec-obj-oper"/> is as follows:
          </t>
          <ol>
            <li>
The value is dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters are handled in accordance with <xref target="sec-proc-params"/>.
If either fails, 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 Path:</dt>
                <dd>This gives visibility into the <tt>OPER</tt> object reference 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 <bcp14>SHALL</bcp14> propagate up to any expression evaluation.
          </t>
        </section>
        <section anchor="sec-proc-eval-typedef">
          <name>TYPEDEF Objects</name>
          <t>
This procedure applies only during the evaluation of a containing expanded expression; a TYPEDEF object cannot be evaluated in isolation.
The evaluation of a TYPEDEF 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 a TYPEDEF object is as follows:
          </t>
          <ol>
            <li>
If the <tt>TYPEDEF</tt> value itself has no parameters, the input value is popped from the stack.
If the <tt>TYPEDEF</tt> value itself has one parameter, the input value is that parameter.
If the <tt>TYPEDEF</tt> value itself has more than parameter, this procedure stops and is considered failed.
            </li>
            <li>
The result value is a <xref target="sec-proc-convert-typedef">type conversion</xref> on the input value.
If the conversion 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-aritype">
          <name>ARITYPE Values</name>
          <t>
This procedure applies only during the evaluation of a containing expanded expression; an ARITYPE value cannot be evaluated in isolation.
The evaluation of an ARITYPE is handled similarly to a TYPEDEF but with no possibility of a parameterized conversion.
          </t>
          <t>
The evaluation of an ARITYPE value is as follows:
          </t>
          <ol>
            <li>
The input value is popped from the stack.
            </li>
            <li>
The result value is a <xref target="sec-proc-convert">type conversion</xref> on the input value.
If the conversion fails this procedure stops and is considered failed.
            </li>
            <li>
The result value is pushed onto the stack.
            </li>
          </ol>
        </section>
      </section>
      <section anchor="sec-proc-rpt">
        <name>Reporting</name>
        <t>
The reporting activity operates on a single source value, which can be either a literal or an object reference value, and a single destination Manager identity.
        </t>
        <t>
Within the AMM the following entities have a reporting context: RPTT and EXPR values and CONST, EDD, and VAR objects.
The value-producing objects are reported-on by reference, while RPTT are reported-on both by value and by reference.
        </t>
        <t>
The procedure for reporting generates a RPTSET to be sent to the destination Manager containing:
        </t>
          <dl>
            <dt>Correlator Nonce:</dt>
            <dd>The <tt>null</tt> value</dd>
            <dt>Reference Time:</dt>
            <dd>The current timestamp</dd>
            <dt>Report List:</dt>
            <dd>
              <t>A single report containing:</t>
              <dl>
                <dt>Source:</dt>
                <dd>Copied from the source of this reporting activity</dd>
                <dt>Generation Time:</dt>
                <dd>The zero-duration value</dd>
                <dt>Items:</dt>
                <dd>A list of items, based on the source, as defined in one of the following subsections</dd>
              </dl>
            </dd>
          </dl>
          <t>
The generated RPTSET can then be aggregated by the processor in accordance with <xref target="sec-proc-rptset-agg"/>.
Whether or not any aggregation occurs is an implementation matter.
        </t>
        <t>
Each RPTSET generated by this activity, as opposed to <xref target="sec-proc-exec-ctrl">control execution</xref>, has nonce of <tt>null</tt> because they can be destined for an arbitrary Manager rather than whatever Manager caused an associated execution context.
This means that there is nothing visible to the Manager which can directly correlate to the execution which caused the reports to be generated.
        </t>
        <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-OBJ</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 anchor="sec-proc-rpt-valueref">
          <name>Value-Producing Objects</name>
          <t>
This activity relies on an object reference value to have been dereferenced in accordance with <xref target="sec-proc-deref"/> and its parameters handled in accordance with <xref target="sec-proc-params"/>.
          </t>
          <t>
The reporting on an object producing a value of any type is as follows:
          </t>
          <ol>
            <li>
The value is produced from the object 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 an AC which contains 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="sec-type-rptset">report</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>
      <section anchor="sec-proc-msgs">
        <name>Agent-Manager Message Handling</name>
        <section anchor="sec-proc-execset-agg">
          <name>Execution-Set Aggregation</name>
          <t>
Managers <bcp14>SHOULD</bcp14> aggregate multiple <xref format="title" target="sec-type-execset"/> values associated with the same Agent and Correlator Nonce into a single Execution-Set.
The aggregation <bcp14>MAY</bcp14> be based on a size limit (<em>e.g.</em>, number of targets), time limit, or an event (<em>e.g.</em>, network availability).
This avoids the overhead of transport and processing multiple executions on the same Agent, and due to the requirements in <xref target="sec-proc-execset-proc"/> makes no difference to (lack of) guarantees in execution order.
          </t>
        </section>
        <section anchor="sec-proc-execset-proc">
          <name>Execution-Set Processing</name>
          <t>
An Agent <bcp14>SHALL</bcp14> process an Execution-Set through the independent <xref format="title" target="sec-proc-exec"/> of each item in the target list.
Execution order is not guaranteed and failures on one target do not affect other target, so targets <bcp14>MAY</bcp14> be executed in any order or concurrently.
This is not the same behavior as the execution of a macro, where execution of items is ordered and a failure of any execution causes subsequent items to not be executed.
          </t>
        </section>
        <section anchor="sec-proc-rptset-agg">
          <name>Reporting-Set Aggregation</name>
          <t>
Agents <bcp14>SHOULD</bcp14> aggregate multiple <xref format="title" target="sec-type-rptset"/> values associated with the same Manager and Correlator Nonce into a single Reporting-Set.
The aggregation <bcp14>MAY</bcp14> be based on a size limit (<em>e.g.</em>, number of reports or number of total report items), time limit, or an event (<em>e.g.</em>, network availability or power-saving wake-up).
This avoids the overhead of transport and processing multiple messages on a Manager and improves timestamp compression in the reports, but it does require that all of the items are associated with the same manager and nonce.
          </t>
        </section>
        <section anchor="sec-proc-rptset-proc">
          <name>Reporting-Set Processing</name>
          <t>
A Manager <bcp14>SHALL</bcp14> process each report within a Reporting-Set independently.
Failures in processing any one report do not affect other reports, so reports <bcp14>MAY</bcp14> be processed in any order or concurrently.
After using a Report Template to correlate report items with source objects, a Manager <bcp14>SHALL</bcp14> treat each (timestamp, object, item value) tuple independently from its containing Reporting-Set or Report.
          </t>
        </section>
      </section>
      <section anchor="sec-proc-type-match">
        <name>Type Matching</name>
        <t>
Type matching is done through pattern matching and does not affect the AMM value.
AMM values are not strictly typed, and as long as an AMM value matches the pattern for a type, that value can be used where that type is needed.
If there is any overlap in the patterns for different semantic types, then there will be ambiguity in the sense that the same value can be used as different types.
        </t>
        <section>
          <name>Built-In Types</name>
          <t>
The matching of a built-in literal type to any object reference value <bcp14>SHALL</bcp14> be considered to fail.
The built-in <tt>LITERAL</tt> type <bcp14>SHALL</bcp14> match any typed or untyped literal value.
        </t>
          <t>
The matching of a built-in literal type to a typed literal value as follows:
        </t>
          <ol>
            <li>If the value type differs from the built-in type, the match fails.</li>
            <li>Otherwise, the literal type is matched to the value primitive as defined below.</li>
          </ol>
          <t>
The matching of a built-in literal type to an untyped literal value as follows:
        </t>
          <dl>
            <dt><tt>NULL</tt>:</dt>
            <dd>This type only matches the <tt>null</tt> primitive value.</dd>
            <dt><tt>BOOL</tt>:</dt>
            <dd>This type only matches the <tt>true</tt> and <tt>false</tt> primitive values.</dd>
            <dt><tt>BYTE</tt>:</dt>
            <dd>This type only matches <tt>uint</tt> primitive values in the domain 0 to 2^8-1 inclusive.</dd>
            <dt><tt>INT</tt>:</dt>
            <dd>This type only matches <tt>int</tt> primitive values in the domain -2^31 to 2^31-1 inclusive.</dd>
            <dt><tt>UINT</tt>:</dt>
            <dd>This type only matches <tt>uint</tt> primitive values in the domain 0 to 2^32-1 inclusive.</dd>
            <dt><tt>VAST</tt>:</dt>
            <dd>This type only matches <tt>int</tt> primitive values in the domain -2^63 to 2^63-1 inclusive.</dd>
            <dt><tt>UVAST</tt>:</dt>
            <dd>This type only matches <tt>uint</tt> primitive values in the domain 0 to 2^64-1 inclusive.</dd>
            <dt><tt>REAL32</tt>:</dt>
            <dd>This type only matches <tt>float</tt> primitive values in the domain of a 32-bit <xref target="IEEE.754-2019"/> floating point number.</dd>
            <dt><tt>REAL64</tt>:</dt>
            <dd>This type only matches <tt>float</tt> primitive values in the domain of a 64-bit <xref target="IEEE.754-2019"/> floating point number.</dd>
            <dt><tt>TEXTSTR</tt>:</dt>
            <dd>This type matches <tt>tstr</tt> primitive values.</dd>
            <dt><tt>BYTESTR</tt>:</dt>
            <dd>This type matches <tt>bstr</tt> primitive values.</dd>
            <dt><tt>TP</tt>:</dt>
            <dd>This type matches <tt>int</tt> primitive values, and <tt>float</tt> values truncated to fixed precision.</dd>
            <dt><tt>TD</tt>:</dt>
            <dd>This type matches <tt>int</tt> primitive values, and <tt>float</tt> values truncated to fixed precision.</dd>
            <dt><tt>LABEL</tt>:</dt>
            <dd>
This type matches <tt>int</tt> and <tt>tstr</tt> values, where the text also matches the <tt>id-text</tt> ABNF rule of <xref target="sec-obj-metadata"/>.
Implementations <bcp14>MAY</bcp14> relax or cache the matching condition for <tt>LABEL</tt> text values to avoid extra processing.
            </dd>
            <dt><tt>CBOR</tt>:</dt>
            <dd>
This type matches <tt>bstr</tt> primitive values that are non-empty and contain a well-formed CBOR item.
Implementations <bcp14>MAY</bcp14> relax or cache the well-formed-ness condition for <tt>CBOR</tt> values to avoid extra processing.
            </dd>
            <dt><tt>ARITYPE</tt>:</dt>
            <dd>This type matches <tt>int</tt> and <tt>tstr</tt> values.</dd>
          </dl>
          <t>
Relaxing some built-in type conditions is done at the risk that users will supply invalid values that will not be caught until significant other processing has already occurred.
If an Agent implementation relaxes these conditions it is <bcp14>RECOMMENDED</bcp14> to use only Managers which enforce the conditions in order to block invalid values before they arrive at an Agent.
          </t>
          <t>
The matching of a built-in object reference type to any literal value <bcp14>SHALL</bcp14> be considered to fail.
The built-in <tt>OBJECT</tt> type <bcp14>SHALL</bcp14> match any object reference values.
        </t>
          <t>
The matching of a built-in object reference type to an object reference value <bcp14>SHALL</bcp14> be considered to succeed if the object reference value Type ID is identical to the type.
        </t>
        </section>
        <section>
          <name>Semantic Types</name>
          <t>
The matching of an input value to each class of <xref target="sec-type-semantic">semantic type</xref> is as follows:
          </t>
          <dl>
            <dt>Named Type Use:</dt>
            <dd>Matching for a named type use <bcp14>SHALL</bcp14> be identical to the matching for the type being named, whether that is TYPEDEF or built-in.</dd>
            <dt>Uniform List:</dt>
            <dd>
Matching for this class <bcp14>SHALL</bcp14> require the value to be an AC, with an item count optionally constrained by minimum and maximum size from the type, and with each item of the AC itself matching the specific sub-type for the list.
            </dd>
            <dt>Diverse List:</dt>
            <dd>
Matching for this class <bcp14>SHALL</bcp14> require the value to be an AC, with an item count optionally constrained by minimum and maximum size from the type, and with each item of the AC itself matching the specific sub-type or sequence for the list.
            </dd>
            <dt>Uniform Map:</dt>
            <dd>
Matching for this class <bcp14>SHALL</bcp14> require the value to be an AM, with a size optionally constrained by minimum and maximum size from the type, and with each key and value of the AM itself matching the specific respective sub-type for the map.
            </dd>
            <dt>Table Template:</dt>
            <dd>
Matching for this class <bcp14>SHALL</bcp14> require the value to be an TBL, with a column count matching exactly the number of columns present in the table template and each row containing items matching the column-specific sub-type for the template.
If the table template contains a limit on minimum or maximum size, the row count <bcp14>SHALL</bcp14> conform with those limits to match.
If the table template contains a key column or unique column-set then all rows <bcp14>SHALL</bcp14> satisfy the uniqueness of those constraints to match.
            </dd>
            <dt>Type Union:</dt>
            <dd>
              <t>The matching for a type union <bcp14>SHALL</bcp14> be performed as follows:</t>
              <ol>
                <li>
The underlying literal types usable with a semantic type are obtained by recursively flattening the type union(s) down to built-in types and removing duplicate built-in types after the first instance of them.
This defines a list of acceptable built-in types for the result.
                </li>
                <li>
The input value is matched to each built-in type in the list, and the first successful match results in a success of matching the whole semantic type.
If none of the built-in types can successfully match the input value, the match is considered failed.
                </li>
                <li>
If successful, the specific base type which matched is also part of the result of this procedure.
                </li>
              </ol>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-proc-convert">
        <name>Type Conversion</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, type conversion is performed implicitly by the Agent while other cases the conversion 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 conversion is for numeric operators in the <xref target="sec-agentadm-opers">Agent ADM</xref>.
        </t>
        <t>
A special case which applies to all conversions is that the <tt>undefined</tt> value is passed-through as the result value unconditionally.
        </t>
        <section anchor="sec-proc-convert-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 except <tt>undefined</tt> as truthy.
          </t>
          <ul>
            <li>The <tt>null</tt> value (of <tt>NULL</tt>)</li>
            <li>The <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> (note that <tt>CBOR</tt> cannot be empty and is excluded here)</li>
            <li>Zero value of <tt>TD</tt> (note that <tt>TP</tt> is excluded here)</li>
          </ul>
          <t>
When casting a value to <tt>BOOL</tt> type, the processor <bcp14>SHALL</bcp14> use the result value <tt>false</tt> if the original value is falsey and <tt>true</tt> if the original value is not <tt>undefined</tt>.
The <tt>undefined</tt> value is passed-through for a boolean conversion (just like other types).
          </t>
        </section>
        <section anchor="sec-proc-convert-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 <bcp14>SHALL</bcp14> perform the following:
          </t>
          <ol>
            <li>If the input is one of the <tt>FLOAT</tt> types and is not finite, the conversion 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 conversion 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 <bcp14>SHALL</bcp14> perform the following:
          </t>
          <ol>
            <li>If the input value is outside the domain of the output type, the conversion is considered failed.</li>
          </ol>
          <section anchor="sec-proc-convert-numeric-promote">
            <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.
Converting to a promoted type is called an "up" conversion, and from a promoted type a "down" conversion.
            </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-conversion 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 <bcp14>SHALL</bcp14> be defined as the smallest up-conversion that will accommodate the input types, as indicated in <xref target="tab-numeric-promotion"/>.
This is almost a strict ordering except for the conversion 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-convert-typedef">
          <name>Semantic Types</name>
          <t>
The converting of an input value to each class of <xref target="sec-type-semantic">semantic type</xref> is as follows.
Similar to built-in type conversion, each semantic type class has the potential to change a value as needed to conform to type limitations.
          </t>
          <dl>
            <dt>Named Type Use:</dt>
            <dd/>
            <dt>Uniform List:</dt>
            <dd>
Converting to this class <bcp14>SHALL</bcp14> require the value to be an AC; if the input is not an AC this procedure stops and is considered failed.
If the uniform list contains limits on the number of items and the value does not satisfy those limits this procedure stops and is considered failed.
For each item of the input value the uniform sub-type <bcp14>SHALL</bcp14> be used to convert to a corresponding output value; if any of those conversions fail this procedure stops and is considered failed.
            </dd>
            <dt>Diverse List:</dt>
            <dd>
Converting to this class <bcp14>SHALL</bcp14> require the value to be an AC; if the input is not an AC this procedure stops and is considered failed.
If the diverse list contains limits on the number of items and the value does not satisfy those limits this procedure stops and is considered failed.
For each item of the input value the corresponding diverse list sub-type <bcp14>SHALL</bcp14> be used to convert to a corresponding output value; if any of those conversions fail this procedure stops and is considered failed.
            </dd>
            <dt>Uniform Map:</dt>
            <dd>
Converting to this class <bcp14>SHALL</bcp14> require the value to be an AM, if the input is not an AC this procedure stops and is considered failed.
If the uniform map contains limits on the number of pairs and the value does not satisfy those limits this procedure stops and is considered failed.
For each key--value pair of the input value the uniform sub-types <bcp14>SHALL</bcp14> be used to convert to a corresponding output pair; if any of those conversions fail this procedure stops and is considered failed.
If the conversion results in any duplicate keys this procedure stops and is considered failed.
            </dd>
            <dt>Table Template:</dt>
            <dd>
Converting to this class <bcp14>SHALL</bcp14> require the value to be a TBL, if the input is not an TBL this procedure stops and is considered failed.
If the table template contains limits on the number of rows and the value does not satisfy those limits this procedure stops and is considered failed.
If the value contains a different number of columns from the table template this procedure stops and is considered failed.
For each item across each row of the input the corresponding column sub-type <bcp14>SHALL</bcp14> be used to convert to a corresponding output table item; if any of those conversions fail this procedure stops and is considered failed.
            </dd>
            <dt>Type Union:</dt>
            <dd>
              <t>
Converting a value for a type union <bcp14>SHALL</bcp14> be performed as follows:
              </t>
              <ol>
                <li>
The underlying built-in types usable with a semantic type are obtained by recursively flattening type union(s) down to built-in types and removing duplicate built-in types after the first instance of them.
This defines a priority list of acceptable built-in 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-union-convert-match">
The input value is first matched against each type in the list, in order.
If any type does match the value, the input is taken as the result value.
If no types directly match, the procedure continues to the next step.
                </li>
                <li anchor="step-union-convert-subconvert">
The input value is attempted to be converted to each type in the list, in order.
The first successful conversion is taken as the the result value.
If none of the built-in types can successfully convert the input value, this procedure stops and is considered failed.
                </li>
              </ol>
              <aside>
                <t>
Because the processing in Steps <xref format="counter" target="step-union-convert-match"/> and <xref format="counter" target="step-union-convert-subconvert"/> could successfully match multiple built-in 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>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-proc-compact">
        <name>Value Compacting</name>
        <t>
The procedures in this section allow AMM values, both typed literals and parameterized  object references, to be compacted by eliding specific information based on the context of an associated semantic type or object formal parameters.
The context for this compacting activity is taken from the model in which the specific values are being used.
        </t>
        <t>
When an object formal parameter, table template column, or report template item is known to have a semantic type that will match and convert from either a typed or an untyped literal with the same result value, the type of the literal can be elided without affecting the result.
Another way of looking at this compacting is that when a literal 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>
Even in the absence of an associated model, there are compacting rules that can be followed to elide unneeded information for specific built-in literal types.
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>
        <section anchor="sec-proc-compact-type">
          <name>Context Type</name>
          <t>
The context type for an <xref target="sec-obj-metadata">object formal parameter</xref> <bcp14>SHALL</bcp14> be the type of that parameter.
The context type for a <xref target="sec-semtype-tblt">table template column</xref> <bcp14>SHALL</bcp14> be the type of that column.
The context type for a <xref target="typedef-rptt">report template item</xref> which contains a <xref target="typedef-valueobj"><tt>VALUE-OBJ</tt></xref> reference <bcp14>SHALL</bcp14> be the produced type of that referenced object.
All other report template items, which must be <tt>EXPR</tt> literals, do not have an associated context type.
          </t>
        </section>
        <section>
          <name>Literal Values</name>
          <t>
When compacting a literal value based on a context, the processor performs the following:
          </t>
          <ol>
            <li>
If the value has type <tt>NULL</tt>, <tt>BOOL</tt>, <tt>TEXTSTR</tt>, or <tt>BYTESTR</tt> the type is removed from the value and this procedure is finished.
These types have unambiguous, unique value representation.
            </li>
            <li>
The associated context type is determined based on the rules of <xref target="sec-proc-compact-type"/>.
If there is no such context type, this procedure is finished with the value unchanged in this step.
            </li>
            <li>
If removing the type from the value has no effect on how it would be <xref target="sec-proc-convert">converted</xref> to the context type, the type is removed from the value.
            </li>
            <li>
If the value is one of the <xref target="sec-type-container">containers</xref> and the context type is a semantic type for that container (<em>i.e.</em>, not just the literal type <tt>AC</tt>, <tt>AM</tt>, or <tt>TBL</tt>), each of the constituent values is compacted based on the corresponding item of the context semantic type.
            </li>
          </ol>
        </section>
        <section>
          <name>Object Reference Values</name>
          <t>
When compacting an object reference value based on a context object, the processor performs the following:
          </t>
          <ol>
            <li>
If the reference value contains given parameters in the form of a map and can be converted to a list with no change in the actual parameters (in accordance with <xref target="sec-proc-params"/>), the parameters are converted to a list.
Eliding the map keys will always compact the given parameters.
            </li>
            <li>
Each of the given parameter values is itself compacted based on the corresponding formal parameter context.
            </li>
          </ol>
        </section>
      </section>
    </section>
    <section anchor="sec-auth-consid">
      <name>ADM Author Considerations</name>
      <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>
      <section anchor="sec-auth-consid-const">
        <name>CONST Definitions Have Life Cycles</name>
        <t>
All CONST objects <bcp14>SHOULD</bcp14> be given names and behaviors that reflect the requirements of <xref target="sec-obj-const"/>, specifically that the stored and produced value cannot change after it is initially defined in a model.
This does not, however, mean that a model needs to contain the same CONST definitions for its entire lifetime.
        </t>
        <t>
When new CONST objects are needed they can be added to a model without any additional consideration, they will just be given a unique name and enumeration.
When a CONST object needs to be superseded, the old CONST object can have its status changed to "deprecated" or "obsolete" and a new object defined to hold the new value (see <xref target="sec-auth-consid-life-cycle"/>).
If this kind of CONST life cycle management is done in an ADM it would likely require software update on the Agent but if it is done in an ODM it can be done during normal continuous runtime.
        </t>
      </section>
      <section anchor="sec-auth-consid-var">
        <name>VAR Definitions Need to Consider State Changes</name>
        <t>
All VAR objects <bcp14>SHOULD</bcp14> be given names and behaviors that reflect the requirements of <xref target="sec-obj-var"/>, specifically that variables are completely Manager-controllable within their defined <xref target="sec-type-semantic">semantic type constraints</xref>.
Application behavior <bcp14>SHOULD</bcp14> be reasonable for any VAR value state that <xref target="sec-proc-type-match">matches</xref> its associated semantic type.
A "reasonable" application behavior does not need to be successful in its application-domain processing but it does need to accept the VAR state for such processing.
Application behavior <bcp14>SHOULD</bcp14> be reasonable when responding to changes of VAR value state over time.
A "reasonable" application can impose hysteresis timeouts to avoid excessive processing if the state of a VAR changes frequently.
        </t>
      </section>
      <section anchor="sec-auth-consid-edd">
        <name>EDD Definitions Need Nilpotency</name>
        <t>
All EDD objects <bcp14>SHOULD</bcp14> be given names and behaviors that reflect the nilpotency requirements of <xref target="sec-obj-edd"/>.
Agent behavior <bcp14>SHOULD</bcp14> be reasonable even if duplicate and concurrent EDD value production is performed.
        </t>
      </section>
      <section anchor="sec-auth-consid-ctrl">
        <name>CTRL Definitions Need Idempotency</name>
        <t>
All CTRL objects <bcp14>SHOULD</bcp14> be given names and behaviors that reflect the idempotency requirements of <xref target="sec-obj-ctrl"/>.
For example the term "ensure" is preferable to "add or modify".
Likewise "discard" is encouraged instead of "remove if necessary".
        </t>
        <t>
Agent behavior <bcp14>SHOULD</bcp14> be reasonable even if duplicate and concurrent CTRL executions are performed.
Consider an "add-" CTRL that fails if a value already exists as opposed to an "ensure-" CTRL that checks a precondition and stops, thus guaranteeing idempotency.
        </t>
      </section>
      <section anchor="sec-auth-consid-oper">
        <name>OPER Definitions Need Nilpotency</name>
        <t>
All OPER objects <bcp14>SHOULD</bcp14> be given names and behaviors that reflect the nilpotency requirements of <xref target="sec-obj-oper"/>.
For example, evaluating an OPER cannot have visible side effects beyond trivial activities such as logging or accounting.
Agent behavior <bcp14>SHOULD</bcp14> be reasonable even when concurrent OPER evaluation is performed.
        </t>
      </section>
      <section anchor="sec-auth-consid-const-var-edd">
        <name>Choosing between CONST, VAR, or EDD</name>
        <t>
The purpose of associated data and expected behavior of values over time are the main influences of which value-producing object type to use for different purposes.
        </t>
        <t>
CONST objects are recommended for data which are expected to have a long use lifetime and in situations where synchronization between Agent and Manager is difficult or impossible.
When storing RPTT or MAC values on an Agent, using a CONST object ensures that any time the value is needed within an execution the object reference will produce the same known value.
For example, any time a report is received with a source referencing a CONST object the associated RPTT can only have one possible content (meaning one possible interpretation of the report items).
When a new value is needed in this case, the old CONST object can have its status changed to "deprecated" or "obsolete" and a new object defined to hold the new value.
        </t>
        <t>
VAR objects are recommended for data which are expected to have shorter lifetime or need to be influenced by self-modifying logic on the Agent itself.
When storing RPTT or MAC values in a VAR object, it requires some synchronization between Agent and Manager.
For example, any time a report is received with a source referencing a VAR object the Manager needs precise state history to know what the stored RPTT value of the VAR was when the report was generated.
The benefit of using a VAR in this case is that a single object can be used to store a time-varying value (in either an ADM or an ODM with no change in behavior).
VAR objects are also useful for storing threshold or limit values for state-based rules and future in-Agent alarm-condition logic.
        </t>
        <t>
EDD objects are necessary when data originates from an application outside the Agent (as its name implies) but can also be used when it is more convenient to have application-controlled, possibly complex, values than try to manage the state of a VAR object.
It is perfectly allowed that a dynamically constructed RPTT value is produced by an EDD and used for reporting.
Doing so just requires the Manager receiving the report to be able to have precise information about what the RPTT content would have been at the time of reporting.
EDD objects can also be coupled with one or more CTRL objects to enforce more complex state limitations than one an individual VAR with a single semantic type (see <xref target="sec-auth-consid-var"/>).
        </t>
        <t>
For example, a set of inter-related EDDs can be defined to allow introspecting the internal state of some application algorithm while an associated parameterized CTRL object is used to alter the configuration of the algorithm, which then alters the state, and finally is reflected in changes to the EDD values.
Rather than attempting to treat the configuration inputs as independently changing VAR objects, the CTRL parameters are updated together by the application so that the entire set of configuration is either considered valid or not.
If inputs were taken from separate VAR objects, there are likely to be intermediate states when some (but not all) VAR states are altered and the whole ensemble is invalid.
By using the CTRL parameters as input, the modification becomes atomic from the Manager's perspective when the CTRL execution finishes.
        </t>
      </section>
      <section anchor="sec-auth-consid-enum-ident">
        <name>Choosing a Semantic Enumeration or an IDENT Hierarchy</name>
        <t>
The choice between using a static definition of enumerated values within a <xref format="title" target="sec-semtype-use"/> (constraining an integer built-in type) or using an extensible <xref target="sec-obj-ident">IDENT object</xref> hierarchy depends on several factors.
        </t>
        <dl>
          <dt>Static or Extensible:</dt>
          <dd>
This consideration is about how many enumerated values are currently known and how much it is expected to grow in the future.
A semantic enumeration is useful when the set of values is small, well-known, and not likely to be expanded upon.
An IDENT hierarchy is more useful when an initial set of values is known but expected to grow in unknown ways in the future.
          </dd>
          <dt>Localized or Distributed:</dt>
          <dd>
This consideration is about how localized the choices are; whether or not a single model can define all options or whether some options need to be defined across multiple models.
An IDENT hierarchy allows definitions of choices to span across multiple models and be defined at different times.
It also allows some choices to be made optional by being present in models which will not be implemented in some Agents.
Knowing which models (and which features) are implemented in an Agent would determine which IDENT choices are available.
          </dd>
          <dt>Parameterized options:</dt>
          <dd>
This consideration is whether or not there are secondary options related to each enumerated value.
An IDENT hierarchy allows object-specific parameters to be associated with all non-abstract IDENTs (see <xref target="sec-auth-consid-ident-params"/>) which allows a form of type safety for IDENT-enumerated choices with parameters.
A static enumeration of choices does not allow for per-choice parameters.
          </dd>
        </dl>
        <t>
For example, a model which needs to identify a unidirectional link as either being outgoing from or incoming to a node can simply use a static enumeration of two possible values.
The value itself then takes the form of one of the enumerated integer choices with a specific human-friendly name associated with each one, and the encoding will be very concise.
The options in this case are limited by design and cannot be expanded upon without changing the meaning of the type.
        </t>
        <t>
In another example, a model needs to make use of a transport endpoint address but does not want to be limited to a single possible transport protocol or addressing scheme.
In this case, the model can define (or import) an abstract base IDENT object and use a value type of an IDENT derived from that base object.
The value then takes the form of an object reference (to a non-abstract, derived IDENT), this is less concise than a single integer but is completely open-ended for possible future support.
The model can itself define some specific derived IDENT objects or defer that to other, transport-related models.
        </t>
      </section>
      <section>
        <name>Choosing a Table Template or a Uniform List</name>
        <t>
The choice between using a <xref format="title" target="sec-semtype-tblt"/> or a <xref format="title" target="sec-semtype-ulist"/> of possibly complex structures depends on several factors.
        </t>
        <dl>
          <dt>Static set of Fields:</dt>
          <dd>
            <t>
If the number of fields and and type of each field of a structure is known at design time, a table template is a simpler and easier to understand by mapping each field to a table column.
The table template is restrictive, similar to the semantic enumeration, in that the columns of a single template are static and cannot be expanded upon (without creating a new semantic type, see <xref target="sec-auth-consid-life-cycle"/>).
            </t>
          </dd>
          <dt>Row Variability:</dt>
          <dd>
            <t>
If there is only a single field or a type-variable field which is more suitable to a <xref target="sec-auth-consid-ident-params">parameterized IDENT</xref> then a uniform list is more suitable.
This especially applies in a situation where the items of the list need to be extensible, which the IDENT hierarchy can handle easily.
The drawback to using an IDENT hierarchy for each item is the complexity of specifying the desired schema and for users to understand how the model works.
            </t>
          </dd>
        </dl>
        <t>
For example, if an application manages a list of entities, each with uniform fields and types, those fields can be converted into columns of a table template and the state of those entities can be encoded all together as a table value.
        </t>
      </section>
      <section anchor="sec-auth-consid-tables">
        <name>Use Tables for Related Data</name>
        <t>
In cases where multiple EDD or VAR values are likely to be produced and evaluated together, that information <bcp14>SHOULD</bcp14> be placed in an <xref target="sec-semtype-tblt">Table Template</xref> semantic type within a single EDD or VAR rather than defining multiple independent EDD and/or 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 increased transport and processor utilization and the potential for non-synchronized access across multiple value productions or when modifying VAR state (see <xref target="sec-auth-consid-var"/>).
        </t>
      </section>
      <section anchor="sec-auth-consid-typedef">
        <name>Use Common TYPEDEFs and Semantic Types</name>
        <t>
Even when values in EDDs or VARs are simple integer counters or gauges, it is strongly <bcp14>RECOMMENDED</bcp14> for ADM authors to make use of semantic types in pre-existing TYPEDEF objects (within shared-use ADMs).
This is preferred over either creating their own semantic types at the point of use or using simple built-in types without any documented semantics.
Both of those alternatives are worse for maintenance and likely to be confusing to users of the ADM, both on the Manager side and the Agent implementation side.
        </t>
      </section>
      <section anchor="sec-auth-consid-ident-params">
        <name>IDENT Objects with Parameters</name>
        <t>
For simple uses of an IDENT hierarchy, the name and enumeration of each non-abstract IDENT function as a sort of extensible choice, where each non-abstract object represents one possible choice and a reference to that object is the AMM value for the choice.
This is a valuable use of an IDENT hierarchy but not the only possible one.
Because IDENT objects can each define formal parameters and IDENT references can use those with given parameters, it is possible to use non-abstract IDENT object to function as data structures.
        </t>
        <t>
A trivial way to use parameterized IDENT objects is to define an IDENT with parameters but without any base objects.
This enables a single AMM value (from any <xref target="sec-conops-values">value-producing object</xref> or within an expression) to contain an IDENT reference which itself contains given parameters associated with the object.
        </t>
        <t>
A more complex way to use parameterized IDENT objects is to construct a hierarchy using an abstract base IDENT (which itself cannot be parameterized), with any number of intermediate abstract derived IDENTs, and finally a set of non-abstract derived IDENTs having form parameters specific to that object's meaning as a choice.
        </t>
        <t>
For example, an abstract "base-transport" object defined in a base model could have non-abstract derived IDENTS, each defined in a separate layer-specific model, including the following:
        </t>
        <ul>
          <li>An "ethernet-transport" with parameters of an Ethernet MAC address</li>
          <li>An "ip-transport" with parameters of an IP address and port number</li>
          <li>A "bpv7-transport" with parameters of an Endpoint ID URI</li>
        </ul>
        <t>
Because each of those parameters it itself typed and type-checked, this kind of structure allows a Manager to perform type checking before allowing values to be sent to an Agent, and allows a general-purpose Agent to validate values before they are passed up to an application or used to change the state of a VAR.
        </t>
      </section>
      <section anchor="sec-auth-consid-const-var-params">
        <name>CONST and VAR Objects with Parameters</name>
        <t>
Unlike the behavior of parameterized EDD objects, for which parameters can be used to arbitrarily affect produced values, the value production procedures for CONST and VAR objects (defined in <xref target="sec-proc-prod-const-var"/>) allow parameters to "flow down" into stored values containing <tt>LABEL</tt> parameters.
This allows things like CONST report templates to contain simple parameters to avoid the need to define several different, but mostly similar, report template values across multiple objects.
        </t>
      </section>
      <section anchor="sec-auth-consid-edd-params">
        <name>EDD Objects with Parameters</name>
        <t>
Parameters provide a powerful mechanism for expressing associative look-ups of EDD data.
EDDs <bcp14>SHOULD</bcp14> be parameterized when the definition of the EDD is dependent upon run-time information.
        </t>
        <t>
For example, if requesting the number of bytes through a specific endpoint, the construct <tt>num_bytes("endpoint_name")</tt> 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.
        </t>
        <t>
Parameters incur transport and processing costs (see <xref target="sec-proc-params"/>) 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.
         </t>
        <t>
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>
        <table>
          <name>Example Parameterized EDDs</name>
          <thead>
            <tr>
              <th>Parameterized Uses</th>
              <th>Non-Parameterized Uses</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>./EDD/num_bytes_by_pri(low)</tt>
              </td>
              <td>
                <tt>./EDD/num_bytes_by_low_pri</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>./EDD/num_bytes_by_pri(med)</tt>
              </td>
              <td>
                <tt>./EDD/num_bytes_by_med_pri</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>./EDD/num_bytes_by_pri(high)</tt>
              </td>
              <td>
                <tt>./EDD/num_bytes_by_high_pri</tt>
              </td>
            </tr>
          </tbody>
        </table>
        <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>
      </section>
      <section anchor="sec-auth-consid-oper-params">
        <name>OPER Objects with Parameters</name>
        <t>
For common uses of OPER objects, the functional behavior performed by the OPER requires only its operands to produce a result.
For complex cases, though, an OPER can be defined to have formal parameters which influence its functional behavior.
        </t>
        <t>
Giving parameters to an OPER is a trade between less complex individual OPER definitions and consolidating behavior into a single parameterized definition.
Parameters can increase expressiveness of a small number of objects, but can also lead to confusing semantics or overloaded objects which could produce the same behaviors by distributing over several, more specialized OPER objects.
        </t>
        <t>
One example is an OPER which has a parameter determining the number of operands to sum together.
While the agent default "numeric addition" OPER is purely a binary function, a general purpose summation OPER can be defined which takes a parameter to determine the number of operands to pop from the evaluation stack and sum together.
        </t>
        <t>
Another example is an OPER which has parameter(s) defining algorithmic configuration separate from the operand(s) which are treated as algorithmic input.
The key distinction is that the given parameter values are treated as constants from the perspective of the expression evaluation and <em>cannot</em> be taken from the evaluation stack.
        </t>
      </section>
      <section anchor="sec-auth-consid-life-cycle">
        <name>Object Life Cycle</name>
        <t>
Within a single model (whether ADM or ODM) each object has a well-defined life cycle described below.
        </t>
        <ol>
          <li>At a specific model revision an object comes into existence with a "current" status.</li>
          <li>At a later revision an object can change to "deprecated" status, which means it continues to exist but hints to users that this will change in the future.</li>
          <li>Finally, a later revision the object will change to "obsolete" status and become unusable, the model definition will continue to exist for historical reference to a user but it has no further meaning to an Agent.</li>
        </ol>
        <t>
This single-object life cycle can be combined across multiple objects to support transitioning of behavior or structure across revisions of a single model.
For example, an outdated TYPEDEF or IDENT object can be deprecated in the same revision that a replacement object is defined (with a descriptive note in the outdated object pointing to its replacement) and later on the outdated object can be made obsolete and no longer usable.
This behavior enables some level of adaptation and growth in a model without need to use more complex mechanisms of model augmentation, where being able to interpret a single structure requires information across several different models.
        </t>
      </section>
      <section anchor="sec-auth-consid-visibility">
        <name>State Visibility</name>
        <t>
When configuration or state is managed using VAR objects, within either ADMs or ODMs, there is a built-in Agent ability to both alter and inspect the stored value of the object.
This provides a large benefit to the Manager side for simple activities such as testing or diagnostic behaviors in Applications which make use of the VAR values.
        </t>
        <t>
Unlike the use of VAR objects, which are managed by the Agent, CTRLs will typically have side effects in application state which are outside of the Agent proper.
When an ADM provides CTRL objects for changing application configuration or state, it is <bcp14>RECOMMENDED</bcp14> that the same ADM also provide EDD objects for inspecting the resulting application state.
This introspection ability might not be needed operationally, but for testing and diagnostics it is important.
        </t>
      </section>
    </section>
    <section anchor="IANA">
      <name>IANA Considerations</name>
      <t>
This document does not make any changes to IANA registries.
      </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>
         The Access Control Lists (ACLs) functionality presented in this
         document would be implemented separately from network security
         mechanisms.
      </t>
      <t>
         ACL groups are expected to be associated with Managers. However, the
         form of Manager identification must be provided by separate transport-specific 
         ADMs. The AMM provides no general purpose identifier, such as peer 
         name and address, that would be required to uniquely describe each Manager.
      </t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml-misc/reference.IEEE.754-2019.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3629.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3339.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7950.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.8341.xml"/>
      </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-DTNMA" target="https://www.iana.org/assignments/TBA/">
          <front>
            <title>Delay-Tolerant Networking Management Architecture (DTNMA) Parameters</title>
            <author>
              <organization>IANA</organization>
            </author>
            <date/>
          </front>
        </reference>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2578.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2580.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6991.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7942.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.8610.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.9675.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-dtn-ari.xml"/>
        <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-dtn-amp.xml"/>
        <reference anchor="github-dtnma-tools" target="https://github.com/JHUAPL-DTNMA/dtnma-ace">
          <front>
            <title>A reference implementation of the DTN Management Architecture (DTNMA) Agent and related Tools</title>
            <author>
              <organization abbrev="JHU/APL">The Johns Hopkins University Applied Physics Laboratory</organization>
            </author>
            <date/>
          </front>
        </reference>
      </references>
    </references>
    <section anchor="sec-access-control-lists">
      <name>Access Control Lists</name>
      <t>
This section presents an overview of fine-grained application security using Access Control Lists (ACLs). 
      </t>
      <t>
Access Control shall be a function of the Agent. A table of entries associating permission tags with groups of objects shall be queried at runtime to ensure privileged access,
while simultaneously allowing efficient implementation on an embedded device.
      </t>
      <t>
The concepts presented are in agreement with the Network Configuration Access Control Model (NACM) documented in <xref target="RFC8341"/>.
      </t>
      <section>
        <name>Tags</name>
        <t>
Permissions are defined using an Access Control Tag (AT). Each AT is a bit mask corresponding to a series of flags. For example three bits would be required for read, write, and execute permissions. 
Tags are similar in principle to file permissions on Unix, which tracks flags for Read/Write/Execute.
        </t>
        <t>
An AT could be stored in a CBOR unsigned integer. For example 0x800C would be a valid tag for an AT with four access controls of four bits each.
        </t>
      </section>
      <section>
        <name>Groups</name>
        <t>
Groups provide a general-purpose configuration to map an AT to a set of objects. 
        </t>
        <t>
An annotative name may be associated with a group, and a numeric group ID is used for for cross-referencing.
        </t>
        <section>
          <name>Associations</name>
          <t>
The following entities within an Agent may retain group associations:
          </t>
          <ul>
            <li>
The Agent shall be associated with a group.
            </li>
            <li>
Each node in the network may have a group association. A transport-specific ADM shall define how to map from authenticated Manager identifier to an access control group.
            </li>
            <li>
ADM objects shall be associated with the group of the Agent. 
            </li>
            <li>
ODM objects shall belong to the group associated with their execution context of creation. This prevents a Manager from exploiting permissions by, for example creating a one-second TBR to execute a task requiring elevated permissions.
            </li>
          </ul>
          <t>
A CTRL is provided to allow an object's group to be re-assigned. 

If a group is deleted all permissions associated with the group shall also be deleted, and objects previously belonging to the group shall inherit the default permissions.
          </t>
        </section>
        <section>
          <name>Permissions</name>
          <t>
Access control permissions shall be assigned using the combination of a Group, ARI Pattern (defined in <xref target="I-D.ietf-dtn-ari"/>), and Access Control Tag. At runtime the Agent shall retain a table of these tuples to store all necessary permissions. The table shall be queried by the Agent to find the corresponding AT for each managed object. If an object does not have an AT in the table then the default AT shall be used.
          </t>
          <aside>
            <t>
NOTE: There are optimizations an implementation could do to avoid time-consuming table lookups, because an ACL will change infrequently and objects are added and removed at controlled points. For example: when an ADM implementation is loaded, when an ODM is modified, etc.  Internally, the agent could associated access controls with an object and update object state as an ACL changes or when ACLs are being added.
            </t>
          </aside>
          <t>
The Agent shall use the Group corresponding to the appropriate execution context when querying for permissions. For more information see <xref target="sec-acl-execution-context"/>.
          </t>
          <t>
An object's ARI shall be used by the Agent when querying the table.
An important consideration is that an ARI contains an organization ID, model ID, and object ID, each of which may be expressed in either a text or integer form.
When looking up permissions the Agent needs to use all forms of identifier of the object itself - which can match all 8 possible combinations - and NOT limit lookup to a particular ARI used by the Manager to reference an object.
          </t>
          <t>
If the Agent discovers multiple tuples that correspond to an object, the AT with least permission should be applied to the object.
For example, if three tuples would allow an operation and the fourth would not, the Agent should deny permission.
          </t>
          <t>
Permissions shall be loaded during agent initialization and may be changed by an operator with sufficient permission. The default access level shall deny all operations. 
          </t>
          <t>
An agent implementation should provide a way to audit assignment of permissions.
          </t>
        </section>
        <section anchor="sec-acl-execution-context">
          <name>Execution Context</name>
          <t>
Each execution context shall be associated with a group. For direct execution the group is expected to correspond to the Manager that caused the execution to occur. For delayed execution such as a TBR the execution context shall refer to the group of the applicable object. When creating reports the ability to produce the report and send to a Manager is driven by permissions of the group of the Manager receiving the report.
          </t>
          <t><cref>TBD</cref>
There may be cases where an object is initialized as protected but assigned to a variable that is not protected, allowing another Manager a means of working around access controls.
In this early version of the document we do not protect against actions of a malicious Agent, or a privileged manager abusing its privileges. An Agent shall prevent an unprivileged Manager from abusing permissions to perform an unprivileged action.
          </t>
        </section>
      </section>
      <section>
        <name>Enforcement</name>
        <t>
Access control shall be enforced in the following way for processing activities described in <xref target="sec-proc"/>.
        </t>
        <section>
          <name>Dereferencing</name>
          <t>
When a variable is dereferenced the Agent shall look up the AT associated with the object. This is similar to other name-based access control systems such as AppArmor in Linux.
          </t>
        </section>
        <section>
          <name>Parameter Handling</name>
          <t>
Read permission shall be required for an object to be passed as a parameter.
          </t>
        </section>
        <section>
          <name>Value Production, Execution, and Evaluation</name>
          <t>
Execute permission shall be required for the object producing a value, executing, or being evaluated. There is one exception: if an OBJ-REF produces itself then Read permission is required.
          </t>
          <t>
Write permission is required for any object that could be modified by an operation. Note that result storage is ephemeral and parameters are passed by value, so any modifications to a VAR would be made by a limited number of special CTRLs in the agent ADM such as store_var.
          </t>
        </section>
        <section>
          <name>Reporting</name>
          <t>
Read permission is required if the OBJ-REF is a single value that will be reported directly.
          </t>
          <t>
Execute permission is required if the OBJ-REF is a RPTT that will be used to generate a RPT.
          </t>
        </section>
      </section>
      <section>
        <name>Roles</name>
        <t>
        Manager roles are implementation-specific and do not need to be specified in the ADM. However the likely manger roles are Trusted (all permissions) and Read-Only.
        </t>
      </section>
    </section>
    <section numbered="false" removeInRFC="true">
      <name>Implementation Status</name>
      <t>
[NOTE to the RFC Editor: please remove this section before publication, as well as the reference to <xref target="RFC7942"/>, <xref target="github-dtnma-tools"/>.]
      </t>
      <t>
This section records the status of known implementations of the
protocol defined by this specification at the time of posting of
this Internet-Draft, and is based on a proposal described in
<xref target="RFC7942"/>.
The description of implementations in this section is
intended to assist the IETF in its decision processes in progressing
drafts to RFCs. Please note that the listing of any individual
implementation here does not imply endorsement by the IETF.
Furthermore, no effort has been spent to verify the information
presented here that was supplied by IETF contributors. This is not
intended as, and must not be construed to be, a catalog of available
implementations or their features. Readers are advised to note that
other implementations can exist.
      </t>
      <t>
An implementation in C11 language of the procedures from this AMM is present in the reference DA (REFDA) library and example executables built from the <tt>apl-fy24</tt> development branch of <xref target="github-dtnma-tools"/>.
This repository includes unit test vectors for verifying DA behavior under many of the procedures of <xref target="sec-proc"/>.
      </t>
    </section>
    <section numbered="false" toc="include">
      <name>Acknowledgments</name>
      <t>
The following participants contributed technical material, use cases, and useful thoughts on
the overall approach captured in this document: David Linko, Sarah Heiner, and Jenny Cao of the Johns
Hopkins University Applied Physics Laboratory.
      </t>
    </section>
  </back>
</rfc>
