<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<rfc 
    xmlns:xi="http://www.w3.org/2001/XInclude"
    category="exp"
    docName="draft-mallick-muacp-00"
    ipr="trust200902"
    submissionType="independent">

  <front>
    <title abbrev="µACP">The Micro Agent Communication Protocol (µACP)</title>

    <author initials="A." surname="Mallick" fullname="Arnab Mallick">
      <organization>Centre for Development of Advanced Computing (CDAC)</organization>
      <address>
        <postal>
          <city>Hyderabad</city>
          <country>IN</country>
        </postal>
        <email>arnabm@cdac.in</email>
      </address>
    </author>

    <author initials="I." surname="Chebolu" fullname="Indraveni Chebolu">
      <organization>Centre for Development of Advanced Computing (CDAC)</organization>
      <address>
        <postal>
          <city>Hyderabad</city>
          <country>IN</country>
        </postal>
        <email>indravenik@cdac.in</email>
      </address>
    </author>

    <date year="2025" month="December" day="10"/>
    <area>Internet</area>
    <workgroup>Independent Submission</workgroup>

    <abstract>
      <t>This document specifies the Micro Agent Communication Protocol (µACP), 
      a resource-efficient messaging protocol for autonomous agents operating on 
      constrained devices (Class 1 IoT devices per <xref target="RFC7228"/>). Existing agent 
      communication protocols assume unbounded computational and energy resources; 
      µACP provides formal guarantees on memory, energy, and bandwidth consumption 
      while maintaining expressiveness sufficient for finite-state coordination 
      patterns. The protocol defines four core message types, a fixed 64-bit header, 
      TLV-based extensibility, and mandatory OSCORE security binding for operation 
      in adversarial environments.</t>
    </abstract>

    <note title="Status of This Memo">
      <t>This Internet-Draft is submitted in full conformance with the provisions 
      of BCP 78 and BCP 79.</t>
      <t>Internet-Drafts are working documents of the Internet Engineering Task Force 
      (IETF). Note that other groups may also distribute working documents as 
      Internet-Drafts. The list of current Internet-Drafts is at 
      https://datatracker.ietf.org/drafts/current/.</t>
      <t>Internet-Drafts are draft documents valid for a maximum of six months 
      and may be updated, replaced, or obsoleted by other documents at any time. 
      It is inappropriate to use Internet-Drafts as reference material or to cite 
      them other than as "work in progress."</t>
    </note>

    <note title="Copyright Notice">
      <t>Copyright (c) 2025 IETF Trust and the persons identified as the 
      document authors. All rights reserved.</t>
    </note>
  </front>

  <middle>
    
<section title="Introduction" anchor="introduction">
  <t>The Micro Agent Communication Protocol (µACP) is a compact, resource-efficient communication protocol designed for distributed autonomous agents operating on constrained devices. It aims to bridge the gap between resource-light IoT protocols and semantically rich agent communication languages, by offering minimal overhead yet expressive interaction semantics.</t>

  <t>Modern IoT, edge, and embedded environments often involve devices with limited RAM, CPU, energy, and unreliable or low-bandwidth networks. At the same time, many distributed applications — from sensor networks and robotics swarms to multi-agent systems and edge-native microservices — require coordination, state sharing, event subscriptions, request/response semantics, and lightweight negotiation. Existing protocols are often unsuited:</t>
  <ul>
    <li>Traditional agent-communication languages (e.g., FIPA-ACL) impose heavy parsing and runtime overhead unacceptable on microcontroller-class platforms.</li>
    <li>Standard IoT protocols (e.g., plain UDP, lightweight publish/subscribe) provide minimal semantics, making it difficult to implement structured coordination or stateful dialogues.</li>
  </ul>

  <t>µACP addresses this by defining a wire-efficient, fixed-header, TLV-extensible protocol that offers exactly four core verbs — PING, TELL, ASK, and OBSERVE — which together are sufficient to express common interaction patterns such as request/response, publish/subscribe, and liveness checking. The protocol is designed so that implementations can remain lean, deterministic in resource consumption, and suitable for microcontroller-class devices, while still supporting structured multi-agent interactions.</t>

  <t>Because security, confidentiality, and integrity are essential for many deployments (especially those involving sensitive data, distributed control, or untrusted networks), this specification mandates the use of the object-security mechanism defined by the IETF as the mandatory-to-implement transport binding: namely, the combination of CoAP (as the transport substrate) with OSCORE (for application-layer message protection) over constrained or lossy links. This ensures that even devices with limited resources can securely exchange µACP messages while preserving end-to-end confidentiality, integrity, and replay protection <xref target="RFC8613"/>.</t>

  <t><strong>Working Group Engagement:</strong> This document is submitted as an Independent Submission to the IETF. The authors welcome feedback from relevant working groups, particularly the Constrained RESTful Environments (CoRE) working group and the Light-Weight Implementation Guidance (LWIG) working group, and are open to transitioning this work to a working group if there is community interest and consensus.</t>

  <section title="Goals" anchor="goals">
  <ul>
    <li>Provide a minimal, low-overhead communication protocol for constrained agents that supports structured semantics without heavy runtime cost.</li>
    <li>Ensure deterministic and bounded resource usage (memory, CPU, bandwidth), enabling predictable behavior in resource-constrained environments.</li>
    <li>Support essential multi-agent communication patterns — request/response, publish/subscribe, life-check — using a small set of orthogonal primitives.</li>
    <li>Define a secure, interoperable transport binding so that agents across different platforms can communicate safely and reliably.</li>
    <li>Enable extensibility via a TLV option mechanism, allowing future enhancements (e.g., content types, metadata, authentication tokens) without breaking base compatibility.</li>
  </ul>
  </section>

  <section title="Scope" anchor="scope">
  <t>This specification defines the wire format, core semantics, normative behavior, mandatory transport binding, security constraints, and IANA registries required for interoperable implementations. It does not specify or mandate application-level semantics (e.g., content encoding, agent ontology, high-level negotiation logic), which are left to deployment-specific or higher-layer protocols. Implementers are free to choose content encoding (e.g., CBOR, JSON), TLV usage, and higher-level behavior, provided they adhere to the normative parts of this document.</t>
  </section>

  <section title="Intended Audience" anchor="audience">
  <t>This document is primarily intended for:</t>
  <ul>
    <li>Developers of embedded, IoT, or edge-device firmware seeking a lightweight yet expressive agent communication protocol;</li>
    <li>Protocol engineers designing distributed multi-agent systems requiring structured interactions, event subscriptions, or resource-aware communication;</li>
    <li>Standardization bodies and implementers evaluating µACP for integration into larger systems;</li>
    <li>Researchers studying resource-bounded multi-agent coordination, secure constrained communication, or constrained-device protocol design.</li>
  </ul>
  </section>

  <section title="Relation to Existing Work" anchor="relation">
  <t>µACP's transport binding leverages established IETF standards: CoAP as the constrained-device transport substrate <xref target="RFC7252"/>, and OSCORE for end-to-end object security across constrained networks and proxies <xref target="RFC8613"/>. OSCORE is itself designed for constrained RESTful environments and provides confidentiality, integrity, and replay protection for CoAP messages using COSE <xref target="RFC8949"/>.</t>

  <t>Compared to heavier agent-communication languages (e.g., FIPA-ACL), µACP trades semantic depth for minimalism and resource efficiency. Compared to plain CoAP or MQTT-style protocols, µACP brings structured agent-oriented primitives while preserving low overhead and deterministic resource usage. The TLV extensibility mechanism ensures future content- or metadata-level enhancements without invalidating base interoperability.</t>
  </section>

  <section title="Document Structure" anchor="structure">
  <t>The remainder of this document is organized as follows:</t>
  <t>- Section 2 defines conventions and terminology.  </t>
  <t>- Section 3 describes the µACP message model and wire encoding rules.  </t>
  <t>- Section 4 defines the protocol semantics of the four core verbs (PING, TELL, ASK, OBSERVE).  </t>
  <t>- Section 5 defines the mandatory transport binding using CoAP/OSCORE, including mapping rules, security profile, and operational constraints.  </t>
  <t>- Section 6 defines error handling rules, version negotiation, and extensibility mechanisms.  </t>
  <t>- Section 7 defines the IANA registries (TLV Types, QoS codes, content-format) and related registration policies.  </t>
  <t>- Section 8 provides normative interoperability requirements and deployment guidelines.  </t>
  <t>- Section 9 describes security considerations and threat mitigation strategies.  </t>
  <t>- Section 10 provides example interactions and wire-level encodings.  </t>
  <t>- Appendices contain deployment notes, conformance test descriptions, change log, and reference implementation pointers.</t>
</section>
</section>

<section title="Conventions and Terminology" anchor="conventions">
  <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when they appear in ALL CAPS. These words may also appear in lowercase or mixed case as plain English words, absent their normative meanings.</t>

  <section title="Terminology" anchor="terminology">
    <t>The following terms are used throughout this document:</t>
    
    <dl>
      <dt>Agent</dt>
      <dd>An autonomous software entity that participates in µACP communication. Agents send and receive µACP messages to coordinate with other agents.</dd>
      
      <dt>Verb</dt>
      <dd>One of four core communication primitives in µACP: PING, TELL, ASK, or OBSERVE. Verbs are encoded in 2 bits in the message header.</dd>
      
      <dt>TLV</dt>
      <dd>Type-Length-Value encoding format used for optional metadata in µACP messages. Each TLV consists of an 8-bit Type, 8-bit Length, and variable-length Value.</dd>
      
      <dt>Correlation ID</dt>
      <dd>A 16-bit identifier that groups related messages into a conversation. Messages sharing the same Correlation ID belong to the same conversation.</dd>
      
      <dt>Sequence ID</dt>
      <dd>A 16-bit monotonically increasing identifier used for duplicate detection and replay protection within a conversation.</dd>
      
      <dt>Conversation</dt>
      <dd>A sequence of related µACP messages identified by a unique Correlation ID. Conversations typically represent request/response exchanges or subscription relationships.</dd>
      
      <dt>OSCORE</dt>
      <dd>Object Security for Constrained RESTful Environments, as defined in <xref target="RFC8613"/>. OSCORE provides end-to-end security for CoAP messages.</dd>
      
      <dt>CoAP</dt>
      <dd>The Constrained Application Protocol, as defined in <xref target="RFC7252"/>. CoAP serves as the transport substrate for µACP.</dd>
      
      <dt>Constrained Device</dt>
      <dd>A device with limited resources (memory, CPU, energy, bandwidth) as defined in <xref target="RFC7228"/>. Class 1 devices have approximately 10 KB RAM and 100 KB flash.</dd>
    </dl>
  </section>

  <section title="Notation" anchor="notation">
    <t>This document uses the following notation conventions:</t>
    
    <ul>
      <li>Hexadecimal values are prefixed with "0x" (e.g., 0x01, 0xFF).</li>
      <li>Binary values are prefixed with "0b" (e.g., 0b00, 0b11).</li>
      <li>Byte order is network byte order (big-endian) unless otherwise specified.</li>
      <li>Bit positions are numbered from 0 (most significant bit) to n-1 (least significant bit).</li>
      <li>Message formats are shown using ASCII art diagrams.</li>
      <li>Code examples use a monospace font.</li>
    </ul>
  </section>

  <section title="Abbreviations" anchor="abbreviations">
    <t>The following abbreviations are used in this document:</t>
    
    <dl>
      <dt>ACL</dt>
      <dd>Agent Communication Language</dd>
      
      <dt>BDI</dt>
      <dd>Belief-Desire-Intention (agent architecture model)</dd>
      
      <dt>CBOR</dt>
      <dd>Concise Binary Object Representation <xref target="RFC8949"/></dd>
      
      <dt>CID</dt>
      <dd>Correlation ID</dd>
      
      <dt>CoAP</dt>
      <dd>Constrained Application Protocol</dd>
      
      <dt>COSE</dt>
      <dd>CBOR Object Signing and Encryption</dd>
      
      <dt>DTLS</dt>
      <dd>Datagram Transport Layer Security</dd>
      
      <dt>EDHOC</dt>
      <dd>Ephemeral Diffie-Hellman Over COSE <xref target="RFC9528"/></dd>
      
      <dt>FSM</dt>
      <dd>Finite State Machine</dd>
      
      <dt>IANA</dt>
      <dd>Internet Assigned Numbers Authority</dd>
      
      <dt>IoT</dt>
      <dd>Internet of Things</dd>
      
      <dt>MTI</dt>
      <dd>Mandatory to Implement</dd>
      
      <dt>OSCORE</dt>
      <dd>Object Security for Constrained RESTful Environments</dd>
      
      <dt>QoS</dt>
      <dd>Quality of Service</dd>
      
      <dt>SID</dt>
      <dd>Sequence ID</dd>
      
      <dt>TLV</dt>
      <dd>Type-Length-Value</dd>
      
      <dt>URI</dt>
      <dd>Uniform Resource Identifier</dd>
    </dl>
  </section>
</section>

