<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE rfc [
  <!ENTITY nbsp "&#160;">
  <!ENTITY zwsp "&#8203;">
  <!ENTITY nbhy "&#8209;">
  <!ENTITY wj   "&#8288;">
]>

<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     docName="draft-song-anp-aip-00"
     category="exp"
     ipr="trust200902"
     submissionType="independent"
     xml:lang="en"
     version="3">

  <front>
    <title abbrev="AIP">Agent Internet Protocol (AIP)</title>

    <seriesInfo name="Internet-Draft" value="draft-song-anp-aip-00"/>

    <author fullname="Jinke Song" initials="J." surname="Song">
      <organization abbrev="HKUST">Dept. of CSE, Hong Kong University of Science and Technology</organization>
      <address>
        <email>ink@chatchat.space</email>
      </address>
    </author>

    <author fullname="Mu Yuan" initials="M." surname="Yuan">
      <organization abbrev="CUHK">Dept. of IE, The Chinese University of Hong Kong</organization>
      <address>
        <email>muyuan@cuhk.edu.hk</email>
      </address>
    </author>

    <date year="2026" month="March" day="25"/>

    <area>art</area>
    <workgroup>Independent Submission</workgroup>

    <keyword>agent</keyword>
    <keyword>protocol</keyword>
    <keyword>datagram</keyword>

    <abstract>
      <t>
        The Internet Protocol (IP, RFC 791) provides best-effort datagram
        delivery between hosts identified by numeric addresses.  The Agent
        Internet Protocol (AIP) provides best-effort datagram delivery
        between autonomous AI agents identified by agent:// URIs --
        human-readable, capability-descriptive names.
      </t>
      <t>
        AIP is designed to serve as the narrow waist of the Agent Network
        Protocol (ANP) suite, occupying an architectural position
        analogous to IP in the TCP/IP suite: a minimal common substrate
        through which upper-layer protocols and link technologies
        interoperate without direct coupling.
      </t>
      <t>
        This document specifies the AIP message format, addressing model,
        upper-layer protocol demultiplexing, TLV options, message
        processing rules, error handling, and interfaces to adjacent
        protocol layers.  Name registration, distributed name resolution,
        and semantic discovery are provided by a companion resolver
        service and are outside the scope of this document.
      </t>
    </abstract>
  </front>

  <middle>

    <!-- ============================================================ -->
    <!--  SECTION 1 — INTRODUCTION                                     -->
    <!-- ============================================================ -->

    <section anchor="introduction">
      <name>Introduction</name>

      <section anchor="problem-statement">
        <name>Problem Statement</name>
        <t>
          The Internet Protocol <xref target="RFC0791"/> provides a
          universal mechanism for delivering datagrams between hosts
          identified by fixed-length numeric addresses.  IP was designed
          under the assumption that communication endpoints are hardware
          devices with stable locations on physical networks.
        </t>
        <t>
          In agent networking, the endpoints are not hardware devices but
          software agents: autonomous programs that can be created,
          destroyed, migrated, and replicated at will.  They do not have
          fixed locations.  They are identified not by physical attachment
          points but by their names and capabilities.
        </t>
        <t>
          An AI agent that needs a French-to-Japanese translator does not
          know -- and should not need to know -- any IP address.  It needs
          to reach "agent://translation/fr-ja".  In AIP, names serve as
          addresses: rather than resolving a name to a numeric location
          before sending, the agent addresses messages directly to a
          human-readable URI and relies on a local resolver to map that
          name to a reachable peer.
        </t>
        <t>
          Current naming systems such as the Domain Name System
          <xref target="RFC1035"/> map human-readable names to network
          locations.  Agents need a naming system that maps intents to
          capabilities.  AIP provides the datagram substrate:
          name-based addressing with the agent:// URI scheme and
          best-effort message delivery.  The name resolution service
          itself -- including registration, distributed lookup, and
          semantic search -- is provided by a companion resolver that
          runs above AIP as an upper-layer protocol (one such resolver
          is ANS <xref target="I-D.song-anp-ans"/>).
        </t>
      </section>

      <section anchor="scope">
        <name>Scope</name>
        <t>
          This document is one of four core Internet-Drafts in
          the Agent Network Protocol (ANP) suite: AIP (this
          document, datagram delivery), AITP
          <xref target="I-D.song-anp-aitp"/> (invocation
          transport), ANS <xref target="I-D.song-anp-ans"/>
          (name system), and ADP
          <xref target="I-D.song-anp-adp"/> (description and
          discovery).  The four drafts are designed to co-evolve
          as a self-contained protocol suite; no additional
          specification is required for baseline
          interoperability.  AIP's local-resolver semantic
          extension
          (<xref target="semantic-resolution"/>)
          <bcp14>MAY</bcp14> be backed by an implementation
          that consults ADP discovery services for ranked
          capability matching; ANS core provides name-to-peer
          binding but does not itself perform ranked semantic
          discovery.
        </t>
        <t>
          AIP defines an experimental datagram protocol serving
          as the narrow waist of the ANP suite, analogous to IP
          in TCP/IP.  It provides a best-effort datagram service
          between named agents.
        </t>
        <t>AIP provides:</t>
        <ol>
          <li>Name-based addressing using agent:// URIs.</li>
          <li>Best-effort datagram delivery.</li>
          <li>Upper-layer protocol demultiplexing via the Protocol field.</li>
          <li>TTL-bounded relay with deduplication.</li>
          <li>Extensible TLV options for timestamps, tracing, and priority.</li>
          <li>Error reporting for undeliverable messages.</li>
        </ol>
        <t>AIP does NOT provide:</t>
        <ol>
          <li>Reliable delivery -- datagrams may be lost, duplicated, or
              reordered.  Reliability is the responsibility of a
              higher-layer protocol such as AITP
              <xref target="I-D.song-anp-aitp"/>.</li>
          <li>Ordering or flow control -- these are higher-layer
              functions.</li>
          <li>Name registration, distributed lookup, or semantic
              discovery -- AIP does not define these functions.
              They are expected to be provided by a companion naming
              service; ANS <xref target="I-D.song-anp-ans"/> is one
              such architecture.</li>
          <li>Fragmentation -- messages exceeding the link MTU are
              rejected, not fragmented.</li>
          <li>Payload confidentiality -- encryption is the responsibility
              of a higher-layer protocol or the application.</li>
        </ol>
      </section>

      <section anchor="assumptions">
        <name>Assumptions</name>
        <t>
          AIP assumes:
        </t>
        <ol>
          <li>A local resolver service capable of mapping agent:// URI
              tokens to link-layer delivery targets.  AIP does not
              require any specific resolver architecture.</li>
          <li>A link layer that can deliver variable-length byte
              sequences between peers identified by peer ID.</li>
          <li>AIP <bcp14>MAY</bcp14> be used with higher-layer
              protocols that provide reliability, ordering, or
              application semantics, but does not depend on them for
              baseline datagram operation.</li>
        </ol>
      </section>

      <section anchor="requirements-language">
        <name>Requirements Language</name>
        <t>
          The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
          "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>",
          "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
          "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>",
          "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and
          "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted
          as described in BCP&nbsp;14 <xref target="RFC2119"/>
          <xref target="RFC8174"/> when, and only when, they appear in all
          capitals, as shown here.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 2 — TERMINOLOGY                                      -->
    <!-- ============================================================ -->

    <section anchor="terminology">
      <name>Terminology</name>

      <dl>
        <dt>Agent</dt>
        <dd>
          An autonomous software entity that participates in the ANP
          network.  An agent has a cryptographic identity (an Ed25519
          key pair) and registers one or more agent:// URIs.
        </dd>

        <dt>Name</dt>
        <dd>
          The identifier component of an agent:// URI that appears after
          the optional namespace and slash.  For example, in
          "agent://acme/code-reviewer", the name is "code-reviewer".
        </dd>

        <dt>Namespace</dt>
        <dd>
          An optional organizational prefix in an agent:// URI that groups
          related agents.  For example, in "agent://acme/code-reviewer",
          the namespace is "acme".  A URI without a namespace is in the
          global namespace.
        </dd>

        <dt>Resolution</dt>
        <dd>
          The process of mapping an agent:// URI to a peer ID so that AIP
          can transmit a message.  Resolution is performed by a local
          resolver.
        </dd>

        <dt>Resolver</dt>
        <dd>
          A local service that maps agent:// URIs to peer IDs.  AIP
          delegates all resolution to the resolver.  A resolver
          <bcp14>MAY</bcp14> additionally support semantic queries
          (see <xref target="semantic-resolution"/>).
        </dd>

        <dt>AIP Message</dt>
        <dd>
          The protocol data unit of AIP.  An independent, self-contained
          datagram carrying a fixed header, source and destination
          agent:// URIs, optional TLV options, and a payload.
        </dd>

        <dt>Peer ID</dt>
        <dd>
          A globally unique identifier for a network participant, derived
          from its Ed25519 public key.  Used at the link layer
          for point-to-point addressing.
        </dd>

        <dt>Node</dt>
        <dd>
          A machine (physical or virtual) running one AIP module.  A node
          has one peer ID.  Multiple agents <bcp14>MAY</bcp14> run on a
          single node.
        </dd>

      </dl>
      <t>
        In summary: a node has one link-layer Peer ID; one or more
        agents <bcp14>MAY</bcp14> run on that node; AIP addresses
        agents by agent:// URI, not by Peer ID.
      </t>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 3 — THE agent:// URI SCHEME                          -->
    <!-- ============================================================ -->

    <section anchor="uri-scheme">
      <name>The agent:// URI Scheme</name>

      <t>
        The agent:// URI is the fundamental addressing primitive of AIP.
        It identifies an agent by a human-readable, capability-descriptive
        name rather than by a numeric network address.  The scheme is
        registered with IANA in accordance with <xref target="RFC7595"/>
        (see <xref target="iana-uri-scheme"/>).
      </t>
      <t>
        An agent:// URI is a <strong>routing token</strong> designating a
        capability endpoint; it does not necessarily correspond to a
        singular legal identity.  Multiple agents, instances, or replicas
        <bcp14>MAY</bcp14> be reachable through the same URI via
        resolver-level load balancing or failover.  Conversely, a single
        agent <bcp14>MAY</bcp14> register multiple URIs for different
        capabilities.
      </t>

      <section anchor="uri-abnf">
        <name>Syntax</name>
        <t>
          The syntax of agent:// URIs is defined in ABNF
          <xref target="RFC5234"/>, following the generic URI
          structure of <xref target="RFC3986"/>:
        </t>
        <sourcecode type="abnf"><![CDATA[
agent-uri    = "agent://" agent-path
agent-path   = [ namespace "/" ] name [ "@" version ]
namespace    = ident
name         = ident
ident        = LCALPHA-DIGIT *( LCALPHA-DIGIT / "-" )
version      = 1*( DIGIT / "." / "-" / ALPHA )
LCALPHA-DIGIT = %x61-7A / DIGIT    ; a-z / 0-9
]]></sourcecode>
        <t>
          Names and namespaces <bcp14>MUST</bcp14> begin with a lowercase
          letter or digit, <bcp14>MUST NOT</bcp14> end with a hyphen, and
          <bcp14>MUST</bcp14> be at least one character long.  Uppercase
          letters are not permitted; implementations
          <bcp14>MUST</bcp14> reject URIs containing uppercase letters
          rather than silently normalizing them.
        </t>
        <t>
          The total URI length (including the "agent://" prefix)
          <bcp14>MUST NOT</bcp14> exceed 263 octets (255 for the
          wire-encoded path plus 8 for the "agent://" prefix).
        </t>
      </section>

      <section anchor="uri-comparison">
        <name>Comparison Rules</name>
        <t>
          Because all characters in agent:// URIs are already constrained
          to lowercase, comparison is a simple octet-by-octet match of
          the wire-encoded forms after the following normalization:
        </t>
        <ol>
          <li>Remove any trailing slash.</li>
          <li>Remove any trailing "@" not followed by a version string.</li>
        </ol>
        <t>
          No percent-decoding is performed because the agent:// scheme
          does not permit percent-encoded characters.
        </t>
      </section>

      <section anchor="uri-wire">
        <name>Wire Encoding</name>
        <t>
          On the wire, agent:// URIs are encoded WITHOUT the "agent://"
          prefix.  The prefix is implicit -- all addresses in AIP messages
          are agent:// URIs.  The encoding is UTF-8.
        </t>
        <t>
          The encoding function strips the 8-octet "agent://" prefix:
        </t>
        <ul>
          <li>wire_encode("agent://acme/translator") -> "acme/translator" (15 octets)</li>
          <li>wire_encode("agent://translator") -> "translator" (10 octets)</li>
          <li>wire_encode("agent://x/y@1.0") -> "x/y@1.0" (7 octets)</li>
        </ul>
        <t>
          The decoding function prepends "agent://":
        </t>
        <ul>
          <li>wire_decode("acme/translator") -> "agent://acme/translator"</li>
        </ul>
        <t>
          This avoids repeating the scheme prefix for both source
          and destination addresses on the wire.
        </t>
      </section>

      <section anchor="uri-examples">
        <name>Examples</name>
        <t>Valid agent:// URIs:</t>
        <ul>
          <li>agent://translator -- global namespace, name only</li>
          <li>agent://acme/code-reviewer@2.1 -- namespace "acme", name "code-reviewer", version "2.1"</li>
          <li>agent://openai/gpt-assistant -- namespace "openai", name "gpt-assistant"</li>
          <li>agent://research/arxiv-search -- namespace "research", name "arxiv-search"</li>
        </ul>
      </section>

      <section anchor="uri-rationale">
        <name>Design Rationale</name>
        <t>
          A dedicated URI scheme is used rather than an existing scheme
          because agent:// URIs serve as first-class routing tokens, not
          as locators that resolve to network endpoints.  Existing
          alternatives were considered and found insufficient:
        </t>
        <ul>
          <li>DID URIs (did:method:...) are identity-centric and lack a
              built-in namespace/version structure for capability
              addressing.</li>
          <li>HTTPS well-known paths (https://host/.well-known/agent/...)
              couple agent identity to DNS names and TLS certificates,
              reintroducing the topology-bound addressing that AIP
              avoids.</li>
          <li>Opaque identifiers with external resolvers provide no
              human-readable semantics and require mandatory resolver
              infrastructure before any message can be sent.</li>
        </ul>
        <t>
          The agent:// scheme provides compact, human-readable routing
          tokens with a fixed wire encoding convention
          (<xref target="uri-wire"/>).
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 4 — AIP MESSAGE FORMAT                               -->
    <!-- ============================================================ -->

    <section anchor="message-format">
      <name>AIP Message Format</name>

      <t>
        AIP messages are carried as payloads of link-layer frames.  An AIP
        message consists of a 16-octet fixed header, a variable-length
        address block containing the source and destination URIs (padded
        to a 4-octet boundary), a variable-length TLV options region, and
        a variable-length payload.
      </t>

      <section anchor="header-diagram">
        <name>Header Structure</name>
        <figure anchor="fig-header">
          <name>AIP Message Header (16 octets fixed)</name>
          <artwork type="ascii-art"><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  Type |   Protocol    |  TTL  | Flags |   Reserved    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Message ID                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Payload Length                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Src URI Len |   Dst URI Len |        Options Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Source URI (wire-encoded, variable)    ...             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Destination URI (wire-encoded, variable) ...          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Address Padding (to 4-octet boundary)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Options (TLV, padded to 4-octet boundary) ...         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Payload (variable)    ...                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Note: one tick mark represents one bit position.
]]></artwork>
        </figure>
      </section>

      <section anchor="field-definitions">
        <name>Field Definitions</name>

        <dl>
          <dt>Version (4 bits)</dt>
          <dd>
            <t>
              Protocol version.  The current version is 1.
              Implementations <bcp14>MUST</bcp14> silently discard
              messages with an unrecognized version.
            </t>
          </dd>

          <dt>Type (4 bits)</dt>
          <dd>
            <t>The message type:</t>
            <table anchor="tbl-types">
              <name>AIP Message Types</name>
              <thead>
                <tr>
                  <th>Value</th>
                  <th>Name</th>
                  <th>Description</th>
                </tr>
              </thead>
              <tbody>
                <tr><td>0</td><td>DATA</td><td>Normal data message (payload delivery to upper layer).</td></tr>
                <tr><td>1</td><td>ERROR</td><td>Error report (carries an error payload, see <xref target="error-handling"/>).</td></tr>
                <tr><td>2</td><td>PING</td><td>Liveness probe.  Recipient <bcp14>MUST</bcp14> reply with PONG.</td></tr>
                <tr><td>3</td><td>PONG</td><td>Liveness reply.  Carries the Message ID of the original PING.</td></tr>
                <tr><td>4-15</td><td></td><td>Reserved for future use.</td></tr>
              </tbody>
            </table>
            <t>
              Implementations <bcp14>MUST</bcp14> silently discard
              messages with unrecognized Type values.
            </t>
          </dd>

          <dt>Protocol (8 bits)</dt>
          <dd>
            <t>
              Identifies the upper-layer protocol that will process the
              payload.  This field is analogous to the Protocol field in
              IPv4 <xref target="RFC0791"/>.  It enables AIP to
              demultiplex incoming messages to the correct upper-layer
              handler.
            </t>
            <table anchor="tbl-protocol">
              <name>AIP Protocol Numbers</name>
              <thead>
                <tr>
                  <th>Value</th>
                  <th>Name</th>
                  <th>Description</th>
                </tr>
              </thead>
              <tbody>
                <tr><td>0</td><td>NONE</td><td>No upper-layer protocol (used for PING/PONG/control messages).</td></tr>
                <tr><td>1</td><td>AITP</td><td>Agent Invocation Transport Protocol <xref target="I-D.song-anp-aitp"/>.</td></tr>
                <tr><td>2</td><td>ANS</td><td>Agent Name System <xref target="I-D.song-anp-ans"/>.</td></tr>
                <tr><td>3</td><td>ADP</td><td>Agent Description Protocol <xref target="I-D.song-anp-adp"/>.</td></tr>
                <tr><td>4-254</td><td></td><td>Available for future assignment (IANA registry).</td></tr>
                <tr><td>255</td><td>EXPT</td><td>Experimental / private use.</td></tr>
              </tbody>
            </table>
            <t>
              The Type and Protocol fields serve orthogonal purposes.
              Type identifies AIP's own control semantics (data delivery,
              error reporting, liveness probing).  Protocol identifies
              which upper-layer consumer processes the payload.  Thus,
              PING/PONG are AIP-layer operations (Type) that carry no
              upper-layer payload, while AITP, ANS, and ADP are upper-
              layer consumers (Protocol) whose payloads travel inside
              DATA messages (Type = 0).
            </t>
            <t>
              In normal operation, ANS and ADP methods are carried as
              AITP segments (Protocol = 1, AITP).  Protocol = 2 (ANS)
              and Protocol = 3 (ADP) are reserved for future use cases
              where a lightweight, single-datagram exchange bypasses
              AITP association overhead — for example, bootstrap
              resolution when no AITP association can yet be
              established, or one-shot name announcements in
              resource-constrained environments.  Until such uses are
              formally specified, conforming implementations
              <bcp14>SHOULD</bcp14> use Protocol = 1 (AITP) for all
              ANS and ADP exchanges, and <bcp14>MUST</bcp14> silently
              discard messages with Protocol values 2 or 3 if they do
              not implement direct-datagram handlers for those
              protocols.
            </t>
          </dd>

          <dt>TTL (4 bits)</dt>
          <dd>
            <t>
              Time to Live.  An upper bound on the number of relay hops.
              Each relaying node <bcp14>MUST</bcp14> decrement the TTL
              by 1.  When the TTL reaches zero, the message
              <bcp14>MUST</bcp14> be discarded; if the ERR flag is set,
              an ERROR message with code TTL_EXPIRED
              <bcp14>SHOULD</bcp14> be returned to the source.
            </t>
            <t>
              The default TTL is 8.  Valid range is 0-15.  A TTL of 0
              means the message <bcp14>MUST NOT</bcp14> be relayed; it is
              delivered only if the destination is local.
            </t>
          </dd>

          <dt>Flags (4 bits)</dt>
          <dd>
            <t>A bitmask of control flags:</t>
            <table anchor="tbl-flags">
              <name>AIP Flag Bits</name>
              <thead>
                <tr>
                  <th>Bit</th>
                  <th>Value</th>
                  <th>Name</th>
                  <th>Description</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>3 (MSB)</td>
                  <td>0x8</td>
                  <td>SIG</td>
                  <td>Message carries an Ed25519 signature (64 octets) appended after the payload.</td>
                </tr>
                <tr>
                  <td>2</td>
                  <td>0x4</td>
                  <td>ERR</td>
                  <td>Error report requested.  If delivery fails, an ERROR message <bcp14>SHOULD</bcp14> be returned to the source.</td>
                </tr>
                <tr>
                  <td>1</td>
                  <td>0x2</td>
                  <td>SEM</td>
                  <td>Semantic resolution provenance.  When clear, AIP performs exact URI resolution (the baseline).  When set, the message was delivered via resolver-assisted semantic discovery: AIP resolved a natural-language query through DISCOVER before transmission.  The Destination URI field carries the resolved agent:// URI; the original query is recorded in the SemQuery option (Type 5, <xref target="options"/>).  Whether the resolver supports semantic resolution is deployment-specific (see <xref target="resolver-semantic-ext"/>).</td>
                </tr>
                <tr>
                  <td>0 (LSB)</td>
                  <td>0x1</td>
                  <td>RLY</td>
                  <td>Relay permitted.  If set, intermediate nodes <bcp14>MAY</bcp14> forward this message toward the destination.</td>
                </tr>
              </tbody>
            </table>
          </dd>

          <dt>Reserved (8 bits)</dt>
          <dd>
            <t>
              Reserved for future use.  Senders <bcp14>MUST</bcp14> set
              this field to zero.  Receivers <bcp14>MUST</bcp14> ignore
              this field.
            </t>
          </dd>

          <dt>Message ID (32 bits)</dt>
          <dd>
            <t>
              A sender-assigned identifier for deduplication and
              request-response correlation.  Implementations
              <bcp14>MUST</bcp14> ensure uniqueness among outstanding
              messages to the same destination.  A monotonically
              increasing counter is one possible strategy.
            </t>
          </dd>

          <dt>Payload Length (32 bits)</dt>
          <dd>
            <t>
              The length in octets of the payload (not including the
              header, address block, or options).  Maximum value is
              65535; implementations <bcp14>MUST</bcp14> reject messages
              with Payload Length exceeding 65535.
            </t>
          </dd>

          <dt>Src URI Len (8 bits)</dt>
          <dd>
            <t>
              The length in octets of the wire-encoded Source URI.  A
              value of 0 is permitted only in ERROR messages (system-
              generated error with no agent source).  Maximum 255.
            </t>
          </dd>

          <dt>Dst URI Len (8 bits)</dt>
          <dd>
            <t>
              The length in octets of the wire-encoded Destination URI.
              <bcp14>MUST NOT</bcp14> be 0.  Maximum 255.
            </t>
          </dd>

          <dt>Options Length (16 bits)</dt>
          <dd>
            <t>
              The total length in octets of the TLV options region,
              including any padding.  If no options are present, this
              field is 0.  Maximum 65535.  The options region
              <bcp14>MUST</bcp14> be padded to a 4-octet boundary.
            </t>
          </dd>

          <dt>Source URI (variable, 0-255 octets)</dt>
          <dd>
            <t>
              The agent:// URI of the sender in wire-encoded form
              (without the "agent://" prefix).
            </t>
          </dd>

          <dt>Destination URI (variable, 1-255 octets)</dt>
          <dd>
            <t>
              The agent:// URI of the intended recipient in wire-encoded
              form (without the "agent://" prefix).  This field always
              contains a valid wire-encoded agent:// URI, regardless of
              whether the SEM flag is set.  When the SEM flag is set, AIP
              resolves the query before transmission and places the
              resolved URI here; the original query is carried in the
              SemQuery option (<xref target="options"/>).
            </t>
          </dd>

          <dt>Address Padding (0-3 octets)</dt>
          <dd>
            <t>
              Zero-valued padding octets added after the Destination URI
              to bring the combined address block (Src URI + Dst URI +
              padding) to a 4-octet boundary.
            </t>
          </dd>
        </dl>
      </section>

      <section anchor="options">
        <name>TLV Options</name>
        <t>
          The options region carries zero or more Type-Length-Value (TLV)
          encoded options.  Options provide extensibility without
          modifying the fixed header.
        </t>
        <t>
          Each option is encoded as:
        </t>
        <artwork type="ascii-art"><![CDATA[
+--------+--------+----------------------------+
|  Type  | Length  |    Data (Length octets)     |
+--------+--------+----------------------------+
  1 byte   1 byte    variable
]]></artwork>
        <t>
          Exception: Type 0 (Pad1) is a single zero octet with no Length
          or Data fields; it is used for single-octet alignment padding.
        </t>

        <table anchor="tbl-options">
          <name>Standard AIP Options</name>
          <thead>
            <tr>
              <th>Type</th>
              <th>Name</th>
              <th>Length</th>
              <th>Description</th>
            </tr>
          </thead>
          <tbody>
            <tr><td>0</td><td>Pad1</td><td>0</td><td>Single-octet padding (no Length field).</td></tr>
            <tr><td>1</td><td>PadN</td><td>N</td><td>Multi-octet padding (N zero octets).</td></tr>
            <tr><td>2</td><td>Timestamp</td><td>8</td><td>UTC Unix timestamp in microseconds (uint64, big-endian).  Used for latency measurement and replay rejection.</td></tr>
            <tr><td>3</td><td>Trace</td><td>variable</td><td>Opaque trace context blob for distributed tracing.  Implementations <bcp14>MAY</bcp14> use W3C Trace Context traceparent format or any other tracing scheme.</td></tr>
            <tr><td>4</td><td>Priority</td><td>1</td><td>Message priority hint (0 = lowest, 255 = highest).  Receivers <bcp14>MAY</bcp14> use this for scheduling.</td></tr>
            <tr><td>5</td><td>SemQuery</td><td>variable</td><td>UTF-8 semantic query string.  <bcp14>MUST</bcp14> be present when the SEM flag is set; <bcp14>MUST NOT</bcp14> be present when the SEM flag is clear.  Records the original natural-language query used for resolver-assisted discovery.</td></tr>
            <tr><td>6-127</td><td></td><td></td><td>Available for future assignment (IANA).</td></tr>
            <tr><td>128-254</td><td></td><td></td><td>Available for experimental / private use.</td></tr>
            <tr><td>255</td><td></td><td></td><td>Reserved.</td></tr>
          </tbody>
        </table>

        <t>
          The entire options region <bcp14>MUST</bcp14> be padded to a
          4-octet boundary using Pad1 or PadN options.
          Implementations <bcp14>MUST</bcp14> ignore unrecognized option
          types (skip by reading Type and Length, then advancing Length
          octets).
        </t>
      </section>

      <section anchor="signature">
        <name>Message Signature</name>
        <t>
          When the SIG flag (bit 3) is set, the message carries a 64-octet
          Ed25519 signature appended immediately after the payload.  The
          signature <bcp14>MUST NOT</bcp14> be included in the Payload
          Length field; receivers detect its presence via the SIG flag.
        </t>
        <t>
          The signature is computed over:
        </t>
        <artwork type="ascii-art"><![CDATA[
sign_input = fixed_header (16 octets, with Reserved set to 0)
           || src_uri_wire
           || dst_uri_wire
           || options_data (without padding)
           || payload
]]></artwork>
        <t>
          The signing key is the Ed25519 private key corresponding to
          the source agent's identity.  Verification uses the
          public key bound to the source agent:// URI; the receiver
          obtains this key from its local resolver (see
          <xref target="sec-identity-key"/>).  The node's link-layer
          Peer ID is used only for message delivery, not for signature
          verification.
        </t>
        <t>
          Implementations <bcp14>SHOULD</bcp14> set the SIG flag on all
          messages in production deployments.  Implementations
          <bcp14>MUST</bcp14> verify signatures on incoming SIG-flagged
          messages and <bcp14>MUST</bcp14> discard messages with invalid
          signatures.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 5 — LOCAL RESOLVER                                   -->
    <!-- ============================================================ -->

    <section anchor="local-resolver">
      <name>Local Resolver</name>

      <t>
        AIP delegates all name resolution to a local resolver service.
        The resolver maps agent:// URIs to peer IDs that AIP can use
        for link-layer transmission.
      </t>
      <t>
        AIP makes no assumptions about resolver internals.  Any
        service that satisfies the Resolver interface
        (<xref target="resolver-interface"/>) is acceptable.
        ANS <xref target="I-D.song-anp-ans"/> is one companion
        resolver architecture.
      </t>

      <section anchor="resolver-interface">
        <name>Resolver Interface</name>
        <t>
          The resolver <bcp14>MUST</bcp14> provide:
        </t>
        <dl>
          <dt>RESOLVE(uri) -> (peer_id, ok)</dt>
          <dd>
            <t>
              Maps a fully-qualified agent:// URI to a peer ID.  Returns
              ok = false if the URI cannot be resolved.
            </t>
          </dd>

          <dt>IS_LOCAL(uri) -> bool</dt>
          <dd>
            <t>
              Returns true if the URI is registered by an agent on the
              local node.
            </t>
          </dd>
        </dl>
        <t>
          The resolver <bcp14>MAY</bcp14> use any local data structure
          (cache, table, or database) to satisfy these operations.
          AIP does not constrain resolver internals, storage model,
          propagation mechanism, or ranking method.  Additional
          resolver operations such as registration and unregistration
          are outside AIP's scope and are defined by the resolver
          specification.
        </t>
      </section>

      <section anchor="resolver-semantic-ext">
        <name>Optional Semantic Resolver Extension</name>
        <t>
          A resolver <bcp14>MAY</bcp14> additionally support the
          following operation for use with the SEM flag
          (<xref target="semantic-resolution"/>):
        </t>
        <dl>
          <dt>DISCOVER(query, tags, namespace, limit) -> list of (uri, peer_id, score)</dt>
          <dd>
            <t>
              Maps a natural-language query to a ranked list of matching
              agents.  A resolver that does not support semantic
              resolution <bcp14>MUST</bcp14> return an empty list.
            </t>
          </dd>
        </dl>
        <t>
          Implementations that do not support semantic resolution are
          fully conformant with this specification.
        </t>
      </section>

      <section anchor="resolver-requirements">
        <name>Requirements on Implementations</name>
        <t>
          Every AIP module <bcp14>MUST</bcp14> be initialized with a
          resolver.  If no full resolver is available, a minimal
          implementation that only supports exact lookup of locally
          registered URIs is sufficient.
        </t>
        <t>
          The resolver <bcp14>SHOULD</bcp14> cache results to avoid
          repeated lookups for the same URI.  Cache entries
          <bcp14>SHOULD</bcp14> expire based on a TTL provided by the
          resolver.  Implementations <bcp14>MUST</bcp14> enforce a
          maximum cache size to prevent unbounded memory growth;
          deployment-specific defaults are expected.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 6 — NAME RESOLUTION                                  -->
    <!-- ============================================================ -->

    <section anchor="name-resolution">
      <name>Name Resolution</name>

      <t>
        AIP resolves destination URIs by calling the local resolver
        (<xref target="resolver-interface"/>).  Baseline AIP
        operation uses exact destination tokens; resolver-assisted
        semantic discovery is an optional extension that occurs
        before forwarding.  Once a destination URI has been selected,
        AIP forwarding proceeds identically in both cases.
      </t>
      <t>
        The resolution strategy depends on the SEM flag:
      </t>

      <section anchor="exact-resolution">
        <name>Exact Resolution (SEM flag clear)</name>
        <t>
          When the SEM flag is clear, the Destination URI is a fully-
          qualified agent:// URI.  AIP calls RESOLVE(uri) on the local
          resolver.  If the resolver returns ok = true, AIP uses the
          returned peer ID for transmission.  If ok = false, AIP
          returns NAME_NOT_FOUND to the upper layer.
        </t>
        <t>
          The resolver <bcp14>MAY</bcp14> use local or distributed
          mechanisms to satisfy the lookup; these mechanisms are
          outside AIP's scope.
        </t>
      </section>

      <section anchor="semantic-resolution">
        <name>Semantic Resolution (SEM flag set) -- Optional Extension</name>
        <t>
          Semantic resolution is an <strong>optional extension</strong>.
          AIP implementations are fully conformant without it.  A
          resolver that does not support semantic resolution
          <bcp14>MUST</bcp14> return an empty list from DISCOVER,
          causing AIP to return NAME_NOT_FOUND.
        </t>
        <t>
          When the SEM flag is set and the resolver supports semantic
          resolution, AIP calls DISCOVER(query, ...) on the local
          resolver and uses the highest-scoring result.  AIP places
          the resolved agent:// URI in the Destination URI field and
          records the original query string in the SemQuery
          option (Type 5).  If the resolver returns an empty list,
          AIP returns NAME_NOT_FOUND to the upper layer.
        </t>
        <t>
          AIP does not specify any particular scoring algorithm.  The
          scoring strategy -- including text similarity, tag matching,
          freshness, and trust signals -- is defined by the resolver
          implementation.  <xref target="appendix-scoring"/> provides
          an informative example using one possible scoring formula.
        </t>
        <t>
          A failed semantic query (empty result list) causes AIP to
          return NAME_NOT_FOUND.  AIP does not perform query rewriting,
          fallback searches, or multi-step retrieval; such behavior, if
          desired, is the responsibility of the resolver or the
          application.
        </t>
        <t>
          After resolution, AIP performs ordinary exact-URI delivery;
          semantic interpretation is confined to resolver selection and
          is not part of the forwarding semantics.  The SEM flag does
          not alter forwarding behavior; it records resolver-assisted
          destination selection provenance for policy, debugging, and
          audit purposes.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 7 — MESSAGE PROCESSING                               -->
    <!-- ============================================================ -->

    <section anchor="message-processing">
      <name>Message Processing</name>

      <t>
        This section defines AIP's complete processing model.  The
        send and receive paths described below are self-contained:
        they depend only on the local resolver interface
        (<xref target="resolver-interface"/>) and the link-layer
        TRANSMIT/DELIVER primitives
        (<xref target="lower-layer-interface"/>).  No knowledge of
        companion protocols is required to implement these paths.
      </t>

      <section anchor="mp-sending">
        <name>Sending</name>
        <t>
          When the upper layer calls SEND:
        </t>
        <ol>
          <li>
            <t><strong>Validate the source URI.</strong></t>
            <t>
              The source URI <bcp14>MUST</bcp14> be locally registered
              (IS_LOCAL returns true).  If not, the send operation
              <bcp14>MUST</bcp14> fail.
            </t>
          </li>
          <li>
            <t><strong>Resolve the destination.</strong></t>
            <t>
              If the SEM flag is clear, call RESOLVE(destination) on the
              local resolver.  If the SEM flag is set, call
              DISCOVER(destination, ...) and use the highest-scoring
              result; place the resolved agent:// URI in the Destination
              URI field and record the original query in a SemQuery
              option (Type 5).  If resolution fails, return
              NAME_NOT_FOUND to the upper layer.
            </t>
          </li>
          <li>
            <t><strong>Construct the message.</strong></t>
            <t>
              Build the 16-octet fixed header with Version = 1, Type,
              Protocol, TTL (default 8), Flags, Reserved = 0, auto-
              generated Message ID, Payload Length.  Wire-encode source
              and destination URIs.  Encode any options (including the
              SemQuery option if SEM flag is set).
            </t>
          </li>
          <li>
            <t><strong>Sign (if SIG flag set).</strong></t>
            <t>
              Compute the Ed25519 signature per
              <xref target="signature"/> and append it after the payload.
            </t>
          </li>
          <li>
            <t><strong>Transmit.</strong></t>
            <t>
              Serialize and call the link layer's TRANSMIT with the
              resolved peer ID and the serialized bytes.
            </t>
          </li>
        </ol>
      </section>

      <section anchor="mp-receiving">
        <name>Receiving</name>
        <t>
          When the link layer delivers bytes:
        </t>
        <ol>
          <li>
            <t><strong>Parse and validate.</strong></t>
            <t>
              Decode fixed header.  If Version is unrecognized, discard.
              If Type is unrecognized, discard.  If the total data is
              shorter than the computed message size, discard.
            </t>
          </li>
          <li>
            <t><strong>Verify signature (if SIG flag set).</strong></t>
            <t>
              Extract the 64-byte signature.  Verify against the
              public key bound to the source agent:// URI, as obtained
              from the local resolver
              (see <xref target="sec-identity-key"/>).  If
              verification fails, discard.  If ERR flag is set,
              <bcp14>SHOULD</bcp14> send INVALID_SIGNATURE error.
            </t>
          </li>
          <li>
            <t><strong>Deduplicate.</strong></t>
            <t>
              Check (Source URI, Message ID) against a bounded
              deduplication cache.  If a match exists, discard.
              Otherwise, add to cache.
            </t>
          </li>
          <li>
            <t><strong>Check TTL.</strong></t>
            <t>
              If TTL is 0 and destination is not local, discard.  If ERR
              flag is set, send TTL_EXPIRED error.
            </t>
          </li>
          <li>
            <t><strong>Deliver or relay.</strong></t>
            <t>
              If IS_LOCAL(destination) returns true, decrement TTL and
              dispatch to the upper-layer handler identified by the
              Protocol field.  If not local and RLY flag is set and
              TTL > 0, decrement TTL, call RESOLVE(destination) to
              obtain the next-hop peer, and re-transmit.  If not local
              and RLY is not set, discard.
            </t>
          </li>
        </ol>
      </section>

      <section anchor="error-handling">
        <name>Error Handling</name>
        <t>
          When an error occurs and the ERR flag is set, the AIP module
          <bcp14>SHOULD</bcp14> generate an ERROR message (Type = 1)
          to the original source.  ERROR generation is best-effort;
          it is not guaranteed and <bcp14>MAY</bcp14> itself be
          suppressed under overload or resource constraints.  ERROR
          messages <bcp14>MUST NOT</bcp14> be generated in response
          to other ERROR messages (preventing loops).
        </t>
        <t>
          The error payload is encoded as:
        </t>
        <artwork type="ascii-art"><![CDATA[
+--------+--------+--------+--------+--------+---...---+
|  Code  | Reservd|     Original Message ID   | Detail  |
+--------+--------+--------+--------+--------+---...---+
  1 byte   1 byte        4 bytes              variable
]]></artwork>

        <table anchor="tbl-errors">
          <name>AIP Error Codes</name>
          <thead>
            <tr>
              <th>Code</th>
              <th>Name</th>
              <th>Description</th>
            </tr>
          </thead>
          <tbody>
            <tr><td>0</td><td></td><td>Reserved (<bcp14>MUST NOT</bcp14> be used).</td></tr>
            <tr><td>1</td><td>NAME_NOT_FOUND</td><td>Destination URI could not be resolved.</td></tr>
            <tr><td>2</td><td>TTL_EXPIRED</td><td>Message TTL reached zero before delivery.</td></tr>
            <tr><td>3</td><td>MSG_TOO_LARGE</td><td>Message exceeds maximum size (65535 octets payload).</td></tr>
            <tr><td>4</td><td>INVALID_SIGNATURE</td><td>Ed25519 signature verification failed.</td></tr>
            <tr><td>5</td><td>RATE_LIMITED</td><td>Sender exceeded rate limit.</td></tr>
            <tr><td>6</td><td>PROTOCOL_ERROR</td><td>Malformed message or protocol violation.</td></tr>
            <tr><td>7</td><td>SHUTTING_DOWN</td><td>Receiving node is shutting down gracefully.</td></tr>
            <tr><td>8</td><td>INTERNAL_ERROR</td><td>Unspecified internal processing error.</td></tr>
            <tr><td>9-255</td><td></td><td>Available for future assignment (IANA).</td></tr>
          </tbody>
        </table>
        <t>
          The Original Message ID field <bcp14>MUST</bcp14> carry the
          full 32-bit Message ID of the message that triggered the error,
          enabling precise correlation.  The Detail field is a UTF-8
          string providing additional context; it <bcp14>MAY</bcp14> be
          empty.
        </t>
      </section>

      <section anchor="deduplication">
        <name>Deduplication</name>
        <t>
          In a GossipSub topology, messages may arrive via multiple paths.
          Implementations <bcp14>MUST</bcp14> maintain a deduplication
          cache keyed by (Source URI, Message ID).  Messages matching
          a cache entry <bcp14>MUST</bcp14> be silently discarded.
          Implementations <bcp14>MUST</bcp14> bound the cache size
          and entry lifetime to prevent unbounded resource consumption;
          deployment-specific defaults are expected.
        </t>
      </section>

      <section anchor="rate-limiting">
        <name>Rate Limiting</name>
        <t>
          Implementations <bcp14>MUST</bcp14> enforce per-peer rate
          limiting to prevent denial-of-service.  Specific thresholds
          are deployment-specific; implementations <bcp14>SHOULD</bcp14>
          document their default values.  Messages exceeding the rate
          limit <bcp14>SHOULD</bcp14> be discarded; if the ERR flag is
          set, a RATE_LIMITED error <bcp14>SHOULD</bcp14> be returned.
        </t>
      </section>

    </section>

    <!-- ============================================================ -->
    <!--  SECTION 8 — INTERFACES                                       -->
    <!-- ============================================================ -->

    <section anchor="interfaces">
      <name>Interfaces</name>

      <section anchor="upper-layer-interface">
        <name>Upper Layer Interface (AITP and others)</name>
        <t>
          AIP provides the following service primitives to upper-layer
          protocols:
        </t>
        <dl>
          <dt>SEND(source, destination, protocol, payload, options) -> message_id</dt>
          <dd>
            <t>Sends a datagram.</t>
            <ul>
              <li><strong>source</strong> -- agent:// URI.  <bcp14>MUST</bcp14> be locally registered.</li>
              <li><strong>destination</strong> -- an agent:// URI token for baseline delivery; when the SEM flag is requested, the caller <bcp14>MAY</bcp14> provide a semantic query string, which the local resolver <bcp14>MUST</bcp14> resolve to an agent:// URI before transmission.</li>
              <li><strong>protocol</strong> -- upper-layer protocol number (0-255).</li>
              <li><strong>payload</strong> -- opaque bytes.</li>
              <li><strong>options</strong> -- optional: type, ttl, flags, message_id, TLV options list.</li>
            </ul>
            <t>Returns: Message ID, or error.</t>
          </dd>

          <dt>RECEIVE callback(source, destination, protocol, payload, message_id, options)</dt>
          <dd>
            <t>
              Invoked when a message arrives for a locally registered
              agent.  The Protocol field identifies which upper-layer
              handler receives the callback.
            </t>
          </dd>
        </dl>
        <t>
          Note: Registration, unregistration, and semantic discovery
          are resolver operations, not AIP primitives.
        </t>
      </section>

      <section anchor="lower-layer-interface">
        <name>Lower Layer Interface (Link Layer)</name>
        <dl>
          <dt>TRANSMIT(peer_id, raw_bytes)</dt>
          <dd>
            <t>
              Sends bytes to a peer.  The link layer routes them using
              whatever technology is available (libp2p, TCP, QUIC, WS,
              Bluetooth, etc.).
            </t>
          </dd>

          <dt>DELIVER callback(peer_id, raw_bytes)</dt>
          <dd>
            <t>
              Invoked by the link layer for each received message.  AIP
              registers this callback during initialization.
            </t>
          </dd>
        </dl>
        <t>
          AIP makes no assumptions about the link layer beyond these two
          primitives.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 9 — SECURITY CONSIDERATIONS                         -->
    <!-- ============================================================ -->

    <section anchor="security">
      <name>Security Considerations</name>

      <section anchor="sec-auth">
        <name>Message Authentication</name>
        <t>
          When the SIG flag is set, AIP messages carry an Ed25519
          signature providing origin authentication and integrity
          protection.  Implementations <bcp14>SHOULD</bcp14> set the
          SIG flag on all messages.  Implementations <bcp14>MUST</bcp14>
          verify signatures before processing signed messages and
          <bcp14>MUST</bcp14> discard messages with invalid signatures.
        </t>
        <t>
          Signature verification is performed against the public key
          bound to the source agent:// URI; node Peer IDs are link-
          layer artifacts and are not used for application-layer
          signature verification.  The receiver obtains the URI-to-key
          binding from its local resolver
          (see <xref target="sec-identity-key"/>).
        </t>
      </section>

      <section anchor="sec-identity-key">
        <name>Identity and Signing Key Relationship</name>
        <t>
          Each agent possesses its own Ed25519 key pair.  A node's
          link-layer Peer ID is derived from one Ed25519 public key,
          but multiple agents <bcp14>MAY</bcp14> run on a single node,
          each with a distinct key pair and agent:// URI.
        </t>
        <t>
          When multiple agents share a node, the message signature
          binds the payload to the <strong>agent's</strong> key, not
          the node's Peer ID.  The receiver obtains the agent's public
          key from the resolver (which maintains the URI-to-public-key
          binding).
        </t>
        <t>
          Relay nodes that forward messages on behalf of others need
          not verify the signature; only the final destination endpoint
          <bcp14>MUST</bcp14> verify.  Relay nodes
          <bcp14>MAY</bcp14> verify opportunistically if they have
          access to the signing key.
        </t>
      </section>

      <section anchor="sec-spoofing">
        <name>Name Spoofing</name>
        <t>
          AIP relies on the resolver to verify that agent:// URIs are
          bound to legitimate Ed25519 public keys.  The specifics of
          name registration verification are defined by the resolver
          specification.
        </t>
      </section>

      <section anchor="sec-poisoning">
        <name>Resolution Poisoning</name>
        <t>
          A malicious resolver could return forged peer IDs, directing
          messages to an attacker.  Mitigations:
        </t>
        <ul>
          <li>Implementations <bcp14>SHOULD</bcp14> use the SIG flag so
              that receivers can verify message authenticity independent
              of resolution correctness.</li>
          <li>Resolver implementations <bcp14>SHOULD</bcp14>
              require Ed25519 signatures on all name entries.</li>
        </ul>
      </section>

      <section anchor="sec-replay">
        <name>Replay Attacks</name>
        <t>Mitigated by:</t>
        <ul>
          <li>Deduplication cache: (Source URI, Message ID) pairs.</li>
          <li>TTL: bounded hop count limits propagation.</li>
          <li>Timestamp option: implementations <bcp14>SHOULD</bcp14>
              include the Timestamp option and reject messages outside
              a deployment-specific freshness window.</li>
        </ul>
      </section>

      <section anchor="sec-dos">
        <name>Resource Exhaustion</name>
        <t>
          Per-peer rate limiting (<xref target="rate-limiting"/>),
          maximum message size (65535 octets), and resolver cache
          capacity limits prevent resource exhaustion.
        </t>
      </section>

      <section anchor="sec-semantic-gaming">
        <name>Semantic Resolution Gaming</name>
        <t>
          When the SEM flag is used, the quality of results depends on
          the resolver's scoring algorithm.  Resolver implementations
          <bcp14>SHOULD</bcp14> incorporate anti-gaming measures such
          as trust signals and keyword-repetition dampening.  These
          defenses are outside AIP's scope and are defined by the
          resolver specification.
        </t>
        <t>
          If the SEM flag is set but the SemQuery option is absent or
          malformed, implementations <bcp14>MUST</bcp14> treat the
          message as a protocol error and discard it.  When the SIG
          flag is also set, the SemQuery option is covered by the
          signed message envelope, protecting provenance integrity.
        </t>
      </section>

      <section anchor="sec-privacy">
        <name>Privacy</name>
        <t>
          Agent:// URIs, resolver metadata, and message headers are
          visible to network participants.  AIP does not provide payload
          confidentiality (AITP's responsibility) or metadata privacy.
          Applications requiring metadata privacy <bcp14>SHOULD</bcp14>
          use privacy-preserving lower-layer routing mechanisms.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 10 — IANA CONSIDERATIONS                             -->
    <!-- ============================================================ -->

    <section anchor="iana">
      <name>IANA Considerations</name>

      <t>
        This document requests the creation of four new IANA registries
        and the registration of a URI scheme.
      </t>

      <section anchor="iana-uri-scheme">
        <name>URI Scheme Registration: agent</name>
        <t>
          Per <xref target="RFC7595"/>, the "agent" URI scheme is
          registered as follows:
        </t>
        <dl>
          <dt>Scheme name</dt><dd>agent</dd>
          <dt>Status</dt><dd>Provisional</dd>
          <dt>Applications/protocols that use this scheme</dt>
          <dd>Agent Internet Protocol (AIP), Agent Invocation Transport Protocol (AITP), Agent Name System (ANS).</dd>
          <dt>Contact</dt><dd>Jinke Song &lt;ink@chatchat.space&gt;</dd>
          <dt>Change controller</dt><dd>Jinke Song &lt;ink@chatchat.space&gt;</dd>
          <dt>Reference</dt><dd>[this document], <xref target="uri-scheme"/></dd>
        </dl>
      </section>

      <section anchor="iana-types">
        <name>AIP Message Type Registry</name>
        <t>
          Registry with 4-bit values (0-15).  Registration policy:
          Specification Required.  Initial values in
          <xref target="tbl-types"/>.
        </t>
      </section>

      <section anchor="iana-protocol">
        <name>AIP Protocol Number Registry</name>
        <t>
          Registry with 8-bit values (0-255).  Registration policy:
          Specification Required for 4-127, First Come First Served for
          128-254.  Value 255 is reserved for experimental use.  Initial
          values in <xref target="tbl-protocol"/>.
        </t>
      </section>

      <section anchor="iana-errors">
        <name>AIP Error Code Registry</name>
        <t>
          Registry with 8-bit values (0-255).  Value 0 reserved
          (<bcp14>MUST NOT</bcp14> use).  Registration policy:
          Specification Required.
          Initial values in <xref target="tbl-errors"/>.
        </t>
      </section>

      <section anchor="iana-flags">
        <name>AIP Flag Bits Registry</name>
        <t>
          Registry with 4 bit positions (0-3).  Registration policy:
          Specification Required.  Initial values in
          <xref target="tbl-flags"/>.
        </t>
      </section>

      <section anchor="iana-options">
        <name>AIP Option Type Registry</name>
        <t>
          Registry with 8-bit values (0-255).  Registration policy:
          Specification Required for 0-127, First Come First Served for
          128-254, value 255 reserved.  Initial values in
          <xref target="tbl-options"/>.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <!--  SECTION 11 — IMPLEMENTATION STATUS                           -->
    <!-- ============================================================ -->

    <section anchor="impl-status">
      <name>Implementation Status</name>

      <t>
        Per <xref target="RFC7942"/>, this section records known
        implementations.
      </t>

      <section anchor="impl-clawnet">
        <name>ClawNet</name>
        <dl>
          <dt>Organization</dt><dd>ChatChatTech</dd>
          <dt>URL</dt>
          <dd><eref target="https://github.com/ChatChatTech/ClawNet"/></dd>
          <dt>Description</dt>
          <dd>
            Go implementation of the full ANP suite.  The AIP module
            (aip/ directory) implements the 16-octet fixed header,
            Protocol field demux, TLV options, local resolver interface,
            Ed25519 signature support, and deduplication cache.  The
            reference implementation is being completed as part of the
            full ClawNet stack conforming to AIP, ANS, AITP, and ADP;
            protocol boundaries are exercised in integration tests
            across the stack.
          </dd>
          <dt>Maturity</dt><dd>Alpha</dd>
          <dt>Coverage</dt>
          <dd>
            <t>Implemented in current prototype:</t>
            <ul>
              <li>16-octet header, Protocol demux, TLV option codec</li>
              <li>Local resolver interface, SEM flag delegation</li>
              <li>Deduplication cache, source URI validation, relay counting</li>
              <li>Message signature support (SIG flag codec)</li>
              <li>Max payload validation (65535)</li>
            </ul>
            <t>Under integration; expected complete before final
            publication candidate:</t>
            <ul>
              <li>Ed25519 signature verification on receive</li>
              <li>Per-peer rate limiting</li>
              <li>Timestamp replay rejection</li>
            </ul>
            <t>The items above affect robustness and enforcement
            behavior; they do not alter the wire format, message
            semantics, or protocol boundaries defined in this
            document.</t>
          </dd>
          <dt>Language</dt><dd>Go</dd>
          <dt>License</dt><dd>Open source</dd>
          <dt>Contact</dt><dd>ink@chatchat.space</dd>
        </dl>
      </section>
    </section>

  </middle>

  <back>

    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

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

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

        <reference anchor="RFC3986" target="https://www.rfc-editor.org/info/rfc3986">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="L. Masinter" initials="L." surname="Masinter"/>
            <date year="2005" month="January"/>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>

        <reference anchor="RFC5234" target="https://www.rfc-editor.org/info/rfc5234">
          <front>
            <title>Augmented BNF for Syntax Specifications: ABNF</title>
            <author fullname="D. Crocker" initials="D." surname="Crocker" role="editor"/>
            <author fullname="P. Overell" initials="P." surname="Overell"/>
            <date year="2008" month="January"/>
          </front>
          <seriesInfo name="STD" value="68"/>
          <seriesInfo name="RFC" value="5234"/>
          <seriesInfo name="DOI" value="10.17487/RFC5234"/>
        </reference>

        <reference anchor="RFC7595" target="https://www.rfc-editor.org/info/rfc7595">
          <front>
            <title>Guidelines and Registration Procedures for URI Schemes</title>
            <author fullname="D. Thaler" initials="D." surname="Thaler" role="editor"/>
            <author fullname="T. Hansen" initials="T." surname="Hansen"/>
            <author fullname="T. Hardie" initials="T." surname="Hardie"/>
            <date year="2015" month="June"/>
          </front>
          <seriesInfo name="BCP" value="35"/>
          <seriesInfo name="RFC" value="7595"/>
          <seriesInfo name="DOI" value="10.17487/RFC7595"/>
        </reference>

      </references>

      <references>
        <name>Informative References</name>

        <reference anchor="RFC0791" target="https://www.rfc-editor.org/info/rfc791">
          <front>
            <title>Internet Protocol</title>
            <author fullname="J. Postel" initials="J." surname="Postel"/>
            <date month="September" year="1981"/>
          </front>
          <seriesInfo name="STD" value="5"/>
          <seriesInfo name="RFC" value="791"/>
          <seriesInfo name="DOI" value="10.17487/RFC0791"/>
        </reference>

        <reference anchor="RFC1035" target="https://www.rfc-editor.org/info/rfc1035">
          <front>
            <title>Domain Names - Implementation and Specification</title>
            <author fullname="P. Mockapetris" initials="P." surname="Mockapetris"/>
            <date year="1987" month="November"/>
          </front>
          <seriesInfo name="STD" value="13"/>
          <seriesInfo name="RFC" value="1035"/>
          <seriesInfo name="DOI" value="10.17487/RFC1035"/>
        </reference>

        <reference anchor="RFC7942" target="https://www.rfc-editor.org/info/rfc7942">
          <front>
            <title>Improving Awareness of Running Code: The Implementation Status Section</title>
            <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
            <author fullname="A. Farrel" initials="A." surname="Farrel"/>
            <date year="2016" month="July"/>
          </front>
          <seriesInfo name="BCP" value="205"/>
          <seriesInfo name="RFC" value="7942"/>
          <seriesInfo name="DOI" value="10.17487/RFC7942"/>
        </reference>

        <reference anchor="I-D.song-anp-aitp">
          <front>
            <title>Agent Invocation Transport Protocol (AITP)</title>
            <author fullname="Jinke Song" initials="J." surname="Song">
              <organization>Department of CSE, HKUST</organization>
            </author>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-song-anp-aitp-00"/>
        </reference>

        <reference anchor="I-D.song-anp-ans">
          <front>
            <title>Agent Name System (ANS)</title>
            <author fullname="Jinke Song" initials="J." surname="Song">
              <organization>Department of CSE, HKUST</organization>
            </author>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-song-anp-ans-00"/>
        </reference>

        <reference anchor="I-D.song-anp-adp">
          <front>
            <title>Agent Description Protocol (ADP)</title>
            <author fullname="Jinke Song" initials="J." surname="Song">
              <organization>Department of CSE, HKUST</organization>
            </author>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-song-anp-adp-00"/>
        </reference>

      </references>
    </references>

    <!-- ============================================================ -->
    <!--  APPENDIX A — WORKED SCORING EXAMPLE                         -->
    <!-- ============================================================ -->

    <section anchor="appendix-scoring" numbered="true">
      <name>Example Resolver Scoring (Informative)</name>

      <t>
        This appendix is entirely informative.  It does not define any
        normative behavior and does not constrain AIP interoperability.
        Implementations are free to use any scoring strategy or none at
        all.
      </t>

      <t>
        This appendix illustrates one possible scoring strategy that a
        semantic resolver could use.  AIP does not mandate any
        particular scoring algorithm; this example is provided for
        implementers' reference.
      </t>

      <t>
        The composite score for each candidate is computed as a weighted
        sum of five components:
      </t>
      <artwork type="ascii-art"><![CDATA[
score = w_text  * S_text      (BM25 text similarity, k1=1.2, b=0.75)
      + w_tag   * S_tag       (Jaccard tag overlap)
      + w_ns    * S_ns        (namespace match)
      + w_fresh * S_fresh     (1 / (1 + age_hours))
      + w_trust * S_trust     (trust score / max_trust)

Example weights: 0.4, 0.3, 0.05, 0.05, 0.2 (sum = 1.0).
]]></artwork>

      <t>Worked example with three resolver entries:</t>

      <table anchor="tbl-example-entries">
        <name>Example Resolver Entries</name>
        <thead>
          <tr><th>#</th><th>URI</th><th>Description</th><th>Skills</th><th>Age</th><th>Trust</th></tr>
        </thead>
        <tbody>
          <tr><td>1</td><td>agent://acme/fr-translator</td><td>French to English translation service</td><td>translation, french, english</td><td>2h</td><td>0.85</td></tr>
          <tr><td>2</td><td>agent://babel/universal</td><td>Universal text translator, 50 languages</td><td>translation, multilingual</td><td>0.5h</td><td>0.92</td></tr>
          <tr><td>3</td><td>agent://research/paper-search</td><td>Academic paper search and retrieval</td><td>research, search</td><td>1h</td><td>0.70</td></tr>
        </tbody>
      </table>

      <t>
        Query: "translate French text", tags: ["translation", "french"],
        max_poi = 0.92.
      </t>

      <artwork type="ascii-art"><![CDATA[
Component scores:

          S_text  S_tag   S_ns  S_fresh          S_trust
Entry 1:  1.000   0.667   0     1/(1+2.0)=0.333  0.85/0.92=0.924
Entry 2:  0.664   0.333   0     1/(1+0.5)=0.667  0.92/0.92=1.000
Entry 3:  0.096   0.000   0     1/(1+1.0)=0.500  0.70/0.92=0.761

Composite (w_text=0.4, w_tag=0.3, w_ns=0.05, w_fresh=0.05, w_trust=0.2):

Entry 1: 0.4*1.000 + 0.3*0.667 + 0.05*0 + 0.05*0.333 + 0.2*0.924
       = 0.400 + 0.200 + 0.000 + 0.017 + 0.185 = 0.802

Entry 2: 0.4*0.664 + 0.3*0.333 + 0.05*0 + 0.05*0.667 + 0.2*1.000
       = 0.266 + 0.100 + 0.000 + 0.033 + 0.200 = 0.599

Entry 3: 0.4*0.096 + 0.3*0.000 + 0.05*0 + 0.05*0.500 + 0.2*0.761
       = 0.038 + 0.000 + 0.000 + 0.025 + 0.152 = 0.215
]]></artwork>

      <t>
        Result: Entry 1 (0.802) > Entry 2 (0.599) > Entry 3 (0.215).
        All above threshold (0.1).
      </t>
    </section>

    <!-- ============================================================ -->
    <!--  APPENDIX B — IMPLEMENTATION ALIGNMENT NOTES                  -->
    <!-- ============================================================ -->

    <section anchor="appendix-bootstrap" numbered="true">
      <name>Network Bootstrap (Informative)</name>

      <t>
        This appendix is entirely informative.  It describes a
        recommended bootstrap sequence for a new agent joining an
        ANP network for the first time.  The steps below depend on
        companion protocols (AITP, ANS, ADP) and link-layer
        infrastructure; they do not alter AIP's wire format or
        processing rules.
      </t>

      <section anchor="bootstrap-overview">
        <name>Bootstrap Sequence</name>
        <ol>
          <li>
            <t><strong>Key Generation.</strong></t>
            <t>
              The agent generates an Ed25519 key pair.  The public
              key derives the node's link-layer Peer ID.  This step
              is entirely local and requires no network interaction.
            </t>
          </li>
          <li>
            <t><strong>Seed Peer Discovery.</strong></t>
            <t>
              The agent obtains the Peer IDs and network addresses
              of one or more seed peers (also called bootstrap
              nodes).  Seed information may come from a compiled-in
              bootstrap list, a DNS SRV record
              (see ANS <xref target="I-D.song-anp-ans"/>,
              Appendix A), a well-known URI, an out-of-band
              configuration file, or manual input.  At least one
              seed peer must be reachable for the remaining steps.
            </t>
          </li>
          <li>
            <t><strong>Link-Layer Connection.</strong></t>
            <t>
              The agent's link-layer module (e.g., libp2p)
              establishes a transport connection to a seed peer
              using the seed's Peer ID and address.  Upon
              connection, mutual peer authentication occurs at the
              link layer (e.g., Noise handshake in libp2p).
            </t>
          </li>
          <li>
            <t><strong>DHT Join.</strong></t>
            <t>
              The agent joins the Kademlia DHT through the seed
              peer, populating its routing table.  After this step,
              the agent can perform DHT get/put operations.
            </t>
          </li>
          <li>
            <t><strong>Name Registration.</strong></t>
            <t>
              The agent constructs an ANS Name Record binding its
              chosen agent:// URI to its Peer ID, signs it, and
              submits it via ans.register (carried over AITP with
              Protocol = 1).  The receiving peer validates the
              signature and stores the record.  The agent also
              publishes the record to the DHT and announces it via
              GossipSub.
            </t>
          </li>
          <li>
            <t><strong>Agent Card Publication.</strong></t>
            <t>
              The agent constructs an ADP Agent Card describing its
              capabilities and publishes it via adp.advertise
              (carried over AITP, Protocol = 1).  The Agent Card
              is also stored in the DHT under the
              /clawnet-profile/ namespace.
            </t>
          </li>
          <li>
            <t><strong>Normal Operation.</strong></t>
            <t>
              The agent's local resolver is now populated with
              at least one cached peer (the seed).  AIP can send
              and receive datagrams.  AITP associations can be
              established with any resolved peer.  The agent is
              fully operational.
            </t>
          </li>
        </ol>
      </section>

      <section anchor="bootstrap-minimal">
        <name>Minimal Bootstrap</name>
        <t>
          Steps 5 and 6 are not required for baseline AIP
          operation.  An agent that only needs to reach peers by
          known agent:// URIs can skip name registration and
          Agent Card publication and rely on DHT resolution
          of other agents' names.
        </t>
        <t>
          Conversely, an agent that cannot reach any seed peer
          cannot join the network.  AIP itself does not solve
          seed discovery; implementations <bcp14>MUST</bcp14>
          provide at least one bootstrap mechanism (compiled-in
          list, DNS, manual configuration) as part of their
          deployment profile.
        </t>
      </section>
    </section>

    <section anchor="appendix-alignment" numbered="true">
      <name>Implementation Alignment Notes</name>

      <t>
        This appendix documents the relationship between this
        specification and the reference implementation in the ClawNet
        aip/ directory.
      </t>

      <table anchor="tbl-alignment">
        <name>Spec-Implementation Mapping</name>
        <thead>
          <tr><th>Spec Concept</th><th>Go Symbol</th><th>Notes</th></tr>
        </thead>
        <tbody>
          <tr><td>Message Type</td><td>aip.MessageType</td><td>TypeData(0), TypeError(1), TypePing(2), TypePong(3).</td></tr>
          <tr><td>Protocol Number</td><td>aip.Protocol</td><td>ProtoNone(0), ProtoAITP(1), ProtoANS(2), ProtoADP(3), ProtoExpt(255).  (Go source still uses ProtoATP as a legacy alias.)</td></tr>
          <tr><td>Flags</td><td>aip.Flags</td><td>FlagRly(0x1), FlagSem(0x2), FlagErr(0x4), FlagSig(0x8).</td></tr>
          <tr><td>Error Code</td><td>aip.ErrorCode</td><td>Full 9-code set.</td></tr>
          <tr><td>Fixed Header</td><td>fixedHeaderSize = 16</td><td>Byte layout per <xref target="fig-header"/>.</td></tr>
          <tr><td>Options</td><td>aip.Option, OptPad1..OptPriority</td><td>TLV encoding with 4-byte alignment.</td></tr>
          <tr><td>Max payload</td><td>aip.MaxPayloadSize = 65535</td><td>Enforced in Marshal() and Unmarshal().</td></tr>
          <tr><td>Local resolver</td><td>aip.LocalResolver (internal)</td><td>Implements the Resolver interface.  BM25 scoring, LRU eviction.  The Go type name is an implementation detail; AIP does not prescribe resolver internals.</td></tr>
          <tr><td>SEM flag resolution</td><td>Module.Send()</td><td>Delegates to resolver's Discover() when FlagSem is set.</td></tr>
          <tr><td>URI parsing</td><td>aip.ParseURI("agent://...")</td><td>Validates agent:// prefix, ident regex.</td></tr>
        </tbody>
      </table>
    </section>

    <!-- ============================================================ -->
    <!--  APPENDIX C — AIP IN ISOLATION EXAMPLE                        -->
    <!-- ============================================================ -->

    <section anchor="appendix-isolation" numbered="true">
      <name>AIP in Isolation (Informative)</name>

      <t>
        This appendix is entirely informative.  It illustrates a
        minimal end-to-end message exchange using only AIP primitives,
        without expanding the internals of any companion protocol.
      </t>

      <t><strong>Scenario:</strong> Agent A wants to send an AITP
        payload to agent://translation/fr-ja.  The local resolver
        already has a cached mapping for that URI.
      </t>

      <ol>
        <li>Agent A calls SEND(source="agent://acme/requester",
            destination="agent://translation/fr-ja", protocol=1,
            payload=..., flags={SIG, RLY, ERR}).</li>
        <li>AIP calls IS_LOCAL("agent://acme/requester") ->
            true.  Source validation passes.</li>
        <li>AIP calls RESOLVE("agent://translation/fr-ja") on the
            local resolver.  The resolver returns (peer_id=0xABCD...,
            ok=true) from its cache.  No distributed lookup is
            needed.</li>
        <li>AIP constructs a DATA message: Version=1, Type=DATA,
            Protocol=AITP(1), TTL=8, Flags=0xD (SIG|ERR|RLY),
            Message ID=42, Payload Length=N.  Source and destination
            URIs are wire-encoded (prefix stripped).</li>
        <li>AIP computes the Ed25519 signature over the header,
            URIs, options, and payload; appends the 64-byte
            signature.</li>
        <li>AIP calls TRANSMIT(peer_id=0xABCD..., serialized_bytes)
            on the link layer.</li>
        <li>At the receiving node, the link layer calls DELIVER.
            AIP parses the header, verifies the signature against
            the public key bound to agent://acme/requester, checks
            deduplication, confirms IS_LOCAL("agent://translation/fr-ja")
            = true, and dispatches the payload to the Protocol=1
            (AITP) handler.</li>
      </ol>

      <t>
        At no point does AIP need to know how the resolver obtained
        its mapping, how AITP will process the payload, or what
        scoring strategy (if any) the resolver uses.  AIP's
        responsibilities are: validate, resolve, construct, sign,
        transmit, and on the receive side: parse, verify, dedup,
        check TTL, deliver or relay.
      </t>
    </section>

  </back>

</rfc>