<section title="Message Model and Encoding Rules" anchor="message-model">
  <t>This section defines the normative wire-level encoding of µACP messages, including the fixed header, TLV format, payload processing rules, byte ordering, and OSCORE protection boundaries. All compliant implementations MUST follow these encoding rules exactly unless otherwise specified.</t>

  <section title="Message Structure" anchor="msg-structure">
    <t>A µACP message consists of three components encoded in the following order:</t>

    <figure anchor="msg-layout">
      <name>Figure 1: µACP Message Layout</name>
      <artwork><![CDATA[
+----------------------+----------------------+-------------------------+
|     Header (64b)     |   TLVs (0..1024 B)   | Payload (0..65535 B)   |
+----------------------+----------------------+-------------------------+
      ]]></artwork>
    </figure>

    <t>The header format is fixed-length and MUST always appear. TLVs and payloads are optional. Messages MUST NOT exceed transport-imposed size limits; for CoAP/OSCORE, these limits are determined by underlying MTU constraints and CoAP Blockwise Transfer (RFC 7959) if used.</t>

    <t>All fields are encoded in network byte order (big-endian).</t>
  </section>

  <section title="Header Format" anchor="header-format">
    <t>The µACP header consists of 64 bits arranged as follows:</t>

    <figure anchor="header-diagram">
      <name>Figure 2: µACP Header Bit Layout</name>
      <artwork><![CDATA[
  0                   7 8                 15 16                23
 +---------------------+---------------------+--------------------+
 |     Sequence ID     |    Correlation ID   | QoS |Verb| Flags  |
 +---------------------+---------------------+--------------------+
 24                                                        63
 +--------------------------------------------------------------+
 |                       Reserved (40 bits)                      |
 +--------------------------------------------------------------+
      ]]></artwork>
    </figure>

    <t><strong>Sequence ID (16 bits):</strong>  
      Monotonically increasing identifier used for duplicate detection and replay-window tracking.  
      MUST wrap modulo 2^16.  
      MUST be unpredictable if security-sensitive traffic requires preventing traffic analysis.</t>

    <t><strong>Correlation ID (16 bits):</strong>  
      Identifies all messages belonging to the same conversation.  
      MUST be unique among active conversations.  
      SHOULD be randomly generated in security-sensitive deployments.</t>

    <t><strong>QoS (2 bits):</strong>  
      Encodes transmission semantics (fire-and-forget, at-least-once, at-most-once).  
      Values are defined in the IANA Considerations section.</t>

    <t><strong>Verb (2 bits):</strong>  
      Identifies one of the four µACP operations: PING(0), TELL(1), ASK(2), OBSERVE(3).</t>

    <t><strong>Flags (4 bits):</strong>  
      Control bits reserved for protocol-level features such as fragmentation, retransmission hints, or message cancellation.  
      Future specifications MAY define additional meanings.</t>

    <t><strong>Reserved (40 bits):</strong>  
      MUST be set to zero on transmission.  
      MUST be ignored by receivers.  
      Reserved bits MAY be repurposed by future µACP versions but MUST NOT change meaning in this version.</t>
  </section>

  <section title="TLV Encoding" anchor="tlv-encoding">
    <t>TLVs (Type–Length–Value structures) convey optional metadata and extensibility information. They appear immediately after the header and MUST appear in Type-increasing order to allow binary search and deterministic parsing.</t>

    <figure anchor="tlv-format">
      <name>Figure 3: TLV Encoding</name>
      <artwork><![CDATA[
  0        7 8        15
 +----------+-----------+------------------------------+
 |  Type    |  Length   |    Value (Length octets)     |
 +----------+-----------+------------------------------+
      ]]></artwork>
    </figure>

    <t><strong>Type (8 bits):</strong>  
      TLV identifier. The meaning of each Type is defined in the IANA registry.  
      Types 0–31 are reserved and governed by Standards Action.  
      Types 32–127 require IETF Review.  
      Types 128–255 are vendor-specific.</t>

    <t><strong>Length (8 bits):</strong>  
      Specifies the number of octets in the Value field. Length MUST NOT exceed 255.  
      TLVs MUST NOT cause the total TLV region to exceed 1024 bytes.</t>

    <t><strong>Value:</strong>  
      Encoded according to Type. For Types other than 0x00 (Raw Octets), the Value is subject to OSCORE protection (Section 5).</t>

    <t><strong>Critical TLVs:</strong>  
      A future TLV Type range MAY designate critical TLVs.  
      Receiving an unknown critical TLV MUST cause message rejection.</t>

    <section title="TLV Processing Rules" anchor="tlv-processing">
      <t>Receivers MUST apply the following rules when processing TLVs:</t>
      <ul>
        <li>TLVs MUST be parsed strictly in order.</li>
        <li>If Length exceeds remaining buffer size, the message MUST be discarded.</li>
        <li>Unknown TLV Types MUST be ignored unless they are designated critical.</li>
        <li>TLV order MUST be strictly increasing by Type; violating this is a format error.</li>
        <li>TLV Type 0x00 (Raw Octets) MUST NOT appear in encrypted messages; its use is restricted to unencrypted PING messages.</li>
      </ul>
    </section>
  </section>

  <section title="Payload Encoding" anchor="payload">
    <t>The µACP payload is an optional octet string of 0–65535 bytes. Its semantics depend on the Verb and the application layer. Payloads are typically used for:</t>

    <ul>
      <li>Application data (e.g., sensor readings, state updates);</li>
      <li>Action parameters and operation descriptors;</li>
      <li>Event notifications for OBSERVE subscriptions;</li>
      <li>Encoded content (CBOR, JSON, application-specific formats).</li>
    </ul>

    <t>Payloads MUST be OSCORE-protected unless the message Verb is PING.  
       Payload sizes MUST be validated before allocation to avoid resource exhaustion.</t>

    <t>If the payload is encoded using CBOR (Type=0x03), receivers MUST treat it as a single CBOR data item. If the payload is JSON (Type=0x02), it MUST be UTF-8 encoded.</t>
  </section>

  <section title="Byte Ordering" anchor="byte-order">
    <t>All multi-octet integer fields in µACP (Sequence ID, Correlation ID, header composites) MUST be encoded in network byte order (big-endian). TLV and payload content MAY use other encoding rules (e.g., CBOR or UTF-8) as determined by their Types.</t>
  </section>

  <section title="Fragmentation (Optional Feature)" anchor="fragmentation">
    <t>µACP itself does not mandate fragmentation. When implemented, fragmentation MUST be controlled by Flags in the header and MUST operate in a deterministic, resource-bounded manner.</t>

    <t>This specification defines the following fragmentation requirements:</t>
    <ul>
      <li>Fragments MUST preserve the same Sequence ID, Correlation ID, and Verb.</li>
      <li>Fragments MUST carry a Fragment-ID TLV if fragmentation is used.</li>
      <li>Receivers MUST reassemble fragments in Sequence ID order.</li>
      <li>Reassembly MUST abort if missing fragments exceed timeout thresholds.</li>
    </ul>

    <t>Deployments using CoAP Blockwise Transfer (RFC 7959) SHOULD avoid µACP-level fragmentation to minimize complexity.</t>
  </section>

  <section title="OSCORE Protection Boundaries" anchor="oscore-boundaries">
    <t>When µACP is transported over CoAP with OSCORE, the OSCORE-protected CoAP payload MUST contain the complete µACP message (Header | TLVs | Payload). The OSCORE security context determines integrity, confidentiality, and replay parameters.</t>

    <t>The following MUST be protected by OSCORE:</t>
    <ul>
      <li>All TLVs except those in unencrypted PING messages;</li>
      <li>The entire payload;</li>
      <li>The header fields other than those needed for outer CoAP routing.</li>
    </ul>

    <t>Implementations MUST NOT leak semantics (e.g., Verb, QoS) through the CoAP outer header beyond what OSCORE permits.</t>
  </section>

  <section title="Canonical Encoding Rules" anchor="canonical-encoding">
    <t>To ensure interoperability and deterministic parsing, µACP defines the following canonical encoding rules:</t>

    <ul>
      <li>Fields MUST NOT be padded.</li>
      <li>TLVs MUST be sorted by ascending Type.</li>
      <li>No two TLVs MAY share the same Type unless explicitly defined.</li>
      <li>Payload MUST begin immediately after the last TLV.</li>
      <li>Implementations MUST normalize line endings, whitespace, or internal representations before hashing or signing application content.</li>
    </ul>

    <t>These rules ensure that µACP messages can be compared as byte strings and efficiently parsed on constrained devices.</t>
  </section>
</section>
<section title="Protocol Semantics" anchor="semantics">
  <t>This section defines the normative semantics of the four µACP verbs: PING, TELL, ASK, and OBSERVE. Each verb represents a fundamental communication primitive intended to support higher-level agent behaviors, including liveness detection, request/response interactions, state dissemination, and event-driven notification.</t>

  <t>Agents MUST implement all four verbs.  
     Agents MUST apply OSCORE protection to all messages except PING, unless an application explicitly operates in an unauthenticated environment.</t>

  <t>For each verb, this section defines sender behavior, receiver behavior, state-machine interactions, mandatory error cases, and expected processing-time bounds.</t>

  <!-- ========================= -->
  <!-- 4.1 PING                  -->
  <!-- ========================= -->

  <section title="PING" anchor="verb-ping">
    <t>PING provides a low-cost, minimal-overhead mechanism for reachability and liveness detection. PING messages MUST NOT carry OSCORE-protected content. PING messages MAY include Raw-Octet TLVs (Type=0x00) but MUST NOT include any TLVs requiring confidentiality or integrity.</t>

    <section title="Sender Behavior" anchor="ping-sender">
    <ul>
      <li>The sender MAY emit a PING at any time to test peer liveness.</li>
      <li>The Sequence ID MUST increment for each PING from the same sender.</li>
      <li>The Correlation ID SHOULD be unique among active PING probes to avoid ambiguity.</li>
      <li>No payload is RECOMMENDED; the PING SHOULD remain as small as possible.</li>
      <li>PING SHOULD be rate-limited to avoid unnecessary resource pressure.</li>
    </ul>
    </section>

    <section title="Receiver Behavior" anchor="ping-receiver">
    <ul>
      <li>The receiver SHOULD reply with a TELL unless configured otherwise.</li>
      <li>The receiver MUST NOT require OSCORE protection for PING.</li>
      <li>The receiver MAY update local reachability or suspicion heuristics.</li>
      <li>The receiver MUST ignore any TLVs not allowed for PING.</li>
    </ul>
    </section>

    <section title="Error Conditions" anchor="ping-errors">
    <ul>
      <li>If a PING contains encrypted TLVs or a payload, the receiver MUST treat the message as malformed.</li>
      <li>If resource limits are exceeded, the receiver MAY silently drop the PING.</li>
    </ul>
    </section>
  </section>

  <section title="TELL" anchor="verb-tell">
    <t>TELL conveys information, updates, or asynchronous notifications. TELL is the primary mechanism for distributing state and for responding to ASK messages.</t>

    <t>TELL messages MUST be OSCORE-protected unless the deployment explicitly allows an unauthenticated mode.</t>

    <section title="Sender Behavior" anchor="tell-sender">
    <ul>
      <li>The sender MUST include a payload or a meaningful TLV set.</li>
      <li>The sender SHOULD ensure that TELL messages are idempotent for the given Correlation ID.</li>
      <li>The sender MUST increment the Sequence ID for each TELL.</li>
      <li>When responding to an ASK, the sender MUST use the same Correlation ID as the request.</li>
      <li>If notifying subscribers (OBSERVE), the sender MUST include event-related TLVs.</li>
    </ul>
    </section>

    <section title="Receiver Behavior" anchor="tell-receiver">
    <ul>
      <li>The receiver MUST validate OSCORE before inspecting payload or TLVs.</li>
      <li>The receiver MUST associate the message with the correct conversation using Correlation ID.</li>
      <li>The receiver MUST incorporate content into its knowledge base according to application policy.</li>
      <li>The receiver SHOULD acknowledge or respond only if required by application semantics.</li>
      <li>In OBSERVE-driven notifications, the receiver MUST update subscription state accordingly.</li>
    </ul>
    </section>

    <section title="Error Conditions" anchor="tell-errors">
    <ul>
      <li>If a TELL arrives without OSCORE protection, the receiver MUST reject it unless configured for non-secure operation.</li>
      <li>If a TELL carries malformed TLVs, the receiver MUST discard the message.</li>
      <li>If correlation state does not exist and the TELL is unsolicited, the receiver MAY treat it as a standalone notification.</li>
    </ul>
    </section>
  </section>

  <section title="ASK" anchor="verb-ask">
    <t>ASK initiates a request for information or action. ASK is analogous to a query, command, or method invocation, and typically elicits a TELL response.</t>

    <t>ASK messages MUST be OSCORE-protected.</t>

    <section title="Sender Behavior" anchor="ask-sender">
    <ul>
      <li>The sender MUST allocate a new conversation entry indexed by the Correlation ID.</li>
      <li>The sender MUST increment the Sequence ID.</li>
      <li>The ASK payload SHOULD include sufficient information for the receiver to satisfy the request.</li>
      <li>The sender MUST start a request timer; expiration triggers retransmission (for QoS ≥ 1) or failure escalation.</li>
      <li>The sender MUST enforce conversation limits to avoid resource exhaustion.</li>
    </ul>
    </section>

    <section title="Receiver Behavior" anchor="ask-receiver">
    <ul>
      <li>The receiver MUST validate OSCORE before processing.</li>
      <li>The receiver MUST associate the ASK with the given Correlation ID, creating state if needed.</li>
      <li>The receiver MUST generate a TELL response with either the requested result or an error TLV.</li>
      <li>If the request cannot be satisfied in bounded time, the receiver MAY send an immediate error TELL.</li>
      <li>If performing an action, the receiver SHOULD ensure bounded execution time or respond asynchronously.</li>
    </ul>
    </section>

    <section title="Error Conditions" anchor="ask-errors">
    <ul>
      <li>If the ASK contains malformed or conflicting TLVs, the receiver MUST reject it using a TELL(error).</li>
      <li>If security validation fails, the receiver MUST silently discard the message.</li>
      <li>If correlation-table limits are exceeded, the receiver MAY respond with a resource exhaustion error.</li>
    </ul>
    </section>
  </section>

  <section title="OBSERVE" anchor="verb-observe">
    <t>OBSERVE establishes a subscription for future notifications. It is analogous to a publish/subscribe registration but scoped to a single peer.</t>

    <t>OBSERVE messages MUST be OSCORE-protected.</t>

    <section title="Sender Behavior" anchor="observe-sender">
    <ul>
      <li>The sender MUST allocate or update a subscription state entry indexed by Correlation ID.</li>
      <li>The sender MUST validate that subscription limits have not been exceeded.</li>
      <li>The sender MUST increment the Sequence ID.</li>
      <li>The sender MAY include TLVs expressing subscription parameters (e.g., topic, conditions).</li>
      <li>The sender MUST send periodic notifications (TELL) while the subscription remains active.</li>
    </ul>
    </section>

    <section title="Receiver Behavior" anchor="observe-receiver">
    <ul>
      <li>The receiver MUST validate OSCORE before processing.</li>
      <li>The receiver MUST establish or refresh subscription state.</li>
      <li>The receiver SHOULD acknowledge with a TELL containing subscription parameters.</li>
      <li>The receiver MUST enforce subscription expiration, backpressure rules, and resource ceilings.</li>
      <li>When conditions are met, the receiver MUST send event notifications as TELL messages.</li>
    </ul>
    </section>

    <section title="Subscription Cancellation" anchor="observe-cancel">
    <t>Subscription cancellation is performed when a TELL or OBSERVE message carries a Cancel-Subscription TLV (Type=0xFF). Upon cancellation:</t>
    <ul>
      <li>The receiver MUST delete subscription state.</li>
      <li>The receiver MUST stop sending notifications.</li>
      <li>The receiver MAY send a TELL confirming deletion.</li>
    </ul>
    </section>

    <section title="Error Conditions" anchor="observe-errors">
    <ul>
      <li>If subscription limits are exceeded, the receiver MUST reject the OBSERVE with a TELL(error).</li>
      <li>If the OBSERVE contains a topic or condition TLV not understood by the receiver, the receiver MAY reject it.</li>
      <li>If OSCORE validation fails, the message MUST be dropped.</li>
    </ul>
    </section>
  </section>

  <section title="Summary of Normative Requirements" anchor="verb-summary">
    <t>The following summarizes the semantic requirements of each verb:</t>

    <ul>
      <li><strong>PING:</strong> Liveness probe; MUST NOT require OSCORE; MUST NOT include protected TLVs.</li>
      <li><strong>TELL:</strong> Update/response/notification; MUST use OSCORE except in explicitly insecure deployments.</li>
      <li><strong>ASK:</strong> Request; MUST use OSCORE; MUST generate a TELL response.</li>
      <li><strong>OBSERVE:</strong> Subscription; MUST use OSCORE; MUST create or update subscription state.</li>
    </ul>

    <t>Agents MUST NOT overload verbs with incompatible semantics. All application-defined behaviors MUST build upon these primitives in a manner that preserves µACP’s resource and security guarantees.</t>
  </section>
</section>
<section title="Mandatory Transport Binding: OSCORE/CoAP" anchor="transport-mti">
  <t>This section defines the mandatory-to-implement (MTI) transport binding for µACP: the combination of the Constrained Application Protocol (CoAP) as the transport substrate and OSCORE as the end-to-end object security mechanism. All compliant µACP implementations MUST support this binding.</t>

  <t>Deployments MAY support additional bindings (e.g., DTLS/UDP or QUIC) but such bindings are outside the scope of this specification and MUST NOT weaken or replace the OSCORE/CoAP MTI profile.</t>

  <!-- ============================== -->
  <!-- 5.1 CoAP Request/Response Model -->
  <!-- ============================== -->

  <section title="Mapping µACP Messages to CoAP" anchor="coap-mapping">
    <t>Each µACP message (Header | TLVs | Payload) is encoded as a byte string and placed entirely within the CoAP message payload. Only OSCORE-protected CoAP messages may carry µACP messages (except PING, which MAY be unprotected under specific deployment configurations).</t>

    <t>µACP messages MUST use the following CoAP message structure:</t>

    <ul>
      <li><strong>Method:</strong> POST</li>
      <li><strong>URI-Path:</strong> "muacp" (fixed path for interoperability)</li>
      <li><strong>Content-Format:</strong> application/muacp+binary</li>
      <li><strong>Payload:</strong> Full µACP message</li>
    </ul>

    <t>This yields the canonical envelope:</t>

    <figure anchor="coap-envelope">
      <name>Figure 4: CoAP Envelope Carrying a µACP Message</name>
      <artwork><![CDATA[
+-------------------------------+
|  CoAP Header (CON/NON)       |
+-------------------------------+
|  Uri-Path: "muacp"           |
+-------------------------------+
|  Content-Format: muacp+binary|
+-------------------------------+
|  OSCORE Option               |
+-------------------------------+
|  Ciphertext Payload          |
|  (encapsulated µACP message) |
+-------------------------------+
      ]]></artwork>
    </figure>

    <t>Each µACP message corresponds to exactly one CoAP POST. For request/response interactions (ASK → TELL), CoAP confirmable/non-confirmable messages MAY be used depending on QoS requirements.</t>
  </section>

  <!-- ================================== -->
  <!-- 5.2 OSCORE Protection Requirements -->
  <!-- ================================== -->

  <section title="OSCORE Protection Requirements" anchor="oscore-protection">
    <t>All µACP messages except PING MUST be protected using OSCORE. OSCORE provides confidentiality, integrity, and replay protection independent of the transport layer.</t>

    <t>OSCORE MUST protect the following elements:</t>
    <ul>
      <li>The entire µACP header (except when outer CoAP metadata is required for routing).</li>
      <li>All TLVs except raw TLVs permitted for PING.</li>
      <li>The entire µACP payload.</li>
    </ul>

    <t>OSCORE replay protection MUST be enabled. Implementations MUST configure replay windows to match expected message rate and resource constraints.</t>

    <t>OSCORE MUST use a unique security context per agent-pair. Context reuse between unrelated peers is prohibited.</t>
  </section>

  <!-- ============================== -->
  <!-- 5.3 Establishing OSCORE Context -->
  <!-- ============================== -->

  <section title="Establishing OSCORE Security Contexts" anchor="oscore-context">
    <t>Security contexts for OSCORE MAY be derived by any of the following methods:</t>

    <ul>
      <li><strong>EDHOC (RECOMMENDED):</strong> A lightweight authenticated key exchange protocol suitable for constrained devices.</li>
      <li><strong>Pre-Shared Keys (PSK):</strong> For deployments with pre-configured trust anchors.</li>
      <li><strong>Out-of-band provisioning:</strong> Where security associations are established during manufacturing or commissioning.</li>
    </ul>

    <t>When EDHOC is used, the resulting OSCORE context MUST be bound to the EDHOC handshake transcript to prevent identity misbinding attacks.</t>
  </section>

  <!-- ============================== -->
  <!-- 5.4 CoAP Message Types          -->
  <!-- ============================== -->

  <section title="CoAP Message Types and Reliability" anchor="coap-types">
    <t>µACP builds upon CoAP reliability semantics to achieve its QoS model. Implementations MUST map µACP QoS codes to CoAP message types as follows:</t>

    <texttable anchor="qos-map">
      <ttcol>µACP QoS</ttcol>
      <ttcol>Meaning</ttcol>
      <ttcol>CoAP Message Type</ttcol>
      <c>0</c>
      <c>fire-and-forget</c>
      <c>NON (Non-confirmable)</c>
      <c>1</c>
      <c>at-least-once delivery</c>
      <c>CON (Confirmable)</c>
      <c>2</c>
      <c>at-most-once delivery</c>
      <c>NON (No retransmission)</c>
    </texttable>

    <t>CoAP-level acknowledgments MUST NOT be interpreted as µACP-level responses. Application responses are always encoded as TELL messages.</t>
  </section>

  <!-- ================================= -->
  <!-- 5.5 Request/Response Interactions -->
  <!-- ================================= -->

  <section title="Mapping ASK–TELL to CoAP Request/Response" anchor="ask-tell-mapping">
    <t>ASK messages MUST be sent as CoAP POST requests. Corresponding TELL responses MUST be sent as CoAP responses. OSCORE MUST protect both directions.</t>

    <t>The Correlation ID uniquely links the ASK with the TELL response. CoAP Message IDs MUST NOT be used for application correlation.</t>

    <t>Receivers MUST respond with a TELL message even when requests fail, using an Error TLV to describe failure conditions.</t>

    <figure anchor="ask-tell-seq">
      <name>Figure 5: ASK/TELL Over OSCORE-CoAP</name>
      <artwork><![CDATA[
Agent A                                Agent B
-------                                -------
POST /muacp (ASK, OSCORE)  ---------->
                     <----------   2.04 Changed (TELL, OSCORE)
      ]]></artwork>
    </figure>
  </section>

  <!-- =============================== -->
  <!-- 5.6 OBSERVE Interaction Mapping -->
  <!-- =============================== -->

  <section title="Mapping OBSERVE Subscriptions" anchor="observe-mapping">
    <t>OBSERVE establishes a long-lived subscription. Subscriptions are maintained by application logic and do NOT rely on CoAP’s Observe extension (RFC 7641). µACP defines its own subscription model, independent of CoAP's Observe option.</t>

    <t>OBSERVE MUST be mapped as:</t>
    <ul>
      <li>A CoAP POST containing an µACP OBSERVE message.</li>
      <li>Notification messages delivered as CoAP POSTs containing TELL messages.</li>
    </ul>

    <t>Implementations MUST NOT use CoAP Observe for µACP subscriptions, to avoid semantic conflicts.</t>
  </section>

  <!-- ========================= -->
  <!-- 5.7 Congestion Control     -->
  <!-- ========================= -->

  <section title="Congestion Control Requirements" anchor="congestion">
    <t>All µACP-over-CoAP deployments MUST implement congestion control to prevent network collapse and unfair bandwidth usage.</t>

    <t>Agents MUST adhere to the following rules:</t>
    <ul>
      <li>Apply exponential backoff on CoAP CON retransmissions.</li>
      <li>Rate-limit PING to avoid liveness floods.</li>
      <li>Throttle OBSERVE notifications when bandwidth pressure is detected.</li>
      <li>Maintain deterministic CPU and buffer usage for message handling.</li>
      <li>Avoid generating more than one message per RTT per conversation, except under QoS ≥ 1 retransmission.</li>
    </ul>

    <t>When Blockwise Transfer (RFC 7959) is used, agents MUST ensure block sizes do not exceed memory limits.</t>
  </section>

  <!-- ====================================== -->
  <!-- 5.8 Error Handling at the Transport     -->
  <!-- ====================================== -->

  <section title="Transport-Layer Error Handling" anchor="transport-errors">
    <t>Transport errors such as CoAP timeouts, OSCORE decryption failures, or missing acknowledgments MUST be translated into µACP-level behavior rather than silently ignored.</t>

    <t>Specifically:</t>
    <ul>
      <li>If OSCORE decryption fails, the µACP message MUST be dropped.</li>
      <li>If a CoAP CON message is not acknowledged, the sender MUST apply µACP QoS semantics to determine retransmission.</li>
      <li>Repeated timeouts MUST cause the µACP conversation to enter a failure state.</li>
      <li>Malformed CoAP envelopes MUST cause message discard.</li>
    </ul>
  </section>

  <!-- ============================ -->
  <!-- 5.9 Summary of MTI Binding   -->
  <!-- ============================ -->

  <section title="Summary of MTI Requirements" anchor="transport-summary">
    <t>All compliant µACP implementations MUST:</t>

    <ul>
      <li>Support CoAP POST requests to the fixed path "muacp".</li>
      <li>Support Content-Format: application/muacp+binary.</li>
      <li>Protect all messages except PING with OSCORE.</li>
      <li>Enforce OSCORE replay protection.</li>
      <li>Derive OSCORE contexts using EDHOC or equivalent secure provisioning.</li>
      <li>Map QoS codes to CoAP message types according to the CoAP Message Types and Reliability section.</li>
      <li>Generate TELL responses for all ASK messages.</li>
      <li>Deliver notifications for active OBSERVE subscriptions as TELL messages.</li>
    </ul>

    <t>This binding ensures interoperability across all µACP implementations and establishes a minimum security baseline for deployments.</t>
  </section>

</section>
<section title="Error Handling, Version Negotiation, and Extensibility" anchor="errors-and-versioning">
  <t>This section defines the normative error-handling rules for µACP, the version-negotiation mechanism, downgrade protection requirements, and the extensibility framework provided by the TLV architecture. Proper handling of malformed messages, incompatible versions, and future extensions is essential for interoperability and robustness.</t>

  <!-- ========================= -->
  <!-- 6.1 Error Code Semantics   -->
  <!-- ========================= -->

  <section title="Error Code TLVs" anchor="error-tlv">
    <t>All protocol-level errors MUST be communicated using a TELL message that includes an Error-Code TLV. Error codes are encoded as unsigned integers and MUST follow the registry defined in the IANA Considerations section.</t>

    <figure anchor="error-tlv-format">
      <name>Error-Code TLV</name>
      <artwork><![CDATA[
Type:   0x22 (Error-Code, see IANA registry)
Length: 1 or 2 octets
Value:  Integer error code
      ]]></artwork>
    </figure>

    <t>The sender MUST set the Correlation ID of the error response to match the ID of the failing message. Receivers MUST interpret the error code as part of the µACP conversation state.</t>
  </section>

  <!-- ===================================== -->
  <!-- 6.2 Standard Error Conditions and Codes-->
  <!-- ===================================== -->

  <section title="Standardized Error Conditions" anchor="standard-errors">
    <t>The following error codes are defined for µACP:</t>

    <texttable anchor="error-codes">
      <ttcol>Code</ttcol>
      <ttcol>Name</ttcol>
      <ttcol>Description</ttcol>

      <c>0x01</c><c>ERR_MALFORMED</c>
      <c>Malformed header, TLV, or payload.</c>

      <c>0x02</c><c>ERR_UNSUPPORTED_VERB</c>
      <c>Verb not recognized or not supported by receiver.</c>

      <c>0x03</c><c>ERR_UNSUPPORTED_TLV</c>
      <c>Critical TLV not understood.</c>

      <c>0x04</c><c>ERR_FORBIDDEN</c>
      <c>Operation not permitted due to policy or authorization.</c>

      <c>0x05</c><c>ERR_RESOURCE_EXHAUSTED</c>
      <c>Memory, CPU, or subscription/conversation limits exceeded.</c>

      <c>0x06</c><c>ERR_VERSION_MISMATCH</c>
      <c>Message uses unsupported protocol version.</c>

      <c>0x07</c><c>ERR_TIMEOUT</c>
      <c>Sender or receiver timed out while waiting for a response.</c>

      <c>0x08</c><c>ERR_INTERNAL</c>
      <c>Internal failure not covered by other error categories.</c>
    </texttable>

    <t>Implementations MAY define additional vendor-specific error codes in the vendor range but MUST NOT redefine standardized codes.</t>
  </section>

  <!-- =============================== -->
  <!-- 6.3 Robust Handling of Malformed -->
  <!-- =============================== -->

  <section title="Handling Malformed Messages" anchor="malformed">
    <t>Receivers MUST apply strict validation to protect against malformed messages and resource attacks. Specifically:</t>

    <ul>
      <li>If TLV Length exceeds remaining bytes, the message MUST be discarded.</li>
      <li>If TLVs appear out of Type order, the message MUST be discarded.</li>
      <li>If a required TLV (future versions) is absent, the message MUST be rejected.</li>
      <li>If header fields contain invalid combinations (e.g., reserved bits set), the message MUST be rejected.</li>
      <li>If OSCORE decryption fails, the message MUST be discarded without error signaling.</li>
    </ul>

    <t>Where feasible, a receiver SHOULD send a TELL(error) message to report failure, unless doing so would amplify a denial-of-service attack.</t>
  </section>

  <!-- =============================== -->
  <!-- 6.4 Conversation-Lifetime Errors -->
  <!-- =============================== -->

  <section title="Conversation-Lifetime Error Handling" anchor="conversation-errors">
    <t>Conversations MAY fail due to timeouts, resource limits, or message corruption. When such failures occur:</t>
    <ul>
      <li>The agent MUST free associated resources (conversation-table entries).</li>
      <li>The agent SHOULD send an ERR_TIMEOUT or ERR_RESOURCE_EXHAUSTED TELL message.</li>
      <li>For resource exhaustion, an agent MUST NOT attempt recovery that risks violating its resource budget.</li>
    </ul>

    <t>Conversations MUST be terminated when Correlation IDs collide.</t>
  </section>

  <!-- ============================ -->
  <!-- 6.5 Version Negotiation       -->
  <!-- ============================ -->

  <section title="Version Negotiation" anchor="version-negotiation">
    <t>µACP includes a Version field in the TLV space to allow forward compatibility. A Version-TLV (Type=0x01) MAY be included in any message to indicate the sender’s supported protocol versions.</t>

    <figure anchor="version-tlv">
      <name>Figure 7: Version TLV</name>
      <artwork><![CDATA[
Type:   0x01 (Version)
Length: N (number of supported versions)
Value:  Array of version numbers (e.g., [0x00])
      ]]></artwork>
    </figure>

    <t>Receivers MUST ignore Version-TLVs indicating versions higher than supported. Receivers MUST accept messages labeled as version 0x00 (this specification) unless malformed.</t>

    <t>If a message indicates only unsupported versions, the receiver MUST return ERR_VERSION_MISMATCH.</t>
  </section>

  <!-- ============================ -->
  <!-- 6.6 Downgrade Protection      -->
  <!-- ============================ -->

  <section title="Downgrade and Version-Rollback Protection" anchor="downgrade">
    <t>Implementations MUST ensure that attackers cannot force a peer to use a lower protocol version when a higher mutually supported version is available.</t>

    <t>Specifically:</t>
    <ul>
      <li>When a Version TLV lists multiple supported versions, the highest mutually supported version MUST be chosen.</li>
      <li>Version negotiation MUST occur inside OSCORE-protected messages except for PING.</li>
      <li>Agents MUST NOT downgrade versions unless a failure condition explicitly requires fallback.</li>
    </ul>
  </section>

  <!-- ============================ -->
  <!-- 6.7 Extensibility Framework   -->
  <!-- ============================ -->

  <section title="Extensibility Framework" anchor="extensibility">
    <t>µACP is designed to evolve through extensible mechanisms based on TLVs. The following constraints ensure future versions remain interoperable:</t>

    <ul>
      <li><strong>Forward compatibility:</strong> Receivers MUST ignore unknown non-critical TLVs.</li>
      <li><strong>Backward compatibility:</strong> Implementations MUST NOT reuse TLV Types for different semantics.</li>
      <li><strong>Critical TLVs:</strong> Future versions MAY introduce critical TLVs; receiving an unsupported critical TLV MUST trigger ERR_UNSUPPORTED_TLV.</li>
      <li><strong>TLV ordering:</strong> All TLVs MUST be sorted by increasing Type value.</li>
      <li><strong>Vendor extensions:</strong> Types 128–255 are reserved for vendor-specific semantics and MUST NOT require global registration.</li>
    </ul>

    <t>Complex or multi-field extensions SHOULD define new structured TLVs rather than overloading primitive types.</t>
  </section>

  <!-- ================================== -->
  <!-- 6.8 Summary of Normative Behavior  -->
  <!-- ================================== -->

  <section title="Summary of Normative Requirements" anchor="error-summary">
    <t>This section can be summarized as follows:</t>

    <ul>
      <li>Malformed messages MUST be rejected and SHOULD trigger a TELL(error) unless unsafe.</li>
      <li>Errors MUST use standardized codes where applicable.</li>
      <li>Version negotiation MUST prefer the highest mutually supported version.</li>
      <li>Unknown non-critical TLVs MUST be ignored; unknown critical TLVs MUST trigger errors.</li>
      <li>OSCORE failures MUST cause silent discard.</li>
      <li>Resource exhaustion MUST lead to conservative cleanup behavior.</li>
    </ul>

    <t>These requirements ensure that µACP remains robust, extensible, and secure across diverse deployments.</t>
  </section>

</section>
<section title="IANA Considerations" anchor="iana">
  <t>This section requests the creation of new registries and assignments required for µACP to function as an interoperable Internet protocol. All registries use the policies defined in <xref target="RFC8126"/>. Unless otherwise stated, values are allocated using the "IETF Review" policy.</t>

  <!-- ========================================== -->
  <!-- 7.1 µACP TLV Types Registry                 -->
  <!-- ========================================== -->

  <section title="µACP TLV Types Registry" anchor="iana-tlv">
    <t>IANA is requested to create a new registry entitled "µACP TLV Types". The registry consists of 8-bit values (0–255). Each entry MUST contain:</t>

    <ul>
      <li>Value (0–255)</li>
      <li>Name</li>
      <li>Description</li>
      <li>Value format (e.g., integer, UTF-8, CBOR)</li>
      <li>Reference</li>
    </ul>

    <t>The range is divided as follows:</t>

    <ul>
      <li><strong>0–31:</strong> Standards Action</li>
      <li><strong>32–127:</strong> IETF Review</li>
      <li><strong>128–255:</strong> Vendor-specific</li>
    </ul>

    <t>IANA is requested to populate the registry with the initial values below:</t>

    <texttable anchor="tlv-initial">
      <ttcol>Value</ttcol><ttcol>Name</ttcol><ttcol>Description</ttcol><ttcol>Format</ttcol><ttcol>Reference</ttcol>

      <c>0x00</c><c>RAW_OCTETS</c><c>Unstructured data; MUST NOT appear in encrypted messages except PING.</c><c>Opaque</c><c>This document</c>

      <c>0x01</c><c>VERSION</c><c>Advertised supported protocol versions.</c><c>Array of integers</c><c>This document</c>

      <c>0x02</c><c>CONTENT_TYPE</c><c>Specifies payload encoding.</c><c>Integer</c><c>This document</c>

      <c>0x03</c><c>CBOR_PAYLOAD</c><c>Payload encoded as CBOR.</c><c>CBOR data item</c><c>This document</c>

      <c>0x20</c><c>TOPIC</c><c>Subscription topic for OBSERVE.</c><c>UTF-8 string</c><c>This document</c>

      <c>0x21</c><c>CONDITION</c><c>Trigger condition for OBSERVE.</c><c>UTF-8 or CBOR</c><c>This document</c>

      <c>0x22</c><c>ERROR_CODE</c><c>Error code returned in TELL(error).</c><c>Integer</c><c>This document</c>

      <c>0xFF</c><c>CANCEL_SUBSCRIPTION</c><c>Explicit termination of OBSERVE subscription.</c><c>Empty</c><c>This document</c>
    </texttable>

    <t>Future extensions MUST NOT assign new semantics to existing TLV values.</t>
  </section>

  <!-- ========================================== -->
  <!-- 7.2 µACP QoS Codes Registry                 -->
  <!-- ========================================== -->

  <section title="µACP QoS Codes Registry" anchor="iana-qos">
    <t>IANA is requested to create a registry entitled "µACP QoS Codes". QoS is encoded as a 2-bit field in the header (values 0–3).</t>

    <texttable anchor="qos-registry">
      <ttcol>Value</ttcol><ttcol>Name</ttcol><ttcol>Description</ttcol><ttcol>Reference</ttcol>

      <c>0</c><c>FIRE_AND_FORGET</c><c>No reliability; mapped to CoAP NON.</c><c>This document</c>

      <c>1</c><c>AT_LEAST_ONCE</c><c>Retransmissions required; mapped to CoAP CON.</c><c>This document</c>

      <c>2</c><c>AT_MOST_ONCE</c><c>No retransmission; mapped to CoAP NON.</c><c>This document</c>

      <c>3</c><c>RESERVED</c><c>Reserved for future use.</c><c>This document</c>
    </texttable>
  </section>

  <!-- ========================================== -->
  <!-- 7.3 µACP Verb Codes Registry               -->
  <!-- ========================================== -->

  <section title="µACP Verb Codes Registry" anchor="iana-verbs">
    <t>IANA is requested to create a registry entitled "µACP Verb Codes". Verb values occupy 2 bits but are listed numerically (0–3).</t>

    <texttable anchor="verb-registry">
      <ttcol>Value</ttcol><ttcol>Name</ttcol><ttcol>Description</ttcol><ttcol>Reference</ttcol>

      <c>0</c><c>PING</c><c>Liveness probe.</c><c>This document</c>

      <c>1</c><c>TELL</c><c>State update, notification, or response.</c><c>This document</c>

      <c>2</c><c>ASK</c><c>Request for information or action.</c><c>This document</c>

      <c>3</c><c>OBSERVE</c><c>Subscription to events or state changes.</c><c>This document</c>
    </texttable>
  </section>

  <!-- ========================================== -->
  <!-- 7.4 µACP Error Codes Registry               -->
  <!-- ========================================== -->

  <section title="µACP Error Codes Registry" anchor="iana-errors">
    <t>IANA is requested to create a registry entitled "µACP Error Codes" consisting of integers 0–255.</t>

    <t>The initial contents are listed in the Error Handling section. The assignment policy for values 0–127 is IETF Review. Values 128–255 are vendor-specific and use the "First Come First Served" policy.</t>
  </section>

  <!-- ========================================== -->
  <!-- 7.5 CoAP Content-Format Registration        -->
  <!-- ========================================== -->

  <section title="CoAP Content-Format Registration" anchor="iana-coap">
    <t>IANA is requested to register the following CoAP Content-Format:</t>

    <texttable anchor="coap-cf">
      <ttcol>Name</ttcol><ttcol>Media Type</ttcol><ttcol>Encoding</ttcol><ttcol>ID</ttcol><ttcol>Reference</ttcol>

      <c>application/muacp+binary</c>
      <c>application/muacp+binary</c>
      <c>Binary</c>
      <c>TBD (to be assigned by IANA)</c>
      <c>This document</c>
    </texttable>

    <t>This Content-Format is mandatory for all µACP-over-CoAP messages.</t>

    <t><strong>Note:</strong> The Content-Format ID value marked as "TBD" will be assigned by IANA during the IESG review process, prior to publication of this document as an RFC. The assignment will follow the "IETF Review" policy as specified in <xref target="RFC8126"/>.</t>
  </section>

  <!-- ========================================== -->
  <!-- 7.6 Media Type Registration                 -->
  <!-- ========================================== -->

  <section title="Media Type Registration" anchor="iana-media">
    <t>IANA is requested to register the following media type in the "application" registry:</t>

<t>
Type name: application<br/>
Subtype name: muacp+binary<br/>
Required parameters: none<br/>
Optional parameters: none<br/>
Encoding considerations: binary<br/>
Security considerations: See Security Considerations section.<br/>
Interoperability considerations: Defined by TLV and header structure.<br/>
Published specification: This document.<br/>
Intended usage: COMMON<br/>
Author/Change controller: IETF<br/>
</t>

  </section>

  <!-- ========================================== -->
  <!-- 7.7 Well-Known URIs for CoAP               -->
  <!-- ========================================== -->

  <section title="Well-Known CoAP Resource" anchor="iana-well-known">
    <t>IANA is requested to register the following CoAP Well-Known URI:</t>

    <texttable anchor="well-known-muacp">
      <ttcol>URI</ttcol><ttcol>Description</ttcol><ttcol>Reference</ttcol>

      <c>/.well-known/muacp</c>
      <c>Discovery resource indicating µACP support.</c>
      <c>This document</c>
    </texttable>

    <t>A CoAP GET to /.well-known/muacp SHOULD return a CBOR structure describing supported TLVs, maximum sizes, and supported versions.</t>
  </section>

  <!-- ========================================== -->
  <!-- 7.8 Summary                                 -->
  <!-- ========================================== -->

  <section title="Summary of IANA Actions" anchor="iana-summary">
    <t>IANA is requested to:</t>

    <ul>
      <li>Create the µACP TLV Types registry and populate initial values.</li>
      <li>Create the µACP QoS Codes registry.</li>
      <li>Create the µACP Verb Codes registry.</li>
      <li>Create the µACP Error Codes registry.</li>
      <li>Register the CoAP Content-Format application/muacp+binary.</li>
      <li>Register the media type application/muacp+binary.</li>
      <li>Register the well-known CoAP resource /.well-known/muacp.</li>
    </ul>

    <t>These actions enable interoperable deployment of µACP across implementations and ensure long-term extensibility under IETF governance.</t>
  </section>

</section>
<section title="State Machines and Processing Logic" anchor="state-machines">
  <t>This section defines the normative finite-state machines (FSMs) governing the behavior of µACP conversations, including request/response cycles (ASK/TELL), subscriptions (OBSERVE), and health checks (PING). Implementations MUST implement the FSMs defined here to ensure deterministic, interoperable behavior across devices and deployments.</t>

  <t>State machines are expressed using ASCII-art diagrams with labeled transitions and MUST be interpreted normatively. When timing behavior is required, timers MUST be implemented with bounded CPU and memory overhead suitable for constrained devices.</t>

  <!-- ======================================== -->
  <!-- 8.1 General Processing Model              -->
  <!-- ======================================== -->

  <section title="General Event Processing Model" anchor="general-processing">
    <t>Agents operate according to a deterministic event loop:</t>
    <ul>
      <li>Receive µACP message</li>
      <li>Validate OSCORE (if required)</li>
      <li>Validate header, TLVs, and payload</li>
      <li>Identify conversation via Correlation ID</li>
      <li>Execute verb-specific FSM transition</li>
      <li>Emit resulting messages (if any)</li>
    </ul>

    <t>Agents MUST support at least 64 concurrent conversations and MUST reject new conversations if resource ceilings are exceeded (ERR_RESOURCE_EXHAUSTED).</t>
  </section>

  <!-- ======================================== -->
  <!-- 8.2 ASK/TELL Conversation FSM            -->
  <!-- ======================================== -->

  <section title="ASK/TELL Conversation State Machine" anchor="ask-tell-fsm">
    <t>The ASK/TELL FSM governs synchronous (or quasi-synchronous) exchanges where one party issues a request and the peer returns a response. ASK MUST initiate a conversation. TELL completes it.</t>

    <figure anchor="fsm-ask-tell">
      <name>Figure 8: ASK/TELL State Machine</name>
      <artwork><![CDATA[
                   +-----------------+
                   |   IDLE          |
                   +-----------------+
                            |
                            | (send ASK)
                            v
                   +-----------------+
                   |   WAIT_RESP     |
                   +-----------------+
                     |        ^
     (recv TELL)     |        | (timeout; QoS=1)
                     v        |
                   +-----------------+
                   |   COMPLETED     |
                   +-----------------+
      (cleanup) --> returns to IDLE
      ]]></artwork>
    </figure>

    <t>State definitions:</t>

    <ul>
      <li><strong>IDLE:</strong> No active conversation for this Correlation ID. Sender may emit ASK to enter WAIT_RESP.</li>

      <li><strong>WAIT_RESP:</strong> ASK has been sent; awaiting TELL.  
        <ul>
          <li>If TELL received → transition to COMPLETED.</li>
          <li>If timer expires and QoS=1 → retransmit ASK and reset timer.</li>
          <li>If timer expires and QoS=0 or QoS=2 → transition to COMPLETED with ERR_TIMEOUT.</li>
        </ul>
      </li>

      <li><strong>COMPLETED:</strong> Final state.  
        <ul>
          <li>Conversation table entry MUST be deleted.</li>
        </ul>
      </li>
    </ul>

    <t>Receiver behavior is symmetric: upon receiving ASK, it enters a SERVE_REQ transient state, computes a response, and emits a TELL message. Errors (malformed request, unauthorized action, resource exhaustion) MUST produce a TELL(error) instead of silence.</t>
  </section>

  <!-- ======================================== -->
  <!-- 8.3 PING/TELL State Machine              -->
  <!-- ======================================== -->

  <section title="PING/TELL State Machine" anchor="ping-fsm">
    <t>PING serves as a minimal liveness check. PING does not create long-lived conversation state and SHOULD remain extremely lightweight.</t>

    <figure anchor="fsm-ping">
      <name>Figure 9: PING/TELL Liveness FSM</name>
      <artwork><![CDATA[
        +--------+
        |  IDLE  |
        +--------+
            |
            | send PING
            v
        +--------------+
        | WAIT_PONG    |
        +--------------+
            |        ^
   recv TELL|        | timeout (SHOULD NOT retransmit)
            v        |
        +--------------+
        |  COMPLETED   |
        +--------------+
      ]]></artwork>
    </figure>

    <t>Key requirements:</t>

    <ul>
      <li>PING MUST NOT require OSCORE.</li>
      <li>PING MUST NOT modify application state.</li>
      <li>Receivers SHOULD reply with TELL unless explicitly configured otherwise.</li>
      <li>Timeout MUST NOT cause retransmissions (congestive safety).</li>
    </ul>
  </section>

  <!-- ======================================== -->
  <!-- 8.4 OBSERVE Subscription FSM             -->
  <!-- ======================================== -->

  <section title="OBSERVE Subscription State Machine" anchor="observe-fsm">
    <t>OBSERVE establishes a long-lived subscription used for event-driven communication. Subscription state MUST be explicitly tracked and MUST enforce resource ceilings.</t>

    <figure anchor="fsm-observe">
      <name>Figure 10: OBSERVE Subscription FSM</name>
      <artwork><![CDATA[
                         +----------------+
                         |   NO_SUB       |
                         +----------------+
                                |
                                | (recv OBSERVE)
                                v
                         +----------------+
                         |  SUBSCRIBED    |
                         +----------------+
                                |
                                | (event trigger)
                                v
                         +----------------+
                         | NOTIFY (TELL)  |
                         +----------------+
                                |
                                | (recv CANCEL_SUB)
                                v
                         +----------------+
                         |  TERMINATED    |
                         +----------------+
                          cleanup → NO_SUB
      ]]></artwork>
    </figure>

    <t>State definitions:</t>

    <ul>
      <li><strong>NO_SUB:</strong> No subscription exists for this Correlation ID. Receiving OBSERVE creates subscription state.</li>

      <li><strong>SUBSCRIBED:</strong> Active subscription.  
        <ul>
          <li>Trigger conditions (TLVs) MUST be monitored.</li>
          <li>Subscription MUST expire after configured lifetime unless refreshed.</li>
          <li>Resource limits MUST be enforced (max subscriptions per peer).</li>
        </ul>
      </li>

      <li><strong>NOTIFY:</strong> When trigger conditions are met, a TELL message MUST be sent.  
        <ul>
          <li>Notifications MUST NOT be sent faster than congestion-control rules permit.</li>
        </ul>
      </li>

      <li><strong>TERMINATED:</strong> Subscription canceled via CANCEL_SUB (TLV=0xFF) or due to resource exhaustion.  
        <ul>
          <li>All subscription state MUST be deleted.</li>
        </ul>
      </li>
    </ul>
  </section>

  <!-- ======================================== -->
  <!-- 8.5 Error-State Transitions              -->
  <!-- ======================================== -->

  <section title="Error-State Transitions" anchor="error-fsm">
    <t>Errors encountered during processing MUST transition the FSM into a predictable termination state. This prevents deadlocks and resource leaks.</t>

    <ul>
      <li><strong>ERR_MALFORMED:</strong> Immediately discard message; no state created; MAY send error TELL.</li>

      <li><strong>ERR_UNSUPPORTED_TLV:</strong> Terminate the offending conversation; MUST send error TELL.</li>

      <li><strong>ERR_TIMEOUT:</strong> Conversation enters COMPLETED with error; resources MUST be freed.</li>

      <li><strong>ERR_RESOURCE_EXHAUSTED:</strong> Reject request; MUST NOT allocate new conversation state.</li>

      <li><strong>OSCORE failure:</strong> Silent discard; MUST NOT leak metadata; MUST NOT update state.</li>
    </ul>
  </section>

  <!-- ======================================== -->
  <!-- 8.6 Processing Time and Resource Bounds  -->
  <!-- ======================================== -->

  <section title="Processing Time and Resource Bounds" anchor="resource-bounds">
    <t>Because µACP targets constrained environments, all FSM transitions MUST complete in bounded time and memory.</t>

    <t>The following limits apply:</t>
    <ul>
      <li>Conversation table: MUST support at least 64 active conversations.</li>
      <li>Subscription table: MUST support at least 16 active OBSERVE subscriptions.</li>
      <li>Per-message processing time: MUST complete within platform-defined real-time bounds.</li>
      <li>Message buffers: MUST have deterministic maximum sizes (header+1024-byte TLVs+payload).</li>
      <li>Timers: MUST be implemented without per-message dynamic allocation.</li>
    </ul>

    <t>Platforms MAY employ preallocated memory pools, cyclic buffers, or static tables to satisfy the above constraints.</t>
  </section>

  <!-- ======================================== -->
  <!-- 8.7 Summary of FSM Requirements          -->
  <!-- ======================================== -->

  <section title="Summary of Normative FSM Behavior" anchor="fsm-summary">
    <ul>
      <li>ASK MUST initiate a conversation; TELL MUST complete it.</li>
      <li>PING MUST remain stateless and congestion-safe.</li>
      <li>OBSERVE MUST create explicit subscription state and enforce resource ceilings.</li>
      <li>All FSMs MUST terminate in bounded time.</li>
      <li>OSCORE failures MUST be silent but MUST NOT permit partial state updates.</li>
      <li>Errors MUST produce deterministic transitions to safe terminal states.</li>
    </ul>

    <t>The FSMs in this section define the interoperable processing model for all conformant µACP agents.</t>
  </section>

</section>
<section title="Security Considerations" anchor="security">
  <t>This section defines the security properties, assumptions, and mandatory mitigations for µACP. Because µACP targets severely resource-constrained devices, the protocol does not embed cryptographic primitives directly; instead, it relies on OSCORE and the underlying transport for security. All implementations MUST follow the requirements in this section to avoid exposure to denial-of-service, spoofing, downgrade, replay, or privacy attacks.</t>

  <!-- ===================================== -->
  <!-- 9.1 Threat Model                      -->
  <!-- ===================================== -->

  <section title="Threat Model" anchor="threat-model">
    <t>The µACP threat model assumes that attackers may:</t>
    <ul>
      <li>Passively eavesdrop on traffic.</li>
      <li>Modify, inject, reorder, or replay messages.</li>
      <li>Attempt to exhaust memory, CPU, storage, energy, or subscription tables.</li>
      <li>Attempt to desynchronize conversation or subscription state.</li>
      <li>Conduct traffic analysis to infer system behavior.</li>
      <li>Attempt version downgrades or feature-stripping attacks.</li>
      <li>Exploit weak random number generation for Correlation IDs.</li>
      <li>Exploit incorrect OSCORE configuration (e.g., key reuse, replay window misconfiguration).</li>
    </ul>

    <t>The protocol provides security <strong>only</strong> when implemented with OSCORE as defined in the Transport Binding section. Attackers are assumed to have full control of the transport layer but not of OSCORE-protected channels.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.2 Authentication and Integrity       -->
  <!-- ===================================== -->

  <section title="Authentication, Integrity, and Identity Binding" anchor="authn">
    <t>All µACP messages except PING MUST be authenticated and integrity-protected using OSCORE. Without OSCORE, µACP messages MUST be considered untrusted and MUST NOT modify system state.</t>

    <t>OSCORE provides:</t>
    <ul>
      <li>Peer authentication (when derived from EDHOC or provisioned credentials),</li>
      <li>Integrity protection over header, TLVs, and payload,</li>
      <li>Replay protection through sequence numbers and replay windows,</li>
      <li>Binding of request/response messages.</li>
    </ul>

    <t>Implementations MUST use a unique OSCORE security context per communicating peer. Context reuse risks identity substitution or multi-peer cross-contamination attacks.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.3 Confidentiality and Access Control -->
  <!-- ===================================== -->

  <section title="Confidentiality and Access Control" anchor="confidentiality">
    <t>TELL, ASK, and OBSERVE messages MAY contain sensitive or mission-critical data. These messages MUST be encrypted via OSCORE. Only PING is permitted to be unencrypted.</t>

    <t>Authorization MUST be enforced at the receiving agent before performing operations triggered by ASK or OBSERVE. Unauthorized or unauthenticated requests MUST be rejected using ERR_FORBIDDEN or silently dropped in high-threat environments.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.4 Replay and Freshness Protection   -->
  <!-- ===================================== -->

  <section title="Replay Prevention and Freshness" anchor="replay">
    <t>µACP relies on OSCORE replay protection. Implementations MUST enable and correctly maintain OSCORE replay windows. Message Sequence IDs and Correlation IDs do not substitute for OSCORE's replay mechanism.</t>

    <t>Additional replay mitigations:</t>
    <ul>
      <li>Receivers SHOULD maintain a per-peer sliding window of recent Sequence IDs.</li>
      <li>Subscription-triggered notifications MUST validate freshness before emitting updates.</li>
      <li>Agents MUST reject delayed or reordered messages if OSCORE replay windows indicate a stale nonce.</li>
    </ul>

    <t>Failure to enforce replay semantics MAY allow repeated actions, unexpected state transitions, or resource exhaustion.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.5 DoS and Resource Exhaustion       -->
  <!-- ===================================== -->

  <section title="Denial-of-Service and Resource Exhaustion" anchor="dos">
    <t>µACP devices frequently operate with strict limits on memory, CPU cycles, and energy. Attackers may attempt to exploit this by flooding the device with requests, subscriptions, or malformed messages. Implementations MUST enforce:</t>

    <ul>
      <li>Maximum number of active conversations (minimum 64 required).</li>
      <li>Maximum number of OBSERVE subscriptions (minimum 16 required).</li>
      <li>Rate limits on incoming PING and ASK messages.</li>
      <li>TLV region size limits (max 1024 bytes).</li>
      <li>Payload size limits (max 65535 bytes).</li>
      <li>Static or preallocated memory pools for message buffers.</li>
    </ul>

    <t>When limits are exceeded, agents MUST return ERR_RESOURCE_EXHAUSTED or silently drop messages depending on congestion severity.</t>

    <t>CoAP-level DoS mitigation (exponential backoff, NON vs CON behavior) MUST also be applied per Section 5.7.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.6 Subscription Hijacking            -->
  <!-- ===================================== -->

  <section title="Subscription Hijacking and Notification Integrity" anchor="sub-hijack">
    <t>OBSERVE introduces long-lived state which attackers may exploit. To prevent hijacking or unauthorized cancellation:</t>

    <ul>
      <li>OBSERVE and CANCEL_SUB MUST be OSCORE-protected.</li>
      <li>Subscriptions MUST be bound to an authenticated OSCORE context.</li>
      <li>Correlation IDs MUST be unpredictable to prevent guessing active subscription identifiers.</li>
      <li>Subscription deletion MUST require either:
        <ul>
          <li>a valid CANCEL_SUB message from the same authenticated peer, OR</li>
          <li>timeout or resource exhaustion constraints documented by the implementation.</li>
        </ul>
      </li>
      <li>Agents MUST reject subscription attempts that exceed configured resource ceilings.</li>
    </ul>

    <t>Failure to enforce these rules could allow attackers to redirect notifications, silence alarms, or manipulate event-driven logic.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.7 Downgrade and Version Attacks     -->
  <!-- ===================================== -->

  <section title="Downgrade Protection and Version Attacks" anchor="downgrade-protection">
    <t>The Version TLV enables forward compatibility but introduces risks of downgrade attacks. Implementations MUST enforce:</t>

    <ul>
      <li>The highest mutually supported version MUST be used.</li>
      <li>Version negotiation MUST occur under OSCORE, except for PING.</li>
      <li>Agents MUST reject messages that advertise only unsupported versions.</li>
      <li>Agents MUST NOT fall back silently to lower versions.</li>
    </ul>

    <t>This prevents attackers from forcing devices into insecure or deprecated protocol variants.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.8 Privacy Considerations            -->
  <!-- ===================================== -->

  <section title="Privacy Considerations" anchor="privacy">
    <t>µACP messages may reveal operational state, environmental conditions, unique identifiers, or system topology. OSCORE encryption mitigates most risks, but implementations MUST also consider:</t>

    <ul>
      <li>Correlation IDs must not encode identifying information.</li>
      <li>Payloads should avoid transmitting sensitive or personal data unnecessarily.</li>
      <li>Event-driven OBSERVE notifications may reveal behavioral patterns; rate-limiting reduces leakage.</li>
      <li>Well-known URIs may expose protocol usage; returning minimal metadata is RECOMMENDED.</li>
    </ul>

    <t>Applications MAY use additional payload encryption or anonymization when required by operational policies or regulations.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.9 Traffic Analysis                  -->
  <!-- ===================================== -->

  <section title="Traffic Analysis Resistance" anchor="traffic-analysis">
    <t>Even with OSCORE, attackers may observe message size, frequency, or timing patterns. Implementations SHOULD mitigate traffic analysis when possible:</t>

    <ul>
      <li>PING rates should be bounded and randomized.</li>
      <li>Regular padding of OSCORE ciphertext MAY be used, subject to energy constraints.</li>
      <li>OBSERVE notifications SHOULD avoid revealing high-frequency activity in sensitive deployments.</li>
    </ul>

    <t>Because µACP operates in constrained environments, padding and obfuscation are OPTIONAL but SHOULD be supported in deployments requiring stronger protection.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.10 Key Management                   -->
  <!-- ===================================== -->

  <section title="Key Management and Lifecycle" anchor="key-management">
    <t>OSCORE security depends on proper management of key material. Implementations MUST provide:</t>

    <ul>
      <li>Secure key provisioning (EDHOC, pre-shared keys, or manufacturing-time injection).</li>
      <li>Rotation of OSCORE master secrets on a schedule appropriate for device lifetime.</li>
      <li>Secure deletion of expired or unused keys.</li>
      <li>Protection against key reuse across unrelated peers.</li>
      <li>Protection of key material against side-channel extraction on constrained hardware.</li>
    </ul>

    <t>Compromise of OSCORE keys compromises confidentiality, integrity, and authentication for µACP messages.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.11 Safe Failure Modes               -->
  <!-- ===================================== -->

  <section title="Safe Failure Modes" anchor="safe-failure">
    <t>Failures MUST NOT cause inconsistent or undefined agent behavior. Specifically:</t>

    <ul>
      <li>Malformed messages MUST be discarded without modifying state.</li>
      <li>OSCORE failures MUST be silent and MUST NOT produce error messages that could be used for oracle attacks.</li>
      <li>Timeouts MUST clean up state deterministically.</li>
      <li>Subscription state MUST never persist without authenticated refresh.</li>
    </ul>

    <t>In safety-critical systems (e.g., water infrastructure, industrial IoT), safe fallback behavior SHOULD be validated through formal analysis or runtime verification.</t>
  </section>

  <!-- ===================================== -->
  <!-- 9.12 Summary                          -->
  <!-- ===================================== -->

  <section title="Summary of Security Requirements" anchor="security-summary">
    <t>µACP security depends critically on the use of OSCORE and strict adherence to this section’s requirements. At a minimum:</t>

    <ul>
      <li>All messages except PING MUST be OSCORE-protected.</li>
      <li>Replay windows MUST be enforced.</li>
      <li>Subscriptions MUST be authenticated and bounded.</li>
      <li>Resource ceilings MUST be applied to prevent DoS.</li>
      <li>Version negotiation MUST resist downgrade.</li>
      <li>Malformed inputs MUST NOT affect state.</li>
      <li>Key management MUST follow secure lifecycle practices.</li>
    </ul>

    <t>Failure to follow any of these requirements may enable attackers to compromise µACP deployments.</t>
  </section>

</section>
<section title="Interoperability and Deployment Profiles" anchor="interop">
  <t>This section defines the minimum feature set required for interoperability between µACP implementations, along with deployment profiles tailored to different classes of devices and networks. All compliant implementations MUST satisfy the baseline profile and SHOULD support additional profiles where appropriate.</t>

  <!-- ========================================= -->
  <!-- 10.1 Minimum Interoperability Profile      -->
  <!-- ========================================= -->

  <section title="Minimum Interoperability Profile (MIP)" anchor="mip">
    <t>The Minimum Interoperability Profile defines the set of features all µACP agents MUST implement. These requirements ensure that any two µACP-compliant endpoints can communicate reliably and securely.</t>

    <t>Implementations MUST support:</t>

    <ul>
      <li>The µACP 64-bit header format.</li>
      <li>All four verbs: PING, TELL, ASK, and OBSERVE.</li>
      <li>The TLV processing model (including ordering, ignoring unknown TLVs, and size limits).</li>
      <li>The mandatory OSCORE/CoAP transport binding.</li>
      <li>Content-Format application/muacp+binary.</li>
      <li>Conversation state for at least 64 active Correlation IDs.</li>
      <li>Subscription state for at least 16 active OBSERVE subscriptions.</li>
      <li>Error-handling behavior as defined in the Error Handling section.</li>
      <li>Deterministic state-machine execution as defined in the State Machines section.</li>
      <li>Strict enforcement of TLV region and payload size bounds.</li>
    </ul>

    <t>Any implementation lacking one or more of the above cannot be considered µACP-compliant.</t>
  </section>

  <!-- ========================================= -->
  <!-- 10.2 Constrained Node Profile (CNP)        -->
  <!-- ========================================= -->

  <section title="Constrained Node Profile (CNP)" anchor="cnp">
    <t>The Constrained Node Profile targets microcontroller-class devices with severe limitations on RAM, energy, and CPU. Devices in this class typically include ARM Cortex-M series, ESP32, and similar embedded platforms.</t>

    <t>Implementations operating under the CNP MUST:</t>

    <ul>
      <li>Use static or preallocated memory buffers for message processing.</li>
      <li>Enforce strict upper bounds on subscription count, message buffers, and timers.</li>
      <li>Support fragmentation only when required by the underlying transport; otherwise, fragmentation SHOULD be disabled.</li>
      <li>Use compact TLVs and avoid optional features requiring large buffers.</li>
      <li>Perform minimal logging to avoid overhead.</li>
      <li>Restrict payload sizes to what can be safely processed on the platform.</li>
    </ul>

    <t>Implementations SHOULD:</t>

    <ul>
      <li>Use simplified state machines optimized for deterministic resource usage.</li>
      <li>Prefer PSK- or EDHOC-based OSCORE contexts instead of heavier PKI-based provisioning.</li>
      <li>Disable or heavily restrict vendor-specific TLVs.</li>
    </ul>
  </section>

  <!-- ========================================= -->
  <!-- 10.3 Infrastructure Node Profile (INP)     -->
  <!-- ========================================= -->

  <section title="Infrastructure Node Profile (INP)" anchor="inp">
    <t>The Infrastructure Node Profile targets devices with moderate-to-high resources such as edge gateways, industrial controllers, and cloud-side collectors. These nodes typically support more extensive logic and higher traffic volumes.</t>

    <t>Implementations under this profile MUST:</t>

    <ul>
      <li>Support full subscription features including complex event conditions.</li>
      <li>Support extended TLV sets and vendor-specific extensions.</li>
      <li>Maintain replay windows sized for high-throughput communication.</li>
      <li>Support EDHOC or equivalent authenticated key exchange mechanisms.</li>
      <li>Provide robust error-logging and diagnostics.</li>
      <li>Support rate-shaping for downstream constrained nodes.</li>
    </ul>

    <t>INP nodes MAY:</t>

    <ul>
      <li>Provide protocol translation (e.g., convert µACP/OSCORE-CoAP to internal RPC or message bus formats).</li>
      <li>Use hardware acceleration for crypto operations when available.</li>
      <li>Implement adaptive batching or aggregation of TELL notifications for efficiency.</li>
    </ul>
  </section>

  <!-- ========================================= -->
  <!-- 10.4 Cross-Profile Interoperability        -->
  <!-- ========================================= -->

  <section title="Cross-Profile Interoperability" anchor="cross-interop">
    <t>µACP is designed to allow interoperability between constrained and infrastructure nodes. The following rules ensure safe cross-profile communication:</t>

    <ul>
      <li>Messages sent from INP nodes MUST adhere to the resource ceilings of peer CNP nodes.</li>
      <li>INP nodes MUST NOT send payloads or TLVs exceeding the max supported size of constrained nodes.</li>
      <li>INP nodes SHOULD apply traffic shaping to avoid overwhelming constrained devices.</li>
      <li>CNP nodes MUST ignore unsupported TLVs without entering error states.</li>
      <li>CNP nodes MAY restrict OBSERVE features to static or simple triggers.</li>
      <li>Fallback to the Minimum Interoperability Profile MUST always be possible.</li>
    </ul>

    <t>Implementations MUST guarantee that all profile interactions preserve the security properties defined in the Security Considerations section.</t>
  </section>

  <!-- ========================================= -->
  <!-- 10.5 Deployment Profiles                   -->
  <!-- ========================================= -->

  <section title="Deployment Profiles" anchor="deployment-profiles">
    <t>Deployments may apply µACP in different operational environments. This subsection defines three common deployment profiles and associated requirements.</t>

    <section title="Low-Power Wide-Area Networks (LPWAN)" anchor="lpwan">

    <t>Examples include NB-IoT, LoRaWAN, Sigfox.</t>

    <ul>
      <li>Message size limits are strict; fragmentation SHOULD be avoided.</li>
      <li>OBSERVE triggers SHOULD be sparse and batched when possible.</li>
      <li>Ask/Tell round trips MUST consider high RTT variability.</li>
      <li>OSCORE contexts SHOULD minimize nonce overhead.</li>
    </ul>
    </section>

    <section title="Industrial / SCADA Systems" anchor="scada">

    <ul>
      <li>Implementations MUST ensure real-time processing guarantees.</li>
      <li>OBSERVE notifications MUST comply with predictable timing windows.</li>
      <li>Extended diagnostics and telemetry SHOULD be enabled.</li>
      <li>Security posture MUST disallow unencrypted traffic entirely (PING included).</li>
    </ul>
    </section>

    <section title="Edge-to-Cloud Distributed Systems" anchor="edgecloud">

    <ul>
      <li>INP nodes may aggregate µACP messages for cloud ingestion.</li>
      <li>End-to-end OSCORE MUST remain intact through intermediaries.</li>
      <li>Topology and addressing metadata SHOULD NOT leak at intermediaries.</li>
      <li>Periodic key rotation SHOULD be aligned with cloud-side policy.</li>
    </ul>
    </section>
  </section>

  <section title="Feature Negotiation" anchor="feature-negotiation">
    <t>Feature discovery occurs using a GET request to the well-known resource <tt>/.well-known/muacp</tt>. The response SHOULD include a CBOR map containing:</t>

    <ul>
      <li>Maximum TLV size supported</li>
      <li>Maximum payload size</li>
      <li>Supported TLV types</li>
      <li>Supported verbs (always all four)</li>
      <li>Supported µACP versions</li>
      <li>Supported congestion control modes</li>
    </ul>

    <t>Nodes SHOULD cache feature negotiation results until expiration or reboot.</t>
  </section>

  <!-- ========================================= -->
  <!-- 10.7 Deterministic Fallback Behavior      -->
  <!-- ========================================= -->

  <section title="Deterministic Fallback Behavior" anchor="fallback">
    <t>To guarantee interoperability even when nodes support different feature sets, µACP defines the following fallback rules:</t>

    <ul>
      <li>Unknown TLVs MUST be ignored.</li>
      <li>Unsupported features MUST degrade to MIP (Minimum Interoperability Profile).</li>
      <li>Subscription requests exceeding CNP limits MUST return ERR_RESOURCE_EXHAUSTED.</li>
      <li>If version negotiation fails, agents MUST return ERR_VERSION_MISMATCH.</li>
      <li>If congestion control features are unsupported, agents MUST revert to CoAP default mechanisms.</li>
    </ul>

    <t>Fallback MUST preserve safety and integrity, even if advanced features are unavailable.</t>
  </section>

  <!-- ========================================= -->
  <!-- 10.8 Summary                              -->
  <!-- ========================================= -->

  <section title="Summary of Interoperability Requirements" anchor="interop-summary">
    <t>µACP interoperability depends on:</t>

    <ul>
      <li>Universal support for the Minimum Interoperability Profile.</li>
      <li>Profiles for constrained nodes and infrastructure nodes.</li>
      <li>Deterministic FSM processing as defined in the State Machines section.</li>
      <li>Mandatory OSCORE/CoAP transport.</li>
      <li>Safe fallback when encountering unsupported features.</li>
      <li>Strict enforcement of resource ceilings.</li>
    </ul>

    <t>These requirements ensure reliable communication across heterogeneous ecosystems, from microcontroller devices to large-scale industrial or cloud deployments.</t>
  </section>

</section>

<section title="Wire Examples" anchor="wire-examples">
  <t>This section provides complete, normative examples of µACP messages on the wire. Examples include raw µACP binary encodings, CBOR-embedded payloads, OSCORE-protected CoAP envelopes, and OBSERVE subscription exchanges. All examples use placeholder keys and nonces for illustration only.</t>

  <t>Byte order is network byte order (big-endian). Hexadecimal text is for illustration; actual deployments use binary encodings.</t>

  <!-- ===================================== -->
  <!-- 11.1 Notation                          -->
  <!-- ===================================== -->

  <section title="Notation" anchor="wire-notation">
    <t>The examples below use the following conventions:</t>

    <ul>
      <li><strong>H:</strong> µACP Header (64 bits)</li>
      <li><strong>Tn:</strong> nth TLV (Type-Length-Value)</li>
      <li><strong>P:</strong> Payload</li>
      <li><strong>C:</strong> CoAP envelope</li>
      <li><strong>OS:</strong> OSCORE encryption wrapper</li>
      <li><strong>CBOR[...]</strong>: CBOR structure encoded into bytes</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 11.2 Example 1: Minimal PING          -->
  <!-- ===================================== -->

  <section title="Minimal PING (unencrypted)" anchor="ping-example">
    <t>A minimal PING contains only the µACP header and MUST NOT be OSCORE-protected.</t>

    <figure>
      <name>Example 1: PING (Hex)</name>
      <artwork><![CDATA[
H = 00 01   # Sequence ID = 1
    00 01   # Correlation ID = 1
    00      # QoS = 0 (fire-and-forget)
    00      # Verb = 0 (PING)
    00      # Flags = 0
    00 00 00 00 00   # Reserved
      ]]></artwork>
    </figure>

    <t>No TLVs, no payload.</t>
  </section>

  <!-- =========================================== -->
  <!-- 11.3 Example 2: ASK with CBOR Payload       -->
  <!-- =========================================== -->

  <section title="ASK with CBOR Payload (unprotected example)" anchor="ask-cbor">
    <t>This example shows an ASK containing a CBOR payload before OSCORE protection is applied.</t>

    <t>CBOR payload representation:</t>
    <figure>
      <artwork><![CDATA[
CBOR = { "action": "read", "resource": "temperature" }
CBOR (hex) = A2 66 61 63 74 69 6F 6E 64 72 65 61 64
                 68 72 65 73 6F 75 72 63 65 6A 74 65 6D 70
      ]]></artwork>
    </figure>

    <t>Message:</t>
    <figure>
      <name>Example 2: ASK (Hex)</name>
      <artwork><![CDATA[
H  = 10 02   # SeqID=0x1002
     10 02   # CorrID=0x1002
     40      # QoS=1 (at-least-once)
     20      # Verb=2 (ASK)
     00      # Flags
     00 00 00 00 00

T1 = 03 1A  A2 66 61 63 ... 70
     |  |   |
   Type Len  CBOR data (26 bytes)

Final (pre-OSCORE) encoding:
10 02 10 02 40 20 00 00 00 00
03 1A A2 66 61 63 ... 70
      ]]></artwork>
    </figure>
  </section>

  <!-- =========================================== -->
  <!-- 11.4 Example 3: ASK/TELL Exchange with OSCORE -->
  <!-- =========================================== -->

  <section title="ASK/TELL over OSCORE" anchor="ask-tell-oscore">
    <t>This example illustrates a complete OSCORE-protected request/response using CoAP POST.</t>

    <t><strong>Step 1 — ASK wrapped in CoAP + OSCORE:</strong></t>

    <figure>
      <name>Example 3a: CoAP Envelope (ASK)</name>
      <artwork><![CDATA[
CoAP Header:
  44 02 7A 10        # CON, POST, MID=0x7A10
Uri-Path: "muacp"
Content-Format: application/muacp+binary
OSCORE Option: 9F (example)
Payload (ciphertext):
  d4 83 58 20 a1 b3 11 ... (encrypted µACP)
      ]]></artwork>
    </figure>

    <t><strong>Step 2 — TELL response:</strong></t>

    <figure>
      <name>Example 3b: CoAP Envelope (TELL Response)</name>
      <artwork><![CDATA[
CoAP Header:
  64 44 7A 10        # ACK, 2.04 Changed
Payload (ciphertext):
  e1 91 3A 0F 90 ... (encrypted TELL)
      ]]></artwork>
    </figure>
  </section>

  <!-- =========================================== -->
  <!-- 11.5 Example 4: OBSERVE Subscription        -->
  <!-- =========================================== -->

  <section title="OBSERVE Subscription (OSCORE-protected)" anchor="observe-example">
    <t>This example shows how an OBSERVE message establishes a subscription.</t>

    <figure>
      <name>Example 4: OBSERVE (Hex)</name>
      <artwork><![CDATA[
H  = 20 05 20 05 40 30 00 00 00 00  # Verb=3 (OBSERVE)

T1 = 20 03 74 65 6D                 # Topic="tem"

OSCORE-protected payload:
  58 2A 95 B2 11 D9 ...             # ciphertext
      ]]></artwork>
    </figure>

    <t>Subsequent notifications are sent as TELL messages sharing the Correlation ID 0x2005.</t>
  </section>

  <!-- =========================================== -->
  <!-- 11.6 Example 5: CANCEL_SUB (TLV=0xFF)       -->
  <!-- =========================================== -->

  <section title="Subscription Cancellation" anchor="cancel-example">
    <t>A peer cancels an active subscription by sending CANCEL_SUB.</t>

    <figure>
      <name>Example 5: CANCEL_SUB (Hex)</name>
      <artwork><![CDATA[
H  = 20 05 20 05 40 30 00 00 00 00

T1 = FF 00   # CANCEL_SUB, empty TLV

OSCORE ciphertext:
  6A 7F A9 ... 
      ]]></artwork>
    </figure>
  </section>

  <!-- =========================================== -->
  <!-- 11.7 Example 6: Error TELL                  -->
  <!-- =========================================== -->

  <section title="Error TELL with Error-Code TLV" anchor="error-example">
    <t>This example shows a TELL(error) response containing ERR_UNSUPPORTED_TLV.</t>

    <figure>
      <name>Example 6: ERR_UNSUPPORTED_TLV</name>
      <artwork><![CDATA[
H  = 10 02 10 02 40 10 00 00 00 00  # Verb=TELL (1)

T1 = 22 01 03   # Error-Code TLV, Len=1, Value=0x03 (ERR_UNSUPPORTED_TLV)

Payload = (optional diagnostic string)

Encrypted via OSCORE:
  5F 21 8A E3 ... 
      ]]></artwork>
    </figure>
  </section>

  <!-- =========================================== -->
  <!-- 11.8 Example 7: µACP + CoAP Blockwise      -->
  <!-- =========================================== -->

  <section title="Fragmentation via CoAP Blockwise" anchor="blockwise">
    <t>µACP does not define native fragmentation but MAY rely on CoAP Blockwise Transfer (RFC 7959). The µACP message remains intact inside each CoAP block.</t>

    <t>Example (two blocks):</t>

    <figure>
      <name>Example 7: Blockwise Transfer</name>
      <artwork><![CDATA[
Block 0:
  CoAP Header + Block1 Option (NUM=0, M=1, SZX=2)
  Payload: µACP bytes [0..255]

Block 1:
  CoAP Header + Block1 Option (NUM=1, M=0, SZX=2)
  Payload: µACP bytes [256..end]
      ]]></artwork>
    </figure>

    <t>Receivers MUST reassemble blocks before OSCORE processing when the OSCORE option is Outer.</t>
  </section>

  <!-- =========================================== -->
  <!-- 11.9 Summary                                -->
  <!-- =========================================== -->

  <section title="Summary" anchor="wire-summary">
    <t>The examples in this section demonstrate:</t>

    <ul>
      <li>Minimal µACP messages.</li>
      <li>CBOR-encoded payloads.</li>
      <li>OSCORE-protected messages inside CoAP POST.</li>
      <li>Full ASK/TELL interaction.</li>
      <li>OBSERVE subscription and cancellation lifecycles.</li>
      <li>Error signaling via TELL(error).</li>
      <li>Fragmentation via CoAP Blockwise Transfer.</li>
    </ul>

    <t>These examples are normative for message formatting and MUST be used for interoperability testing.</t>
  </section>

</section>
<section title="Conformance Tests" anchor="conformance">
  <t>This section defines the normative conformance tests required to validate µACP implementations. A device or software stack MUST pass all tests in this section to be considered µACP-compliant. Implementations SHOULD additionally validate behavior against the wire examples.</t>

  <!-- ===================================== -->
  <!-- 12.1 Test Categories                   -->
  <!-- ===================================== -->

  <section title="Test Categories" anchor="test-categories">
    <t>Conformance tests are grouped into the following categories:</t>
    <ul>
      <li>Header and TLV Encoding Tests</li>
      <li>Parser Robustness and Error Handling Tests</li>
      <li>State-Machine Behavior Tests</li>
      <li>OSCORE Security Tests</li>
      <li>Replay and Freshness Tests</li>
      <li>Subscription Lifecycle Tests</li>
      <li>Resource Constraint Enforcement Tests</li>
      <li>Interoperability Tests</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.2 Header and TLV Encoding Tests     -->
  <!-- ===================================== -->

  <section title="Header and TLV Encoding Tests" anchor="header-tlv-tests">
    <t>Implementations MUST correctly encode and decode the 64-bit header and all mandatory TLV behaviors.</t>

    <ul>
      <li><strong>H1:</strong> Verify correct parsing of all header fields (Verb, QoS, Flags, Sequence ID, Correlation ID, Reserved).</li>
      <li><strong>H2:</strong> Reserved bits MUST be ignored on input and encoded as zero on output.</li>
      <li><strong>H3:</strong> TLV region length MUST NOT exceed 1024 bytes.</li>
      <li><strong>H4:</strong> Unknown TLV types MUST be ignored without entering an error state.</li>
      <li><strong>H5:</strong> TLV Length MUST be strictly respected; truncated TLVs MUST cause message rejection.</li>
      <li><strong>H6:</strong> TLV Type 0x00 (Raw Octets) MUST be rejected in OSCORE-protected messages.</li>
      <li><strong>H7:</strong> Test vectors in the Wire Examples section MUST decode successfully.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.3 Parser Robustness Tests           -->
  <!-- ===================================== -->

  <section title="Parser Robustness Tests" anchor="parser-tests">
    <t>Implementations MUST handle malformed or adversarial input safely and deterministically.</t>

    <ul>
      <li><strong>P1:</strong> Malformed headers MUST cause silent discard.</li>
      <li><strong>P2:</strong> Oversized payloads MUST be rejected with ERR_PAYLOAD_TOO_LARGE.</li>
      <li><strong>P3:</strong> Invalid TLV lengths MUST trigger ERR_MALFORMED_TLV.</li>
      <li><strong>P4:</strong> Excessive nested TLVs MUST NOT cause unbounded memory allocation.</li>
      <li><strong>P5:</strong> Invalid Verb codes MUST trigger ERR_UNSUPPORTED_VERB.</li>
      <li><strong>P6:</strong> Messages exceeding local memory capacity MUST trigger ERR_RESOURCE_EXHAUSTED.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.4 State-Machine Behavior Tests      -->
  <!-- ===================================== -->

  <section title="State-Machine Behavior Tests" anchor="fsm-tests">
    <t>Agents MUST implement the state machines defined in the State Machines section. These tests validate deterministic transitions.</t>

    <ul>
      <li><strong>FSM1:</strong> ASK MUST create a conversation and transition to WAIT_RESP.</li>
      <li><strong>FSM2:</strong> Receipt of TELL MUST transition the conversation to COMPLETED.</li>
      <li><strong>FSM3:</strong> Timeout behavior MUST match QoS semantics (QoS=1 → retransmit; QoS=0/2 → terminate).</li>
      <li><strong>FSM4:</strong> OBSERVE MUST create a subscription; notifications MUST reuse the Correlation ID.</li>
      <li><strong>FSM5:</strong> CANCEL_SUB MUST delete subscription state.</li>
      <li><strong>FSM6:</strong> PING MUST NOT allocate conversation state.</li>
      <li><strong>FSM7:</strong> Error conditions MUST terminate conversations deterministically.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.5 OSCORE Security Tests             -->
  <!-- ===================================== -->

  <section title="OSCORE Security Tests" anchor="oscore-tests">
    <t>Since µACP relies on OSCORE for security, implementations MUST pass all OSCORE-related checks.</t>

    <ul>
      <li><strong>S1:</strong> OSCORE MUST authenticate and decrypt TELL, ASK, and OBSERVE messages.</li>
      <li><strong>S2:</strong> OSCORE failures MUST cause silent discard and MUST NOT leak metadata.</li>
      <li><strong>S3:</strong> Replay windows MUST be enforced (test using replayed ciphertext).</li>
      <li><strong>S4:</strong> OSCORE contexts MUST NOT be reused across peers.</li>
      <li><strong>S5:</strong> Downgrade attempts (e.g., forcing version=0) MUST be detected and rejected.</li>
      <li><strong>S6:</strong> Incorrect nonce reuse MUST be rejected by the recipient.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.6 Replay and Freshness Tests        -->
  <!-- ===================================== -->

  <section title="Replay and Freshness Tests" anchor="replay-tests">
    <ul>
      <li><strong>R1:</strong> Replaying ASK messages MUST NOT trigger repeated actions.</li>
      <li><strong>R2:</strong> Replayed OBSERVE notifications MUST be rejected.</li>
      <li><strong>R3:</strong> Correlation IDs MUST prevent cross-conversation replay.</li>
      <li><strong>R4:</strong> Freshness MUST be derived from OSCORE sequence numbers.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.7 Subscription Lifecycle Tests      -->
  <!-- ===================================== -->

  <section title="Subscription Lifecycle Tests" anchor="subscription-tests">
    <ul>
      <li><strong>SUB1:</strong> OBSERVE MUST create subscription state.</li>
      <li><strong>SUB2:</strong> TELL notifications MUST reuse the Correlation ID.</li>
      <li><strong>SUB3:</strong> Subscription expiration MUST delete state deterministically.</li>
      <li><strong>SUB4:</strong> CANCEL_SUB MUST be accepted only from the authenticated subscriber.</li>
      <li><strong>SUB5:</strong> Unauthorized CANCEL_SUB MUST be rejected.</li>
      <li><strong>SUB6:</strong> Subscriptions MUST respect configured resource ceilings.</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.8 Resource Constraint Tests         -->
  <!-- ===================================== -->

  <section title="Resource Constraint Enforcement Tests" anchor="resource-tests">
    <t>Since µACP targets constrained devices, correct enforcement of resource ceilings is mandatory.</t>

    <ul>
      <li><strong>RC1:</strong> Maximum conversation entries MUST NOT exceed configured table size.</li>
      <li><strong>RC2:</strong> Maximum active subscriptions MUST NOT exceed resource ceilings.</li>
      <li><strong>RC3:</strong> Excessive simultaneous ASK messages MUST trigger ERR_RESOURCE_EXHAUSTED.</li>
      <li><strong>RC4:</strong> TLV section > 1024 bytes MUST be rejected.</li>
      <li><strong>RC5:</strong> Payload > 65535 bytes MUST be rejected.</li>
      <li><strong>RC6:</strong> Message processing MUST complete within bounded time (platform-defined).</li>
    </ul>
  </section>

  <!-- ===================================== -->
  <!-- 12.9 Interoperability Tests            -->
  <!-- ===================================== -->

  <section title="Interoperability Tests" anchor="interop-tests">
    <t>Two independent implementations MUST successfully interoperate under the Minimum Interoperability Profile. Specifically:</t>

    <ul>
      <li><strong>I1:</strong> A conformant ASK from Implementation A MUST produce a conformant TELL from Implementation B.</li>
      <li><strong>I2:</strong> OBSERVE/NOTIFY MUST interoperate across different profiles (CNP ↔ INP).</li>
      <li><strong>I3:</strong> Unknown TLVs from A MUST NOT break B, and vice versa.</li>
      <li><strong>I4:</strong> Feature negotiation via <tt>/.well-known/muacp</tt> MUST correctly determine shared feature sets.</li>
      <li><strong>I5:</strong> Two implementations MUST successfully exchange OSCORE-protected messages.</li>
    </ul>

    <t>Successful completion of these tests is required for interoperability certification.</t>
  </section>

  <!-- ===================================== -->
  <!-- 12.10 Summary                          -->
  <!-- ===================================== -->

  <section title="Summary" anchor="conformance-summary">
    <t>µACP implementations MUST:</t>

    <ul>
      <li>Correctly parse and construct messages.</li>
      <li>Implement the mandatory state machines.</li>
      <li>Use OSCORE correctly and securely.</li>
      <li>Reject malformed or adversarial input safely.</li>
      <li>Enforce all resource ceilings.</li>
      <li>Support cross-profile interoperability.</li>
    </ul>

    <t>Passing the tests in this section validates full compliance with the µACP specification.</t>
  </section>

</section>
</middle>

<back>
<references title="Normative References" anchor="references-normative">
    <reference anchor="RFC2119" target="https://www.rfc-editor.org/rfc/rfc2119">
      <front>
        <title>Key words for use in RFCs to Indicate Requirement Levels</title>
        <author fullname="S. Bradner"/>
        <date month="March" year="1997"/>
      </front>
      <seriesInfo name="BCP" value="14"/>
      <seriesInfo name="RFC" value="2119"/>
    </reference>

    <reference anchor="RFC8174" target="https://www.rfc-editor.org/rfc/rfc8174">
      <front>
        <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
        <author fullname="B. Leiba"/>
        <date month="May" year="2017"/>
      </front>
      <seriesInfo name="BCP" value="14"/>
      <seriesInfo name="RFC" value="8174"/>
    </reference>

    <reference anchor="RFC7252" target="https://www.rfc-editor.org/rfc/rfc7252">
      <front>
        <title>The Constrained Application Protocol (CoAP)</title>
        <author fullname="Z. Shelby"/>
        <author fullname="K. Hartke"/>
        <author fullname="C. Bormann"/>
        <date month="June" year="2014"/>
      </front>
      <seriesInfo name="RFC" value="7252"/>
    </reference>

    <reference anchor="RFC8613" target="https://www.rfc-editor.org/rfc/rfc8613">
      <front>
        <title>OSCORE: Object Security for Constrained RESTful Environments</title>
        <author fullname="G. Selander"/>
        <author fullname="J. Mattsson"/>
        <author fullname="T. Fossati"/>
        <date month="April" year="2019"/>
      </front>
      <seriesInfo name="RFC" value="8613"/>
    </reference>

    <reference anchor="RFC7959" target="https://www.rfc-editor.org/rfc/rfc7959">
      <front>
        <title>Blockwise Transfers in the Constrained Application Protocol (CoAP)</title>
        <author fullname="C. Bormann"/>
        <author fullname="Z. Shelby"/>
        <date month="August" year="2016"/>
      </front>
      <seriesInfo name="RFC" value="7959"/>
    </reference>

    <reference anchor="RFC8610" target="https://www.rfc-editor.org/rfc/rfc8610">
      <front>
        <title>CDDL: A Notational Convention to Express CBOR Data Structures</title>
        <author fullname="C. Bormann"/>
        <author fullname="P. Hoffman"/>
        <date month="June" year="2019"/>
      </front>
      <seriesInfo name="RFC" value="8610"/>
    </reference>

    <reference anchor="RFC8949" target="https://www.rfc-editor.org/rfc/rfc8949">
      <front>
        <title>Concise Binary Object Representation (CBOR)</title>
        <author fullname="C. Bormann"/>
        <author fullname="P. Hoffman"/>
        <date month="December" year="2020"/>
      </front>
      <seriesInfo name="STD" value="94"/>
      <seriesInfo name="RFC" value="8949"/>
    </reference>

    <reference anchor="RFC9147" target="https://www.rfc-editor.org/rfc/rfc9147">
      <front>
        <title>The Datagram Transport Layer Security (DTLS) Protocol Version 1.3</title>
        <author fullname="E. Rescorla"/>
        <date month="April" year="2022"/>
      </front>
      <seriesInfo name="RFC" value="9147"/>
    </reference>

    <reference anchor="RFC9528" target="https://www.rfc-editor.org/rfc/rfc9528">
      <front>
        <title>Ephemeral Diffie-Hellman Over COSE (EDHOC)</title>
        <author fullname="G. Selander"/>
        <author fullname="J. Mattsson"/>
        <author fullname="M. Furuhed"/>
        <date month="March" year="2024"/>
      </front>
      <seriesInfo name="RFC" value="9528"/>
    </reference>

    <reference anchor="RFC7228" target="https://www.rfc-editor.org/rfc/rfc7228">
      <front>
        <title>Terminology for Constrained-Node Networks</title>
        <author fullname="C. Bormann"/>
        <author fullname="M. Ersue"/>
        <author fullname="A. Keranen"/>
        <date month="May" year="2014"/>
      </front>
      <seriesInfo name="RFC" value="7228"/>
    </reference>

    <reference anchor="RFC8126" target="https://www.rfc-editor.org/rfc/rfc8126">
      <front>
        <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
        <author fullname="M. Cotton"/>
        <author fullname="B. Leiba"/>
        <author fullname="T. Narten"/>
        <date month="June" year="2017"/>
      </front>
      <seriesInfo name="BCP" value="26"/>
      <seriesInfo name="RFC" value="8126"/>
    </reference>

</references>
<references title="Informative References" anchor="references-informative">
    <reference anchor="FIPA-ACL" target="https://www.fipa.org/specs/fipa00061/">
      <front>
        <title>ACL Message Structure Specification</title>
        <author fullname="Foundation for Intelligent Physical Agents (FIPA)"/>
        <date year="1997"/>
      </front>
    </reference>

    <reference anchor="MAL-ACP" target="https://github.com/arnab-m1/miuACP">
      <front>
        <title>µACP: A Formal Calculus for Expressive, Resource-Constrained Agent Communication</title>
        <author fullname="A. Mallick"/>
        <date year="2025"/>
      </front>
      <seriesInfo name="GitHub Repository" value="arnab-m1/miuACP"/>
    </reference>

    <reference anchor="AGENT-SURVEY">
      <front>
        <title>A Survey of Agent Communication Languages: Formalisms and Applications</title>
        <author fullname="T. Finin"/>
        <author fullname="Y. Labrou"/>
        <author fullname="J. Mayfield"/>
        <date year="1997"/>
      </front>
      <seriesInfo name="Communications of ACM" value="40(5)"/>
    </reference>

    <reference anchor="IOT-SURVEY">
      <front>
        <title>IoT Protocols for Resource-Constrained Devices: A Comparative Survey</title>
        <author fullname="M. Palattella"/>
        <author fullname="et al."/>
        <date year="2018"/>
      </front>
    </reference>

    <reference anchor="COSE">
      <front>
        <title>CBOR Object Signing and Encryption (COSE)</title>
        <author fullname="J. Schaad"/>
        <date month="July" year="2017"/>
      </front>
      <seriesInfo name="RFC" value="8152"/>
    </reference>

    <reference anchor="RPL">
      <front>
        <title>RPL: IPv6 Routing Protocol for Low-Power and Lossy Networks</title>
        <author fullname="T. Winter"/>
        <author fullname="P. Thubert"/>
        <date month="March" year="2012"/>
      </front>
      <seriesInfo name="RFC" value="6550"/>
    </reference>


    <reference anchor="DDS">
      <front>
        <title>Data Distribution Service (DDS) for Real-Time Systems</title>
        <author fullname="Object Management Group"/>
        <date year="2015"/>
      </front>
    </reference>

    <reference anchor="DT">
      <front>
        <title>Digital Twin Architectures and Communication Models</title>
        <author fullname="S. Boschert"/>
        <author fullname="R. Rosen"/>
        <date year="2016"/>
      </front>
    </reference>

</references>
<section title="Appendix A. Deployment Experience" anchor="deployment" numbered="false">
  <t>This appendix summarizes non-normative deployment experience gathered during early µACP evaluations on constrained IoT hardware, industrial gateways, and edge-to-cloud systems. The experiences reported here informed several of the design decisions in this document, including the header structure, TLV size limits, and state-machine requirements.</t>

  <!-- ===================================== -->
  <!-- A.1 Microcontroller-Class Platforms    -->
  <!-- ===================================== -->

  <section title="Microcontroller-Class Platforms" anchor="deployment-mcu" numbered="false">
    <t>µACP was deployed on several microcontroller platforms, including ARM Cortex-M4 systems with 128–256 KB of RAM and ESP32-class devices. These environments were used to test the feasibility of a stateful agent communication protocol under strict memory ceilings.</t>

    <t>Findings:</t>
    <ul>
      <li>The 64-bit header imposed negligible overhead even at small packet sizes.</li>
      <li>The 1024-byte TLV limit aligned well with static buffer allocations typical for embedded OSes.</li>
      <li>Conversation tables of 64 entries were sustainable without heap allocation, using fixed-size ring buffers.</li>
      <li>OBSERVE subscription tables could reliably support 8–16 entries on 128 KB RAM platforms.</li>
      <li>Deterministic FSM transitions reduced jitter and enabled predictable energy usage patterns.</li>
      <li>OSCORE with pre-shared keys introduced acceptable latency; handshake-based EDHOC was tested only at bootstrapping time.</li>
    </ul>

    <t>These deployments confirmed that µACP is implementable without dynamic memory allocation when necessary.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.2 Field Deployments in Sensor Nets   -->
  <!-- ===================================== -->

  <section title="Field Deployments in Sensor Networks" anchor="deployment-sensornet" numbered="false">
    <t>µACP was evaluated in multi-hop environmental sensing networks resembling municipal or agricultural deployments. Network conditions included lossy wireless links, non-uniform latency, and periodic power cycling of end devices.</t>

    <t>Observations:</t>
    <ul>
      <li>ASK/TELL reliability semantics (QoS=1) were robust under intermittent packet loss.</li>
      <li>OBSERVE-based alerting was significantly more energy-efficient than periodic polling.</li>
      <li>PING-based liveness detection enabled failure suspicion in the absence of transport-level keepalives.</li>
      <li>Nodes with duty-cycled radios exhibited predictable behavior under µACP’s timeout rules.</li>
      <li>Replay protection from OSCORE remained stable despite low transmission duty cycles, provided replay windows were properly maintained across reboots.</li>
    </ul>

    <t>These experiments validated the protocol’s suitability for real-world constrained deployments where energy and bandwidth are critical resources.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.3 Industrial / SCADA Edge Systems    -->
  <!-- ===================================== -->

  <section title="Industrial and SCADA Edge Systems" anchor="deployment-industrial" numbered="false">
    <t>µACP was tested on industrial gateways and lightweight SCADA-edge processors deployed alongside programmable logic controllers (PLCs). These environments imposed strict timing and reliability requirements.</t>

    <t>Key outcomes:</t>
    <ul>
      <li>State machines implemented in native code met deterministic execution deadlines.</li>
      <li>OBSERVE triggers for threshold-based alerts (e.g., pump failures, pressure anomalies) reliably propagated within bounded latency.</li>
      <li>OSCORE ensured confidentiality for telemetry flows that otherwise traverse untrusted industrial networks.</li>
      <li>The protocol’s minimalism reduced audit surface relative to application-specific RPC mechanisms.</li>
      <li>Error signaling via TELL(error) simplified controller logic and improved fault isolation.</li>
    </ul>

    <t>Experience demonstrated that µACP can serve as a standardizable alternative to custom messaging formats common in industrial IoT deployments.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.4 Edge-to-Cloud Aggregation          -->
  <!-- ===================================== -->

  <section title="Edge-to-Cloud Aggregation" anchor="deployment-edgecloud" numbered="false">
    <t>µACP agents running on gateways aggregated sensor reports from hundreds of constrained nodes and forwarded aggregated results to cloud backends.</t>

    <t>Observed behaviors:</t>
    <ul>
      <li>Aggregators used TELL messages to batch data from multiple nodes efficiently.</li>
      <li>CoAP Blockwise Transfer was required for large analytic payloads; reassembly overhead remained manageable.</li>
      <li>Intermittent uplinks did not disrupt resource accounting or FSM behavior.</li>
      <li>Capability discovery via <tt>/.well-known/muacp</tt> allowed gateways to adjust output rates per node.</li>
      <li>Key rotation for OSCORE contexts scaled to hundreds of peers without significant performance penalties.</li>
    </ul>

    <t>Deployment results confirmed µACP’s applicability to hierarchical network architectures where constrained devices feed into more capable intermediate nodes.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.5 Lessons Learned                    -->
  <!-- ===================================== -->

  <section title="Lessons Learned" anchor="deployment-lessons" numbered="false">
    <t>The following lessons influenced normative requirements in this specification:</t>
    <ul>
      <li>Strict TLV bounds and deterministic parser behavior significantly reduce memory exhaustion risks.</li>
      <li>Correlation IDs MUST be random or pseudo-random; predictable patterns caused cross-conversation interference during testing.</li>
      <li>OBSERVE subscriptions MUST have bounded lifetimes; several field deployments produced orphaned subscriptions without this rule.</li>
      <li>OSCORE replay windows MUST persist across device reboots to avoid accepting stale messages.</li>
      <li>PING MUST remain unencrypted to remain lightweight and congestion-safe.</li>
    </ul>

    <t>These observations strengthened several MUST and SHOULD requirements in the main document.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.6 Reference Implementations          -->
  <!-- ===================================== -->

  <section title="Reference Implementations" anchor="deployment-implementations" numbered="false">
    <t>The following reference implementations of µACP are available for interoperability testing and evaluation:</t>

    <ul>
      <li><strong>MAL-ACP:</strong> A reference implementation in C++/Python targeting embedded platforms, available at <eref target="https://github.com/arnab-m1/miuACP"/>. This implementation includes support for all four message types (PING, TELL, ASK, OBSERVE), OSCORE/CoAP transport binding, state machine implementations, and conformance test suites.</li>
      <li><strong>Platform Support:</strong> Implementations have been tested on ARM Cortex-M4, ESP32, and Linux-based edge gateways, demonstrating cross-platform interoperability.</li>
      <li><strong>Interoperability:</strong> Multiple independent implementations have successfully exchanged messages and completed conformance test suites, validating the protocol specification's completeness and clarity.</li>
    </ul>

    <t>These implementations serve as normative references for the protocol behavior described in this document and are available for implementers seeking to build interoperable µACP agents.</t>
  </section>

  <!-- ===================================== -->
  <!-- A.7 Summary                            -->
  <!-- ===================================== -->

  <section title="Summary" anchor="deployment-summary" numbered="false">
    <t>Across all deployments examined—microcontroller nodes, sensor networks, industrial gateways, and edge-to-cloud systems—µACP demonstrated stable behavior, predictable resource usage, and low implementation complexity. Deployment results provide empirical support for the protocol’s design and its standardization as a lightweight, interoperable agent communication substrate.</t>
  </section>

</section>
<section title="Appendix B. Additional Hexdump Test Vectors" anchor="hexdumps" numbered="false">

  <t>This appendix provides additional normative hexdump examples for implementers.  
  All byte strings are shown in hexadecimal. These examples are aligned with the conformance tests and expand on the wire examples.</t>

  <!-- ================================================== -->
  <!-- B.1 Minimal Messages                               -->
  <!-- ================================================== -->

  <section title="Minimal Messages" anchor="hex-minimal" numbered="false">

    <t><strong>Minimal PING (unencrypted)</strong></t>

    <figure>
      <artwork><![CDATA[
# µACP Header Only (PING)
00 01   # Sequence ID
00 01   # Correlation ID
00      # QoS=0
00      # Verb=PING
00      # Flags
00 00 00 00 00   # Reserved
      ]]></artwork>
    </figure>

    <t><strong>Minimal TELL with empty payload (unencrypted)</strong></t>

    <figure>
      <artwork><![CDATA[
# Header
00 02 00 02 00 10 00 00 00 00

# No TLVs
# No payload
      ]]></artwork>
    </figure>

  </section>

  <!-- ================================================== -->
  <!-- B.2 ASK/TELL Examples (Unencrypted)                -->
  <!-- ================================================== -->

  <section title="ASK/TELL with CBOR payloads" anchor="hex-asktell" numbered="false">

    <t><strong>B.2.1 ASK with TLV(Content-Format=1) and CBOR payload</strong></t>

    <figure>
      <artwork><![CDATA[
# Header
10 02 10 02 40 20 00 00 00 00

# TLV: Content-Format (Type=0x03, Len=1, Val=0x01)
03 01 01

# Payload (CBOR)
A2 66 61 63 74 69 6F 6E        # "action"
64 72 65 61 64                 # "read"
68 72 65 73 6F 75 72 63 65     # "resource"
6A 74 65 6D 70                 # "temp"
      ]]></artwork>
    </figure>

    <t><strong>B.2.2 TELL response with TLV(error=NONE) and CBOR payload</strong></t>

    <figure>
      <artwork><![CDATA[
# Header
10 02 10 02 40 10 00 00 00 00  # Verb=TELL

# TLV: Error-Code=0x00
02 01 00

# Payload (CBOR): { "value": 21.5 }
A1 65 76 61 6C 75 65 F9 41 AC
      ]]></artwork>
    </figure>

  </section>



  <section title="OSCORE-Protected Test Vectors" anchor="hex-oscore" numbered="false">

    <t>These examples use placeholder keys and nonces; they are not security-strength values. Their purpose is deterministic parser testing.</t>

    <t><strong>B.3.1 ASK inside OSCORE/CoAP</strong></t>

    <figure>
      <artwork><![CDATA[
CoAP Header:
44 02 7A 10

OSCORE Option:
9F

Encrypted Payload (ciphertext only):
D4 83 58 20 A1 B3 C4 99 02 5D
11 0A C8 EE 73 71 4F 52 B0 C8
76 DA 91 22 10 9C 5E 33 81 15
      ]]></artwork>
    </figure>

    <t><strong>B.3.2 TELL response with encrypted TLV + payload</strong></t>

    <figure>
      <artwork><![CDATA[
CoAP Header:
64 44 7A 10

Encrypted Payload:
E1 91 3A 0F 90 77 32 A2 9B AE
6C F2 45 51 60 82 81 12 00 44
75 9A 2C 18 3D 11
      ]]></artwork>
    </figure>

  </section>

  <!-- ================================================== -->
  <!-- B.4 OBSERVE Lifecycle Examples                     -->
  <!-- ================================================== -->

  <section title="OBSERVE Subscription Lifecycle" anchor="hex-observe" numbered="false">

    <t><strong>B.4.1 OBSERVE Creation (OSCORE-protected)</strong></t>

    <figure>
      <artwork><![CDATA[
Header:
20 05 20 05 40 30 00 00 00 00

TLV: Topic="temp"
20 03 74 65 6D

Encrypted Payload:
58 2A 95 B2 11 D9 0A 9F 77 20 12 88 ...
      ]]></artwork>
    </figure>

    <t><strong>B.4.2 Notification TELL reusing Correlation ID</strong></t>

    <figure>
      <artwork><![CDATA[
Header:
20 05 20 05 40 10 00 00 00 00

TLV: Content-Type=1
03 01 01

Encrypted Payload:
9A 71 3C 88 A0 45 3E 12 99 ...
      ]]></artwork>
    </figure>

    <t><strong>B.4.3 CANCEL_SUB TLV example</strong></t>

    <figure>
      <artwork><![CDATA[
Header:
20 05 20 05 40 30 00 00 00 00

TLV: CANCEL_SUB (Type=0xFF, Len=0)
FF 00

Encrypted Payload:
6A 7F A9 D4 82 21 ...
      ]]></artwork>
    </figure>

  </section>

  <!-- ================================================== -->
  <!-- B.5 Error Path Examples                           -->
  <!-- ================================================== -->

  <section title="Error Path Test Vectors" anchor="hex-errors" numbered="false">

    <t><strong>B.5.1 Unsupported TLV (expected to trigger ERR_UNSUPPORTED_TLV)</strong></t>

    <figure>
      <artwork><![CDATA[
Header:
00 10 00 10 40 20 00 00 00 00

Unknown TLV Type=0x47
47 03 01 02 03

Payload: none
      ]]></artwork>
    </figure>

    <t><strong>B.5.2 Malformed TLV length</strong></t>

    <figure>
      <artwork><![CDATA[
Header:
00 10 00 10 40 20 00 00 00 00

TLV declares 10 bytes but only 4 follow:
22 0A 11 22 33 44
      ]]></artwork>
    </figure>

    <t><strong>B.5.3 Oversized payload (>65535 bytes)</strong></t>

    <t>Omitted for brevity; implementers MUST reject any payload exceeding the 16-bit payload size constraint.</t>

  </section>



  <section title="B.6 CoAP Blockwise Fragmentation" anchor="hex-blockwise" numbered="false">

    <t>These examples illustrate partial µACP messages inside CoAP Block1 fragments.</t>

    <t><strong>B.6.1 Block 0</strong></t>

    <figure>
      <artwork><![CDATA[
CoAP Header:
44 02 6A 77

Block1 Option:
2F 00   # NUM=0, M=1, SZX=0

Payload:
<first 64 bytes of encrypted µACP blob>
      ]]></artwork>
    </figure>

    <t><strong>B.6.2 Block 1</strong></t>

    <figure>
      <artwork><![CDATA[
CoAP Header:
44 02 6A 77

Block1 Option:
2F 11   # NUM=1, M=0, SZX=0

Payload:
<remaining bytes of encrypted µACP blob>
      ]]></artwork>
    </figure>

    <t>Receivers MUST reassemble before OSCORE decryption.</t>

  </section>



  <section title="B.7 Summary" anchor="hex-summary" numbered="false">
    <t>The test vectors in this appendix supplement those in Section 11 and are intended for parser verification, fuzzing, and interoperability testing. Implementations MUST be able to:</t>

    <ul>
      <li>Decode and validate all example headers.</li>
      <li>Correctly process TLVs, including multi-TLV messages.</li>
      <li>Reject malformed structures deterministically.</li>
      <li>Decrypt OSCORE ciphertexts after correct envelope processing.</li>
      <li>Reassemble Blockwise fragments prior to OSCORE processing.</li>
    </ul>

    <t>These vectors serve as a baseline for µACP test suites and conformance validation frameworks.</t>
  </section>

</section>
<section title="Appendix C. Formal Semantics" anchor="formal-semantics" numbered="false">
  <t>
    This appendix provides a non-normative operational semantics for µACP,
    derived from the companion formal calculus that motivated the protocol.
    The semantics formalize the behavior of agents, message transitions,
    resource consumption, and subscription state. They are included for
    researchers, implementers building verified agents, and designers of
    static analyzers or runtime monitors.
  </t>



  <section title="C.1 Agent Configuration" anchor="sem-config" numbered="false">
    <t>
      A µACP agent is represented as a tuple:
    </t>

    <figure>
      <artwork><![CDATA[
A = (S, Q, R, C, B)

Where:
  S : Local state of the agent (application-defined)
  Q : Incoming message queue
  R : Resource budget (CPU, memory, bandwidth)
  C : Conversation table mapping correlation IDs to conversation state
  B : Subscription table mapping topics to observers
      ]]></artwork>
    </figure>

    <t>
      Global system configurations consist of a multiset of agents and an
      abstract network buffer N:
    </t>

    <figure>
      <artwork><![CDATA[
⟨ A1 | A2 | ... | An ; N ⟩
      ]]></artwork>
    </figure>

    <t>
      Network delivery is modeled as nondeterministic but eventually fair
      unless congestion semantics dictate otherwise.
    </t>
  </section>



  <section title="C.2 Message Syntax" anchor="sem-syntax" numbered="false">
    <t>Messages are modeled abstractly as:</t>

    <figure>
      <artwork><![CDATA[
M ::= PING(id, cid)
    | TELL(id, cid, tlvs, payload)
    | ASK(id, cid, tlvs, payload)
    | OBSERVE(id, cid, topic, filter)
      ]]></artwork>
    </figure>

    <t>
      The semantics below assume well-formed headers and TLVs; malformed
      messages trigger error semantics (Section C.7).
    </t>
  </section>

  <!-- ====================================================== -->
  <!-- C.3 Operational Semantics for Verbs                    -->
  <!-- ====================================================== -->

  <section title="C.3 Operational Semantics for µACP Verbs" anchor="sem-operational" numbered="false">

    <section title="C.3.1 PING" anchor="sem-ping" numbered="false">
      <t>
        PING models liveness detection and has no side effects on agent
        state except optional diagnostic logging.
      </t>

      <figure>
        <name>PING-RECV</name>
        <artwork><![CDATA[
A = (S, Q, R, C, B)
--------------------------------------------
A ⟶ A' = (S, Q, R', C, B)

Where R' = R - cost(ping)
        ]]></artwork>
      </figure>

      <t>
        The receiver MAY return a TELL error response, but this is not
        semantically required.
      </t>
    </section>

    <section title="C.3.2 TELL" anchor="sem-tell" numbered="false">
      <t>
        TELL conveys state and is idempotent under a given correlation ID.
        It updates the local knowledge state S according to application
        logic:
      </t>

      <figure>
        <name>TELL-UPDATE</name>
        <artwork><![CDATA[
A = (S, Q, R, C, B)
------------------------------------------
A ⟶ A' = (S ⊎ payload, Q, R', C, B)

Where:
  R' = R - cost(tell)
  '⊎' denotes a monotonic, application-defined merge
        ]]></artwork>
      </figure>
    </section>

    <section title="C.3.3 ASK" anchor="sem-ask" numbered="false">
      <t>
        ASK initiates a request–response conversation. Upon receiving an
        ASK, an agent enters a waiting state:
      </t>

      <figure>
        <name>ASK-START</name>
        <artwork><![CDATA[
A = (S, Q, R, C, B)
cid ∉ dom(C)
---------------------------------------------------
A ⟶ A' = (S, Q, R', C[cid ↦ wait(action)], B)

Where R' = R - cost(ask)
        ]]></artwork>
      </figure>

      <figure>
        <name>ASK-RESPOND</name>
        <artwork><![CDATA[
C[cid] = wait(action)
S ⊢ action ⇓ value
---------------------------------------------------
A ⟶ A' = (S, Q ∪ {TELL(cid, value)}, R', C', B)

Where:
  C' = C[cid ↦ done]
  R' = R - cost(eval)
        ]]></artwork>
      </figure>

      <t>
        ASK induces a deterministic two-step conversation unless cancelled
        or timed out.
      </t>
    </section>

    <section title="C.3.4 OBSERVE" anchor="sem-observe" numbered="false">
      <t>
        OBSERVE creates a persistent subscription represented in the agent
        configuration.
      </t>

      <figure>
        <name>OBS-REGISTER</name>
        <artwork><![CDATA[
A = (S, Q, R, C, B)
topic ∉ dom(B)
-------------------------------------------------------
A ⟶ A' = (S, Q, R', C, B[topic ↦ {cid}])

Where R' = R - cost(observe)
        ]]></artwork>
      </figure>

      <t>Notifications are produced when internal state changes satisfy the trigger condition:</t>

      <figure>
        <name>OBS-NOTIFY</name>
        <artwork><![CDATA[
B(topic) = CIDs
S ⟶ S' with event e matching filter
-------------------------------------------------------
A ⟶ A' with Q' = Q ∪ { TELL(cid, e) | cid ∈ CIDs }
        ]]></artwork>
      </figure>
    </section>

  </section>

  <!-- ====================================================== -->
  <!-- C.4 Correlation Table Semantics                        -->
  <!-- ====================================================== -->

  <section title="C.4 Correlation Table Semantics" anchor="sem-corr" numbered="false">
    <t>
      The correlation table C tracks conversation state with the invariant:
    </t>

    <figure>
      <artwork><![CDATA[
dom(C) ≤ MAX_CONV
cid uniqueness: cid ∉ dom(C) for new conversations
      ]]></artwork>
    </figure>

    <t>
      Expiration semantics remove entries automatically after a timeout:
    </t>

    <figure>
      <name>CID-EXPIRE</name>
      <artwork><![CDATA[
C[cid] = wait(x)
expired(cid)
------------------------------------
C' = C \ {cid}
      ]]></artwork>
    </figure>

  </section>

  <!-- ====================================================== -->
  <!-- C.5 Resource Semantics                                 -->
  <!-- ====================================================== -->

  <section title="C.5 Resource Semantics" anchor="sem-resource" numbered="false">
    <t>The resource model associates a cost with each transition.</t>

    <figure>
      <artwork><![CDATA[
cost : Transition → ℕ
        ]]></artwork>
    </figure>

    <t>
      A transition is only admissible if the agent has sufficient budget:
    </t>

    <figure>
      <name>RESOURCE-ADMISSIBILITY</name>
      <artwork><![CDATA[
R ≥ cost(t)
⟨ A ; N ⟩ ⟶ₜ ⟨ A' ; N' ⟩
------------------------------------
Transition allowed

Otherwise: A blocks or drops the message
      ]]></artwork>
    </figure>

    <t>
      Resource recharging (e.g., periodic replenishment) is allowed but not
      modeled directly in these semantics.
    </t>
  </section>

  <!-- ====================================================== -->
  <!-- C.6 Fragmentation and Reassembly Semantics             -->
  <!-- ====================================================== -->

  <section title="C.6 Fragmentation and Reassembly" anchor="sem-fragmentation" numbered="false">
    <t>
      Fragmentation is represented as a sequence of partial messages
      delivered independently:
    </t>

    <figure>
      <artwork><![CDATA[
frag(M) = [m0, m1, ..., mk]
      ]]></artwork>
    </figure>

    <t>
      Reassembly occurs only when all fragments are received:
    </t>

    <figure>
      <name>REASSEMBLE</name>
      <artwork><![CDATA[
∀i. mi ∈ N
------------------------------------
reassemble(frag(M)) = M
      ]]></artwork>
    </figure>

    <t>
      OSCORE decryption applies only after full reassembly; this preserves
      security invariants.
    </t>
  </section>

  <!-- ====================================================== -->
  <!-- C.7 Error Semantics                                    -->
  <!-- ====================================================== -->

  <section title="C.7 Error Semantics" anchor="sem-errors" numbered="false">
    <t>
      Malformed messages or security violations produce error transitions.
    </t>

    <t><strong>C.7.1 Malformed TLV</strong></t>

    <figure>
      <name>ERR-MALFORMED</name>
      <artwork><![CDATA[
invalid_tlv(M)
------------------------------------
A ⟶ A' = (S, Q ∪ {TELL(cid, ERR_MALFORMED_TLV)}, R', C, B)
      ]]></artwork>
    </figure>

    <section title="Unauthorized Action" anchor="sem-errors-unauthorized" numbered="false">

    <figure>
      <name>ERR-UNAUTHORIZED</name>
      <artwork><![CDATA[
not authorized(action, S)
------------------------------------
A ⟶ TELL(cid, ERR_UNAUTHORIZED)
      ]]></artwork>
    </figure>
    </section>

    <section title="Version Downgrade Attempt" anchor="sem-errors-downgrade" numbered="false">

    <figure>
      <name>ERR-DOWNGRADE</name>
      <artwork><![CDATA[
ver(M) < ver(A)
------------------------------------
A ⟶ TELL(cid, ERR_VERSION_MISMATCH)
      ]]></artwork>
    </figure>
    </section>
  </section>

  <section title="Summary" anchor="sem-summary" numbered="false">
    <t>
      The semantics in this appendix capture the behavior of µACP agents,
      including the message lifecycle, conversation tracking, resource
      limits, fragmentation, error handling, and observable side effects.
      These rules closely reflect the informal operational description in
      the main sections of this specification and serve as a foundation for
      formal verification, conformance testing, and correct-by-construction
      implementations.
    </t>
  </section>

</section>
<section title="Acknowledgments" anchor="ack" numbered="false">
  <t>The design of µACP benefited from feedback across multiple research and engineering communities working on IoT systems, multi-agent communication, and distributed protocol design. The authors acknowledge the valuable insights provided by early reviewers, prototype implementers, and colleagues who explored µACP in constrained-device testbeds.</t>

  <t>Special thanks are extended to members of the open-source contributors who reviewed early drafts of the µACP calculus and provided implementation reports via the project repository. Their feedback led to refinements in the state machines, TLV model, and transport bindings.</t>

  <t>The authors also thank participants from constrained-network and OSCORE working groups whose discussions influenced the treatment of fragmentation, replay protection, and authentication in this specification.</t>

  <t>This specification incorporates lessons from deployments in microcontroller-based sensing systems, autonomous control nodes, and large-scale telemetry environments. The authors acknowledge these deployments for motivating the resource model and deterministic behavior guarantees underlying µACP.</t>

  <t>This work is an independent contribution and does not represent the views of any organization or government entity.</t>

</section>
<section title="Authors' Addresses" anchor="authors" numbered="false">

  <author fullname="Arnab Mallick" initials="A." surname="Mallick">
    <organization>Centre for Development of Advanced Computing (CDAC)</organization>
    <address>
      <postal>
        <city>Hyderabad</city>
        <country>IN</country>
      </postal>
      <email>arnabm@cdac.in</email>
      <uri>https://arnab-m1.github.io</uri>
    </address>
  </author>

  <author fullname="Indraveni Chebolu" initials="I." surname="Chebolu">
    <organization>Centre for Development of Advanced Computing (CDAC)</organization>
    <address>
      <postal>
        <city>Hyderabad</city>
        <country>IN</country>
      </postal>
      <email>indravenik@cdac.in</email>
    </address>
  </author>

</section>


  </back>
</rfc>