diff --git a/CLAUDE.md b/CLAUDE.md index b20cd5f..346c554 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,7 +55,7 @@ language** — README's "What AMAP is not" says this normatively; keep it true. | | | |---|---| -| Document | **`draft-rapp-amap-00`**, dated 2026-10-18; corresponds to contract 3.1.0 (the frozen files' titles) | +| Document | **`draft-rapp-ammp-00`**, "The Agent Mediated Messaging Protocol (AMMP)", dated 2026-10-18; corresponds to contract 3.1.0 (the frozen files' titles). Renamed from AMAP on 2026-10-18; the repository, `draft/draft-amap.xml`, the `amap-*` names and the `AMAP-Peer-*` header fields are not renamed yet | | Wire `contract_version` | **`"2"`** — the draft's Versioning section says why it is not reset to `"1"` | | `README.md` claims | **121 fixtures** — matches the gate | | Actual gate result | **121 fixtures (42 valid, 79 invalid), 0 unexpected**, then **114 signed peer cases and 10 MIME cases, RFC 8032 vectors ok, 0 unexpected** | @@ -84,7 +84,7 @@ The draft's JSON is never hand-copied. `draft/tools/sync_sources.py` `` block, rewriting only that CDATA body and folding per RFC 8792. xml2rfc's own `src=` can't do it: 3.34.1 crashes on non-ASCII UTF-8 in a src file. Gates in `make -C draft`: -- a byte comparison: `dist/draft-rapp-amap-00.xml` must equal the source (never edit `dist/`); +- a byte comparison: `dist/draft-rapp-ammp-00.xml` must equal the source (never edit `dist/`); - `sync_sources.py`: blocks equal disk, and no schema or listed fixture lacks a block; - `check_render.py`: the same, plus roster counts, docName, no host paths; - `check_coverage.py`: every RFC 2119 sentence in the protocol sections @@ -333,7 +333,7 @@ not defects: - **`fixtures/validate.py` and `fixtures/peer-signed/` code comments still cite `spec/contract.md` / `spec/peer-origin.md` section numbers.** They resolve, because the frozen files stay. (The schema descriptions were remapped to the - draft's section names for draft-rapp-amap-00.) + draft's section names for draft-rapp-ammp-00, then named AMAP.) - **CI changes are proposed, not applied.** `.github/workflows/` is read-only from agent sessions, so a workflow change is handed to the operator to apply. - **The `attestation` field name collides with IETF RATS usage** (RFC 9334): diff --git a/CONFORMANCE.md b/CONFORMANCE.md index 2b3fa92..788ad93 100644 --- a/CONFORMANCE.md +++ b/CONFORMANCE.md @@ -5,7 +5,7 @@ specification is mounted read-only in this container at: ``` ~/.amap-spec/ - dist/draft-rapp-amap-00.txt THE NORMATIVE PROSE: the AMAP Internet-Draft, rendered. + dist/draft-rapp-ammp-00.txt THE NORMATIVE PROSE: the AMAP Internet-Draft, rendered. Cite it by section number. schemas/ JSON Schema documents the spec's artifacts must validate against fixtures/ canonical example artifacts, valid and invalid @@ -38,7 +38,7 @@ rather than inventing one. **Read the spec before changing behaviour that the spec governs.** Do not work from memory of what amap "usually" does, and do not infer a rule from other code in this workspace — other code may itself be non-conformant. The draft at -`~/.amap-spec/dist/draft-rapp-amap-00.txt`, with `schemas/` and `fixtures/`, is the +`~/.amap-spec/dist/draft-rapp-ammp-00.txt`, with `schemas/` and `fixtures/`, is the only authority here, for the peer lane as well as the mail lane. **When you touch a spec-governed surface, verify conformance rather than @@ -67,7 +67,7 @@ need different handling, so name which one you believe it is: invented rule as a spec requirement. **A missing mount is not permission to proceed.** If -`~/.amap-spec/dist/draft-rapp-amap-00.txt` is absent, the feature is not installed, +`~/.amap-spec/dist/draft-rapp-ammp-00.txt` is absent, the feature is not installed, the operator's checkout has moved, or this sandbox launched before the `dist` mount existed and needs a relaunch. Say so and stop, rather than falling back to the frozen `spec/contract.md` or `spec/peer-origin.md`, or guessing at the diff --git a/CONSUMERS.md b/CONSUMERS.md index b9f821d..f770ca9 100644 --- a/CONSUMERS.md +++ b/CONSUMERS.md @@ -32,7 +32,7 @@ Maintained by hand, and therefore incomplete — see the honesty note below. | a connector interface document | defines what a connector IS, upstream of any one implementation | **targets v3.1.0 DRAFT** (§5.2); older sections pinned v2.3.0 and are mid-cascade | | a conformance harness | runs the fixture gate against implementations | unknown | -The pins above are dated. The current revision, `draft-rapp-amap-00`, +The pins above are dated. The current revision, `draft-rapp-ammp-00`, corresponds to contract 3.1.0 (wire `contract_version` `"2"`); its body no longer says "DRAFT". It also folds in cross-host statement changes made since those dates (the statement id grammar, point decoding, the size limit and diff --git a/README.md b/README.md index 5c56205..fc0cb61 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ implementation: a trusted mail runtime implements one half, an untrusted per-agent connector implements the other, and the two can be built by different people and versioned independently. -**Current revision: `draft-rapp-amap-00`**, which corresponds to contract +**Current revision: `draft-rapp-ammp-00`**, which corresponds to contract 3.1.0 (wire `contract_version` `"2"` - the contract's own SemVer and the wire major track different things as of 3.0.0; see the draft's Versioning and Conformance section). The draft has not been submitted. @@ -134,14 +134,14 @@ draft/draft-amap.xml the normative prose, as an IETF Internet-Draft - actors, hand-edited, and the source of dist/ schemas/ JSON Schema (2020-12) for each message fixtures/ golden valid + invalid artifacts, and the validator -dist/ the draft rendered: draft-rapp-amap-00.txt to read, .xml to submit +dist/ the draft rendered: draft-rapp-ammp-00.txt to read, .xml to submit spec/contract.md FROZEN - the prose the draft was reconciled against spec/peer-origin.md FROZEN - the peer-origin profile's prose before it moved into the draft ``` The Internet-Draft (`draft/draft-amap.xml`), together with `schemas/` and -`fixtures/`, is the normative contract. Read it as `dist/draft-rapp-amap-00.txt`. +`fixtures/`, is the normative contract. Read it as `dist/draft-rapp-ammp-00.txt`. The JSON the draft shows is written into it from `schemas/` and `fixtures/`, never copied by hand, and the build fails if the two ever differ. diff --git a/SANDY-FEATURE.md b/SANDY-FEATURE.md index 7bf5cdd..fa3d7ee 100644 --- a/SANDY-FEATURE.md +++ b/SANDY-FEATURE.md @@ -77,7 +77,7 @@ Five named mounts rather than one `.` mount of the whole repo. `dist` was added on 2026-09-24, when the Internet-Draft became the canonical prose: without it, every sandbox read a `spec/contract.md` that says it is frozen and points at a file no sandbox could open. `dist/` is mounted rather than `draft/` because the -rendered `draft-rapp-amap-00.txt` is what an agent can read. `draft/` holds the XML +rendered `draft-rapp-ammp-00.txt` is what an agent can read. `draft/` holds the XML source and build tooling, which an agent has no use for. One `.` mount: `.` would also carry `.git` and everything else into every amap sandbox for no benefit, and `.git` cannot be named as a `from` anyway (leading dot is rejected). diff --git a/WORKFLOWS.md b/WORKFLOWS.md index e48f628..047b025 100644 --- a/WORKFLOWS.md +++ b/WORKFLOWS.md @@ -193,7 +193,7 @@ make -C draft # build dist/ and run every gate make -C draft normdiff BASE=origin/main ``` -- The dist copy: `dist/draft-rapp-amap-00.xml` must equal `draft/draft-amap.xml` +- The dist copy: `dist/draft-rapp-ammp-00.xml` must equal `draft/draft-amap.xml` byte for byte. It looks identical to the source and is easy to edit by mistake; an edit there fails the check instead of being silently overwritten. - `tools/sync_sources.py`: every JSON block in the draft equals its file on diff --git a/dist/draft-rapp-amap-00.txt b/dist/draft-rapp-ammp-00.txt similarity index 95% rename from dist/draft-rapp-amap-00.txt rename to dist/draft-rapp-ammp-00.txt index 48b5997..f71230b 100644 --- a/dist/draft-rapp-amap-00.txt +++ b/dist/draft-rapp-ammp-00.txt @@ -8,21 +8,22 @@ Intended status: Standards Track Proofpoint, Inc. Expires: 21 April 2027 18 October 2026 - The Agent Mailbox Access Protocol (AMAP) - draft-rapp-amap-00 + The Agent Mediated Messaging Protocol (AMMP) + draft-rapp-ammp-00 Abstract - The Agent Mailbox Access Protocol (AMAP) is a wire contract, carried - over a filesystem namespace, between an untrusted per-agent connector - and a trusted, credentialed mail runtime. It gives a sandboxed AI - agent the ability to send and receive email through a runtime that - does not trust it: every outbound message begins as an inert request - file that the runtime copies into private staging, validates - independently, and applies policy to before anything is transmitted, - and every inbound message is authenticated and screened by the - runtime before a notice describing it appears in the agent's - namespace. + The Agent Mediated Messaging Protocol (AMMP) is a wire contract, + carried over a filesystem namespace, between an untrusted per-agent + connector and a trusted, credentialed, store-and-forward messaging + runtime. It gives a sandboxed AI agent the ability to send and + receive messages (email, and under an optional profile, messages to + other agents) through a runtime that does not trust it: every + outbound message begins as an inert request file that the runtime + copies into private staging, validates independently, and applies + policy to before anything is transmitted, and every inbound message + is authenticated and screened by the runtime before a notice + describing it appears in the agent's namespace. This document specifies the directory layout and its filesystem obligations — ownership, write and delete rights, and the path, @@ -35,7 +36,7 @@ Abstract specifies how a Runtime signs and verifies that traffic when it travels between hosts as mail. - AMAP is deliberately not a mail protocol: it neither defines nor + AMMP is deliberately not a mail protocol: it neither defines nor replaces SMTP, IMAP, or provider-side infrastructure, and composes with them rather than displacing them. Its single design center is that no security property depends on the agent — or on the connector @@ -52,10 +53,9 @@ Discussion Venues - Rapp & Adams Expires 21 April 2027 [Page 1] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Source for this draft, its schemas, its conformance fixtures and an @@ -111,7 +111,7 @@ Table of Contents Rapp & Adams Expires 21 April 2027 [Page 2] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 3.1. Actors . . . . . . . . . . . . . . . . . . . . . . . . . 13 @@ -167,7 +167,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 3] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.2. Symlinks, descriptors, and open discipline . . . . . . . 81 @@ -223,13 +223,13 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 4] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Appendix K. A Deferred Seam-Visible "Handled" Signal (Non-Normative) . . . . . . . . . . . . . . . . . . . . . 135 Appendix L. Historical Background . . . . . . . . . . . . . . . 137 - L.1. draft-rapp-amap-00 — brought to the IETF (contract + L.1. draft-rapp-ammp-00 — brought to the IETF (contract 3.1.0) . . . . . . . . . . . . . . . . . . . . . . . . . 137 L.2. How the versioning rules came about . . . . . . . . . . . 138 L.3. 3.1.0 — the protocol is AMAP; the outbound extension space; @@ -237,22 +237,23 @@ Internet-Draft AMAP October 2026 L.4. 3.0.0 — direction-aware tolerance, and six closed safety holes . . . . . . . . . . . . . . . . . . . . . . . . . . 143 L.5. 2.3.0 — inbound byte access in force . . . . . . . . . . 145 - L.6. 2.2.0 — deletion rights, read-only inbound . . . . . . . 145 + L.6. 2.2.0 — deletion rights, read-only inbound . . . . . . . 146 L.7. 2.1.0 — the body spool, and three optional Result members . . . . . . . . . . . . . . . . . . . . . . . . . 146 L.8. 2.0.0 — attachments, and contract_version required . . . 146 - L.9. Fixture identifier normalization . . . . . . . . . . . . 146 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 146 + L.9. Fixture identifier normalization . . . . . . . . . . . . 147 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 147 1. Introduction — Motivation and Problem Statement - AI agents increasingly need email. They are tasked over it, they - return results over it, and they correspond over it with people and - with systems that speak no other protocol. An agent is nonetheless - an untrusted process: it can be prompt-injected by the very content - it is asked to read, it can be defective, and it can be compromised - outright. Granting such a process email capability directly is - dangerous along three concrete axes. + AI agents increasingly need to correspond, by email above all. They + are tasked over it, they return results over it, and they correspond + over it with people and with systems that speak no other protocol. + An agent is nonetheless an untrusted process: it can be prompt- + injected by the very content it is asked to read, it can be + defective, and it can be compromised outright. Granting such a + process email capability directly is dangerous along three concrete + axes. *Inbound.* Delivered mail is untrusted content routed directly into the agent's reasoning. A message body, a subject line, a sender @@ -276,10 +277,9 @@ Internet-Draft AMAP October 2026 - Rapp & Adams Expires 21 April 2027 [Page 5] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 1.1. Why the existing options are insufficient @@ -304,20 +304,21 @@ Internet-Draft AMAP October 2026 Adjacent agent protocols do not fill the gap, because they are solving a different problem: integration and interoperation _among credentialed participants_, rather than isolation of an _untrusted_ - one. Section 3.4 positions AMAP against that landscape in detail. + one. Section 3.4 positions AMMP against that landscape in detail. 1.2. The approach - AMAP interposes a *trusted runtime* between the agent and the mail - system. The runtime holds every credential, owns the agent's sending + AMMP interposes a *trusted runtime* between the agent and the systems + that carry its messages, holding each message before forwarding it. + The runtime holds every credential, owns the agent's sending identity, and makes every policy decision. The agent interacts with the runtime only through a channel that carries *no capability*: it writes an inert request file into a directory, and the runtime — independently, on its own schedule, over its own private copy of those bytes — decides what, if anything, happens next. In the other - direction the runtime authenticates and screens mail before writing a - notice describing it into the agent's namespace, and withholds the - bytes of anything it will not vouch for. + direction the runtime authenticates and screens each message before + writing a notice describing it into the agent's namespace, and + withholds the bytes of anything it will not vouch for. The payoff, which the rest of this document formalizes, is the load- bearing invariant: @@ -332,13 +333,12 @@ Internet-Draft AMAP October 2026 - Rapp & Adams Expires 21 April 2027 [Page 6] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 - AMAP is the wire contract at exactly that trust boundary, and is + AMMP is the wire contract at exactly that trust boundary, and is owned by neither side of it. That ownership choice is what allows a runtime and a connector built by different parties, on different schedules, to interoperate and to co-evolve against a versioned @@ -391,17 +391,17 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 7] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 1.5. Non-goals - * *AMAP is not a mail transport.* It neither defines nor replaces + * *AMMP is not a mail transport.* It neither defines nor replaces SMTP, IMAP, or any provider-side mail infrastructure. It describes what a runtime and a connector exchange _locally_; whatever the runtime does with a mail provider is out of scope. - * *AMAP is not agent-to-agent RPC.* The core contract is local to + * *AMMP is not agent-to-agent RPC.* The core contract is local to one deployment's filesystem, between two components on either side of a single trust boundary. The optional peer-origin profile (Section 12) lets Agents of one principal write to one another, @@ -410,7 +410,7 @@ Internet-Draft AMAP October 2026 return semantics, no discovery mechanism, and no transport of its own. - * *AMAP is not a policy language.* What a runtime's policy decides — + * *AMMP is not a policy language.* What a runtime's policy decides — which recipients are permitted, which content is held for review, how a sender's standing is computed — is deliberately out of scope. The wire defines only the shapes of requests and verdicts, @@ -426,7 +426,7 @@ Internet-Draft AMAP October 2026 This section is to be removed before publishing as an RFC. - AMAP began as an implementation: a Runtime and Connectors built + AMMP began as an implementation: a Runtime and Connectors built separately against a shared contract, with an offline conformance suite so that each side could be tested without the other. It has been exercised in deployments of several cooperating Agents from more @@ -447,16 +447,16 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 8] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Collaborators.* The work should be shaped by more than one organization, and by the people who operate mail at scale. - * *Alignment with related work.* AMAP deliberately adds no new + * *Alignment with related work.* AMMP deliberately adds no new transport and no new identity scheme: email stays SMTP, and how an Agent's identity is established is left to work designed for that - purpose. Where AMAP touches such work, it should follow it rather + purpose. Where AMMP touches such work, it should follow it rather than invent its own. Much of this document records why a rule is the way it is, because @@ -503,7 +503,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 9] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 2. Conventions and Terminology @@ -537,11 +537,12 @@ Internet-Draft AMAP October 2026 It does not hold write authority over the peer tree (Section 12.3). - * *Agent* — the untrusted process whose email capability this - protocol mediates. It holds no credential, has no send path of - its own, and reaches the protocol only through its Connector. - Nothing in this document places a requirement on the Agent, - because no security property may depend on it. + * *Agent* — the untrusted process whose messaging capability this + protocol mediates: email, and under the peer-origin profile, + messages to other Agents. It holds no credential, has no send + path of its own, and reaches the protocol only through its + Connector. Nothing in this document places a requirement on the + Agent, because no security property may depend on it. * *Binding Record* — the optional, informational artifact at the Volume root naming which mailbox the Volume is bound to @@ -556,10 +557,9 @@ Internet-Draft AMAP October 2026 - Rapp & Adams Expires 21 April 2027 [Page 10] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Connector* — the per-Agent component that speaks the Agent-side @@ -615,7 +615,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 11] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Origin Class* — the class of origin a consumer assigns to an @@ -635,10 +635,14 @@ Internet-Draft AMAP October 2026 * *Result* — the Runtime-authored verdict for one consumed Submit Request (Section 6). - * *Runtime* — the trusted, credentialed, Agent-agnostic component - that speaks the other half: it holds mail credentials, owns each - Agent's identity, makes every policy decision, and is the only - party that transmits or receives mail. + * *Runtime* — the trusted, credentialed, Agent-agnostic, store-and- + forward messaging component that speaks the other half: it holds + the messaging credentials, owns each Agent's identity, makes every + policy decision, and is the only party that transmits or receives + messages. It holds each message before forwarding it: an outbound + message is copied into private staging and checked before anything + is transmitted, and an inbound message is screened before a Notice + describing it appears. * *Sidecar* — attachment bytes stored beside a Submit Request or a Notice, in a directory named after that artifact, with each blob @@ -665,13 +669,9 @@ Internet-Draft AMAP October 2026 - - - - Rapp & Adams Expires 21 April 2027 [Page 12] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 3. Architecture and Trust Model @@ -681,7 +681,7 @@ Internet-Draft AMAP October 2026 +=============+===============+====================+==============+ | Actor | Trust | Holds | Reaches | +=============+===============+====================+==============+ - | *Runtime* | trusted | mail-send | the mail | + | *Runtime* | trusted | messaging | the mail | | (container) | | credentials, Agent | provider, | | | | identity, policy, | the Volume | | | | the record of what | | @@ -702,7 +702,7 @@ Internet-Draft AMAP October 2026 Table 1 The Runtime is trusted by construction: it is the party holding the - credentials, and a compromise of it is a compromise of the mail + credentials, and a compromise of it is a compromise of the messaging capability itself. The Connector is the interesting case. It runs Agent-side, is reachable by whatever compromises the Agent, and is therefore treated as untrusted for every property that protects the @@ -727,7 +727,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 13] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 No requirement in this document places a Runtime-side, other-Agent- @@ -783,7 +783,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 14] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Isolation is structural rather than enforced by policy.* A Connector @@ -807,10 +807,10 @@ Internet-Draft AMAP October 2026 _This subsection is informative. It contains no requirements and creates no dependency on any external protocol. Nothing here claims - that AMAP replaces, subsumes, or competes with any protocol named + that AMMP replaces, subsumes, or competes with any protocol named below._ - AMAP occupies a narrow position: it is the local seam at a single + AMMP occupies a narrow position: it is the local seam at a single trust boundary, where one side holds every credential and the other holds none. The adjacent protocols in the agent ecosystem sit at different layers, and the common question of "why not use one of them @@ -819,13 +819,13 @@ Internet-Draft AMAP October 2026 *Model Context Protocol (MCP)* [MCP] connects an agent host to tools and context through JSON-RPC servers. It is an integration interface: live capabilities are exposed across it and exercised by - the agent through it. That makes MCP complementary to AMAP rather - than an alternative. A Connector often surfaces AMAP's operations to + the agent through it. That makes MCP complementary to AMMP rather + than an alternative. A Connector often surfaces AMMP's operations to its Agent through MCP, or through whatever tool interface its harness - uses natively; AMAP is the capability-free seam sitting behind that + uses natively; AMMP is the capability-free seam sitting behind that surface. The contrast worth stating is exactly the one that motivates the two coexisting: an MCP-style interface grants live - capability across the boundary it spans, while AMAP's channel + capability across the boundary it spans, while AMMP's channel deliberately grants none — the Agent-side surface can be as rich as the harness likes, because what crosses the trust boundary underneath it is an inert file. The current stable MCP specification revision @@ -839,15 +839,15 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 15] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 credentialed participants that can authenticate to each other. - AMAP's design center is the opposite: an untrusted agent that holds + AMMP's design center is the opposite: an untrusted agent that holds no credentials at all, with enforcement placed entirely on the trusted side of a local boundary. The two are orthogonal, and compose without friction — an agent that speaks A2A to its peers can - use AMAP for its mail capability, and neither protocol needs to know + use AMMP for its mail capability, and neither protocol needs to know about the other. A2A is at v1.0 (v1.0.1, May 2026); it originated at Google and has been hosted as a Linux Foundation project since June 2025. @@ -865,7 +865,7 @@ Internet-Draft AMAP October 2026 currently active protocol at a different layer — an interface between a host or editor and an agent — originated by Zed Industries. It is unrelated to the merged Agent Communication - Protocol and unrelated to AMAP. + Protocol and unrelated to AMMP. The citation facts in this subsection were verified in July 2026. A reviewer preparing this document for publication at a later date is @@ -895,7 +895,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 16] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * accepted only once the provider has accepted the message for relay @@ -951,7 +951,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 17] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 / @@ -1007,7 +1007,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 18] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Isolation is structural.* A Connector scoped to / cannot @@ -1063,7 +1063,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 19] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *(b) No-follow while building the chain.* Each directory component @@ -1119,7 +1119,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 20] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Requirement (c) is needed in both of its branches because an Agent @@ -1175,7 +1175,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 21] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Commit sentinel.* All Sidecar bytes are written — .tmp sibling, then @@ -1231,7 +1231,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 22] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Tree rules.* Every Runtime-owned inbound-class tree is an *origin @@ -1287,7 +1287,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 23] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 underscore, beginning with a letter or digit, so that it names the @@ -1343,7 +1343,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 24] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | | | |deletes here (or | @@ -1399,7 +1399,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 25] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | | |convention,|returns "not | @@ -1455,7 +1455,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 26] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 5. Outbound: Submit Request @@ -1511,7 +1511,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 27] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 5.1. Field semantics and obligations @@ -1567,7 +1567,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 28] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Recipient syntax and header-injection discipline.* Each draft.to @@ -1623,7 +1623,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 29] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 6. Outbound: Result @@ -1679,7 +1679,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 30] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Any policy miss — allowlist, rate limit, DLP hold, halt — MUST @@ -1735,7 +1735,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 31] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *attachments[]* (OPTIONAL) carries one diagnostic entry per @@ -1791,7 +1791,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 32] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 { @@ -1847,7 +1847,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 33] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 1. *Schema failure.* The Notice fails validation against the @@ -1903,7 +1903,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 34] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *contract_version*, *notice_id*, *ts*, *kind*, and *message* are @@ -1959,7 +1959,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 35] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *The untrusted-content posture covers every sender-originated @@ -2015,7 +2015,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 36] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 7.2. Inbound attachment Descriptors @@ -2071,7 +2071,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 37] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *A grant, not a directive.* A consumer MUST tolerate a Descriptor @@ -2127,7 +2127,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 38] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 { @@ -2183,7 +2183,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 39] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 8. Task Correlation @@ -2239,7 +2239,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 40] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 9.1. Field semantics and obligations @@ -2295,7 +2295,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 41] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 { @@ -2351,7 +2351,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 42] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Written whole and atomically.* A Runtime MUST NOT publish a newly @@ -2407,7 +2407,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 43] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 11. The Fleet Roster @@ -2463,7 +2463,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 44] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Readability is split between the parties that can observe it.* A @@ -2519,7 +2519,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 45] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 The tree is named for what it asserts, not for what it is used for: @@ -2575,7 +2575,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 46] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Its own schema.* A Peer Notice is pinned by the peer-notice schema @@ -2631,7 +2631,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 47] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 it (user identities, mount sets, a host boundary) is out of scope; @@ -2687,7 +2687,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 48] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Verification placement (Runtime).* Verification MUST be performed by @@ -2743,7 +2743,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 49] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 (Section 12.6). A Runtime MUST NOT copy it from text the sender @@ -2778,13 +2778,13 @@ Internet-Draft AMAP October 2026 when it accepts the submit. The id MUST be globally unique and unguessable, with at least 128 bits of entropy, and MUST be spelled under the notice_id character set (^[A-Za-z0-9_][A-Za-z0-9_.-]*$). - It has exactly one spelling inside every AMAP document: message.id, + It has exactly one spelling inside every AMMP document: message.id, message.in_reply_to and message.references[] on a Peer Notice, message_id on a peer-routed Result, and the reply key a sender submits all carry the bare id. When the id is carried in a mail header, it is encoded as , where domain is the sending Runtime's authority. The encoding is applied on the way into the - header and removed on the way out, and MUST NOT appear in an AMAP + header and removed on the way out, and MUST NOT appear in an AMMP document. The reverse edge and every ledger depend on two properties of the id: @@ -2799,7 +2799,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 50] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *A reply is a Peer Notice in the reverse direction*, on the same @@ -2855,7 +2855,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 51] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *An unresolved reply key is refused, not stripped.* A reply key @@ -2911,7 +2911,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 52] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 The Runtime is never an allowed peer sender, so this keeps it out of @@ -2967,7 +2967,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 53] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Formats.* ts, sender_since and the timestamps in sender_exposure @@ -3023,7 +3023,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 54] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * The sender MUST fold the field so that no line exceeds 998 octets @@ -3079,7 +3079,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 55] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 whitespace, and MUST NOT otherwise alter it. A field body over @@ -3135,7 +3135,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 56] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 12.6.3. Verification @@ -3191,7 +3191,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 57] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 9. *Body.* The body decodes under the charset rule of @@ -3247,7 +3247,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 58] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | mail, no | No AMAP-Peer-Statement field. | none | @@ -3303,7 +3303,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 59] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * checks 1 to 5(a) passed, so the statement is authenticated by a @@ -3359,7 +3359,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 60] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 or done; and, once decided, the _disposition_: placement, or a @@ -3415,7 +3415,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 61] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 An implementation MUST survive a crash at each of these points: after @@ -3471,7 +3471,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 62] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *With H intact*, the receiver sets floor to one second after @@ -3527,7 +3527,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 63] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Permission.* A resolved reply to a record this Runtime issued is a @@ -3583,7 +3583,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 64] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Rotation.* A receiver MUST support at least two concurrent keys per @@ -3639,7 +3639,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 65] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Form.* A Control Notice is carried in an AMAP-Peer-Control header @@ -3695,7 +3695,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 66] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Failures.* A Control Notice that fails any rule is dropped and @@ -3751,7 +3751,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 67] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 12.6.10. The Intake Location @@ -3807,7 +3807,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 68] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 { @@ -3863,7 +3863,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 69] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 external mail, and MUST NOT make the boolean true. Moving @@ -3919,7 +3919,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 70] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Presentation.* A Connector presenting a peer body MUST meet the @@ -3975,7 +3975,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 71] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 per the conformance classes below, MUST do so for the version-absent @@ -4031,7 +4031,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 72] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * *Consequently:* adding an optional member to a Runtime-authored @@ -4087,7 +4087,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 73] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 meanings, and would defeat the fail-closed rule above exactly where @@ -4143,7 +4143,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 74] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | | | reply_to_message_id}, | @@ -4199,7 +4199,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 75] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | | | (Section 12.5). The | @@ -4255,7 +4255,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 76] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Emission of contract_version on the artifacts that require it is @@ -4311,7 +4311,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 77] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * MUST uphold the filesystem and policy obligations of Sections 4 @@ -4367,7 +4367,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 78] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * MUST tolerate a Binding Record that is absent, and MUST NOT crash @@ -4423,7 +4423,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 79] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * MUST accept every valid peer-* fixture and MUST reject every @@ -4479,7 +4479,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 80] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 arbitrary, and not character-set-safe, and using one as a path @@ -4535,7 +4535,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 81] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 The read side mirrors all of it (Section 4.1): per-component no- @@ -4591,7 +4591,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 82] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.5. Attribution spoofing @@ -4647,7 +4647,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 83] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.7. Recipient policy and header injection @@ -4703,7 +4703,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 84] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 The inbound direction is weaker still and is labelled as such: @@ -4759,7 +4759,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 85] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.11. Fail-closed version handling, and the cost of tolerance @@ -4815,7 +4815,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 86] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.13. Retention, deletion, and lost verdicts @@ -4871,7 +4871,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 87] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * Ingest by copy. @@ -4927,7 +4927,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 88] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 14.16. Special-use domain names @@ -4983,7 +4983,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 89] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 parse to disagree with the first), refuses duplicate JSON member @@ -5039,7 +5039,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 90] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Change controller: to be confirmed with the stream in which this @@ -5095,7 +5095,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 91] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate @@ -5151,7 +5151,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 92] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, @@ -5207,7 +5207,7 @@ Appendix A. Submit-Request Schema Rapp & Adams Expires 21 April 2027 [Page 93] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -5216,7 +5216,7 @@ Internet-Draft AMAP October 2026 "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/submit-request.schema.json", "title": "submit-request", - "description": "agent -> runtime: an inert outbound request. AMAP\ + "description": "agent -> runtime: an inert outbound request. AMMP\ , section \"Outbound: Submit Request\". Agent-authored: this doc\ ument's envelope stays CLOSED (additionalProperties:false) at ev\ ery level per the asymmetry of section \"Versioning\" — an unrec\ @@ -5263,7 +5263,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 94] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "minItems": 1 @@ -5319,7 +5319,7 @@ Appendix B. Result Schema Rapp & Adams Expires 21 April 2027 [Page 95] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -5329,7 +5329,7 @@ Internet-Draft AMAP October 2026 "$id": "https://amap-spec/schemas/result.schema.json", "title": "result", "description": "runtime -> agent: verdict for a submit-request. AM\ - AP, section \"Outbound: Result\". Runtime-authored: this documen\ + MP, section \"Outbound: Result\". Runtime-authored: this documen\ t's envelope is OPEN (no additionalProperties:false) at every le\ vel per the tolerance rule of section \"Versioning\" — a consume\ r MUST ignore members it does not recognize; emitting an unrecog\ @@ -5375,7 +5375,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 96] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 } @@ -5402,7 +5402,7 @@ Appendix C. Deliver-Notice Schema "$id": "https://amap-spec/schemas/deliver-notice.schema.json", "title": "deliver-notice", "description": "runtime -> connector: one notice per delivered mes\ - sage. AMAP, section \"Inbound: Deliver Notice and Inbound Messag\ + sage. AMMP, section \"Inbound: Deliver Notice and Inbound Messag\ e\". Runtime-authored: this document's envelope is OPEN (no addi\ tionalProperties:false) at every level per the tolerance rule o\ f section \"Versioning\" — a consumer MUST ignore members it doe\ @@ -5431,7 +5431,7 @@ Appendix C. Deliver-Notice Schema Rapp & Adams Expires 21 April 2027 [Page 97] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "task_id": { "type": "string", "minLength": 1 }, @@ -5487,7 +5487,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 98] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "allOf": [ @@ -5523,7 +5523,7 @@ Appendix D. Inbound-Message Schema "description": "runtime -> connector: the full delivered message (\ incl. body_text), spooled at inbound/messages/notice-.json, \ keyed on the runtime-minted notice-id (never the provider messag\ - e.id). AMAP, section \"The Inbound Message (body spool)\". Runti\ + e.id). AMMP, section \"The Inbound Message (body spool)\". Runti\ me-authored: this document's envelope is OPEN (no additionalProp\ erties:false) at every level per the tolerance rule of section \\ "Versioning\" — a consumer MUST ignore members it does not recog\ @@ -5543,7 +5543,7 @@ Appendix D. Inbound-Message Schema Rapp & Adams Expires 21 April 2027 [Page 99] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "from": { "type": "string" }, @@ -5599,7 +5599,7 @@ Appendix E. Binding-Record Schema Rapp & Adams Expires 21 April 2027 [Page 100] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -5609,7 +5609,7 @@ Internet-Draft AMAP October 2026 "$id": "https://amap-spec/schemas/binding-record.schema.json", "title": "binding-record", "description": "runtime/provisioner -> volume root: identity.json\ - , the mailbox<->volume binding record. AMAP, section \"Binding R\ + , the mailbox<->volume binding record. AMMP, section \"Binding R\ ecord\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-w\ ritable, so a consumer MUST treat contents as untrusted data an\ d MUST tolerate the file's absence. Unlike the other runtime-aut\ @@ -5648,21 +5648,21 @@ Appendix F. Peer-Origin Profile Schemas "$id": "https://amap-spec/schemas/peer-notice.schema.json", "title": "peer-notice", "description": "runtime -> connector: one notice per peer message \ - placed in /peer/notices/. AMAP, section \"The Peer-Ori\ + placed in /peer/notices/. AMMP, section \"The Peer-Ori\ gin Profile (Optional)\". Same layout as deliver-notice with kin\ Rapp & Adams Expires 21 April 2027 [Page 101] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 d and mailbox pinned to \"peer\", message.from pinned to a bare \ addr-spec (the one runtime-asserted `from` in the protocol), mes\ sage.id / in_reply_to / references pinned to the notice_id chars\ et (the peer message id is bare on the wire; its Message-ID enco\ - ding exists only inside a mail header, never in an AMAP document\ + ding exists only inside a mail header, never in an AMMP document\ ), plus the optional runtime-asserted message.sender_exposure. R\ untime-authored: envelope OPEN at every level per section \"Vers\ ioning\" — a consumer MUST ignore members it does not recognize\ @@ -5691,7 +5691,7 @@ Internet-Draft AMAP October 2026 ult.message_id, >=128 bits of entropy, globally unique and ungue\ ssable. Bare on the wire under the notice_id charset; when carri\ ed in a mail header it is encoded as and decoded aga\ - in before it enters any AMAP document.", + in before it enters any AMMP document.", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*(?!\\n)$" }, "from": { @@ -5711,7 +5711,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 102] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "task_id": { "type": "string", "minLength": 1 }, @@ -5767,7 +5767,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 103] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "window_start": { "type": "string", "minLength": 1 }, @@ -5823,7 +5823,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 104] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Figure 15: schemas/peer-notice.schema.json @@ -5844,7 +5844,7 @@ Internet-Draft AMAP October 2026 "$id": "https://amap-spec/schemas/peer-statement.schema.json", "title": "peer-statement", "description": "runtime -> runtime: the signed statement that carr\ - ies a peer message between hosts. AMAP, section \"Peer Traffic B\ + ies a peer message between hosts. AMMP, section \"Peer Traffic B\ etween Hosts\". The sending runtime signs the statement's exact \ UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Stateme\ nt header field (section \"Carriage, and the Candidate the Verif\ @@ -5879,7 +5879,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 105] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "attachments" @@ -5935,7 +5935,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 106] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "description": "bare addr-spec of the one receiving agent (sec\ @@ -5991,7 +5991,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 107] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "type": "string", @@ -6047,7 +6047,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 108] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:\ @@ -6103,7 +6103,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 109] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 A receiving Runtime reports what it did with a statement it did not @@ -6122,7 +6122,7 @@ Internet-Draft AMAP October 2026 "description": "runtime -> runtime: the signed control notice a re\ ceiving runtime sends to a configured sending runtime about wha\ t it did with an authenticated peer statement that it did not pl\ - ace (refused, dropped, or demoted). AMAP, section \"Control Noti\ + ace (refused, dropped, or demoted). AMMP, section \"Control Noti\ ces\". Carried in an AMAP-Peer-Control header field with the sam\ e k/s/b grammar as AMAP-Peer-Statement, signed with the same per\ -runtime key; `kind` is \"control\", so a control notice never v\ @@ -6159,7 +6159,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 110] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}(?!\\n)$" @@ -6215,7 +6215,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 111] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "enum": [ @@ -6271,7 +6271,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 112] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 ] @@ -6327,7 +6327,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 113] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 ] @@ -6383,7 +6383,7 @@ Appendix G. Peer-Directory Schema Rapp & Adams Expires 21 April 2027 [Page 114] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -6394,7 +6394,7 @@ Internet-Draft AMAP October 2026 "title": "directory", "description": "runtime -> connector: the router's most recent wor\ d about which peers this agent may address, published per instan\ - ce at /directory.json. AMAP, section \"The Peer Direct\ + ce at /directory.json. AMMP, section \"The Peer Direct\ ory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is n\ ot a prediction that a submit to it will be accepted, nor its ab\ sence a prediction of refusal — authorisation is evaluated by th\ @@ -6439,7 +6439,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 115] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "description": "sorted addresses this agent may task — the aut\ @@ -6486,7 +6486,7 @@ Appendix H. Fleet-Roster Schema ime's most recent word about which instances it has admitted, wr\ itten once for the whole fleet to a location the deployment desi\ gnates and exposes read-only to each agent it points at the rost\ - er. AMAP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ + er. AMMP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ SATION: a member's presence says the instance exists, never tha\ t this agent may address it or that a submission to it will be a\ ccepted; authorisation is evaluated by the runtime at submit tim\ @@ -6495,7 +6495,7 @@ Appendix H. Fleet-Roster Schema Rapp & Adams Expires 21 April 2027 [Page 116] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 e and only the result reports what happened. NOT A SOURCE OF TH\ @@ -6551,7 +6551,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 117] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 "type": "object", @@ -6607,7 +6607,7 @@ I.1. Valid Submit Request with attachments Rapp & Adams Expires 21 April 2027 [Page 118] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -6663,7 +6663,7 @@ I.2. Valid Deliver Notice with a clean attachment Descriptor Rapp & Adams Expires 21 April 2027 [Page 119] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 NOTE: '\' line wrapping per RFC 8792 @@ -6719,7 +6719,7 @@ I.3. Valid Inbound Message Rapp & Adams Expires 21 April 2027 [Page 120] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 I.4. Valid Result — a policy hold with per-attachment diagnostics @@ -6775,7 +6775,7 @@ I.5. Invalid Deliver Notice — a content_ref that fails the binding Rapp & Adams Expires 21 April 2027 [Page 121] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 { @@ -6831,7 +6831,7 @@ I.7. Invalid Submit Request carrying an unrecognized member Rapp & Adams Expires 21 April 2027 [Page 122] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 $: additional property 'x_injected' not allowed @@ -6887,7 +6887,7 @@ Appendix J. Conformance Suite Rapp & Adams Expires 21 April 2027 [Page 123] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 +======================================+============================+ @@ -6943,7 +6943,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 124] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | | notice.schema.json | @@ -6999,7 +6999,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 125] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 +--------------------------------------+----------------------------+ @@ -7055,7 +7055,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 126] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | invalid/notice-attachment-ref-index- | deliver- | @@ -7111,7 +7111,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 127] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | invalid/peer-kind-deliver.json | peer- | @@ -7167,7 +7167,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 128] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | invalid/request-subject-crlf.json | submit- | @@ -7223,7 +7223,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 129] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | invalid/control-policy-code-without- | peer- | @@ -7279,7 +7279,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 130] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 | invalid/statement-ts-fractional.json | peer- | @@ -7335,7 +7335,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 131] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 files set retention to its minimum, P, and the cases that probe @@ -7391,7 +7391,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 132] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *A note on pattern anchoring, and a portability cost.* Every schema @@ -7447,7 +7447,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 133] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 * Write ordering and commit-sentinel atomicity — Sidecars before @@ -7503,7 +7503,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 134] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 transport peer candidates, in a location that is neither inbound/ @@ -7559,7 +7559,7 @@ Appendix K. A Deferred Seam-Visible "Handled" Signal (Non-Normative) Rapp & Adams Expires 21 April 2027 [Page 135] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 *Why a Connector-forgeable signal would be acceptable here.* A @@ -7615,7 +7615,7 @@ Internet-Draft AMAP October 2026 Rapp & Adams Expires 21 April 2027 [Page 136] -Internet-Draft AMAP October 2026 +Internet-Draft AMMP October 2026 Today exactly one reference Connector carries a private workaround @@ -7638,7 +7638,7 @@ Appendix L. Historical Background _(Informative.)_ - AMAP was specified and implemented before it was brought to the IETF. + AMMP was specified and implemented before it was brought to the IETF. Its contract was versioned on its own scale, from 1.0.0 to 3.1.0, separately from the wire version that documents carry. This appendix records that history, newest first, because implementations were @@ -7647,7 +7647,7 @@ Appendix L. Historical Background them. An entry that turned out to be wrong is left standing, with a correction attached, rather than quietly rewritten. -L.1. draft-rapp-amap-00 — brought to the IETF (contract 3.1.0) +L.1. draft-rapp-ammp-00 — brought to the IETF (contract 3.1.0) * *One document.* The peer-origin profile's prose, previously a companion document in the repository, is now Section 12. The @@ -7657,6 +7657,35 @@ L.1. draft-rapp-amap-00 — brought to the IETF (contract 3.1.0) The reasoning that explained earlier version changes moved into this appendix (Appendix L.2). + + + + + + + + + + + + +Rapp & Adams Expires 21 April 2027 [Page 137] + +Internet-Draft AMMP October 2026 + + + * *The protocol is AMMP.* It was AMAP, the Agent Mailbox Access + Protocol, and is renamed the Agent Mediated Messaging Protocol + before its first submission: "mailbox access" named only its first + channel, and the contract is a mediation seam for an Agent's + correspondence, mail and peer traffic alike. The abstract and the + definitions of Agent and Runtime describe it that way, as a store- + and-forward messaging runtime; email remains the only transport + this document defines. The acronym AMAP was also already in use + by an expired 2003 individual draft. Nothing on the wire changes: + no document carries the protocol's name, and the header fields of + Section 15.1 keep their names. + * *Editorial review for submission.* Terminology was alphabetized and Drop and Fail Closed became defined terms; requirements previously phrased as "never" are, where they are requirements, @@ -7666,14 +7695,6 @@ L.1. draft-rapp-amap-00 — brought to the IETF (contract 3.1.0) in Section 1.6; and IANA considerations were added for the two header fields the profile defines. - - - -Rapp & Adams Expires 21 April 2027 [Page 137] - -Internet-Draft AMAP October 2026 - - * *The signed statement between hosts*, after reports from the first implementations of revision s5-r4, which now stands as the profile's text, without a revision label (an implementation names @@ -7701,6 +7722,14 @@ L.2. How the versioning rules came about regime, adding a member was not a safe additive change: a strict major-1 validator rejected the *whole document*, not just the new member. Inbound, that was *silent total message loss* — an + + + +Rapp & Adams Expires 21 April 2027 [Page 138] + +Internet-Draft AMMP October 2026 + + attachment-bearing email vanished instead of degrading. Outbound, it was an accidental schema error rather than a designed refusal. And there was no signal to gate on while contract_version stayed "1". @@ -7722,14 +7751,6 @@ L.2. How the versioning rules came about yields a per-Notice drop under check 1 of Section 7.1, a real cost, disclosed, but narrow and legible. Changing the wire major to "3" would instead have forced every major-2 counterpart on both sides to - - - -Rapp & Adams Expires 21 April 2027 [Page 138] - -Internet-Draft AMAP October 2026 - - refuse all traffic, including all the traffic the new tolerance rule protects. Contract 3.1.0 was an additive minor change over 3.0.0, and the wire major stayed "2". @@ -7757,6 +7778,14 @@ Internet-Draft AMAP October 2026 exact against the fixture set. Both statements were false: the content_ref index and prefix binding is not expressible in the schema dialect used here, and a fixture exists that is schema- + + + +Rapp & Adams Expires 21 April 2027 [Page 139] + +Internet-Draft AMMP October 2026 + + valid on its own and must nonetheless be dropped. Section 7.1 states two independent checks, and so does the Connector conformance class. @@ -7777,15 +7806,6 @@ Internet-Draft AMAP October 2026 exploit path, and each is now a requirement (Section 4.1, Section 5.1, Section 8). - - - - -Rapp & Adams Expires 21 April 2027 [Page 139] - -Internet-Draft AMAP October 2026 - - *The peer-origin profile's presentation rule.* A prior revision of the profile said only that a Connector "MAY present peer bodies under the same untrusted-content framing it uses for mail". That was a @@ -7801,6 +7821,27 @@ L.3. 3.1.0 — the protocol is AMAP; the outbound extension space; the An additive *minor* bump; the wire major stays "2". + + + + + + + + + + + + + + + + +Rapp & Adams Expires 21 April 2027 [Page 140] + +Internet-Draft AMMP October 2026 + + * *The signed cross-host peer statement and control notice* (2026-10-09, proposed, not yet reviewed; companion-document section 5 revision s5-r4). Two new schemas (Appendix F): the @@ -7817,7 +7858,7 @@ L.3. 3.1.0 — the protocol is AMAP; the outbound extension space; the valid, 22 invalid) bring version 3.1.0 to 119 (42 valid, 77 invalid). - *Correction (draft-rapp-amap-00).* The statement schema accepted + *Correction (draft-rapp-ammp-00).* The statement schema accepted an id or in_reply_to beginning with "-", which the notice_id character set forbids, so a receiver could verify a statement it could not then publish; one signed case minted such an id. The @@ -7834,14 +7875,6 @@ L.3. 3.1.0 — the protocol is AMAP; the outbound extension space; the which exposes that location. Additive: a new schema and seven fixtures, and nothing existing changes shape. - - - -Rapp & Adams Expires 21 April 2027 [Page 140] - -Internet-Draft AMAP October 2026 - - * *The protocol is AMAP; the schema $id authority is amap-spec* (2026-09-15). The protocol formerly called AMP ("Agent Mailbox Protocol") is renamed AMAP ("Agent Mailbox Access Protocol") @@ -7858,6 +7891,13 @@ Internet-Draft AMAP October 2026 is a companion document (spec/peer-origin.md, itself DRAFT), and its schema and fixtures may still change before it is settled. + + +Rapp & Adams Expires 21 April 2027 [Page 141] + +Internet-Draft AMMP October 2026 + + * *Outbound extension space.* outbound/ext// is defined as a Connector-owned side channel a Runtime MAY read by out-of-band agreement, with no shape specified and nothing security-relevant @@ -7890,14 +7930,6 @@ Internet-Draft AMAP October 2026 rendering a snapshot onto an Agent-writable mount that goes stale whenever the fleet changes. It is advisory and never authoritative, and a Runtime never reads it back as authorisation, - - - -Rapp & Adams Expires 21 April 2027 [Page 141] - -Internet-Draft AMAP October 2026 - - which is what stops it decaying into an allowlist the Agent can see. The Namespace root gains a Runtime-owned posture for Runtime-written files: the file sits beside the lanes rather than @@ -7914,6 +7946,14 @@ Internet-Draft AMAP October 2026 Questions from Runtime implementers reconciling against this document, each answered from the existing text and then stated: a Runtime knows the of every Namespace it serves and + + + +Rapp & Adams Expires 21 April 2027 [Page 142] + +Internet-Draft AMMP October 2026 + + rejects a request from a Namespace it cannot name (Section 4.1); outbound/ext//'s id is a lowercase single path segment (Section 4.1); a Runtime may be built from several trusted @@ -7946,14 +7986,6 @@ Internet-Draft AMAP October 2026 Directory. With them and the fleet roster's seven, version 3.1.0 has 89 fixtures (34 valid, 55 invalid). - - - -Rapp & Adams Expires 21 April 2027 [Page 142] - -Internet-Draft AMAP October 2026 - - L.4. 3.0.0 — direction-aware tolerance, and six closed safety holes A *major document bump*; the wire major stays "2". Section 13.1 @@ -7971,6 +8003,13 @@ L.4. 3.0.0 — direction-aware tolerance, and six closed safety holes authored artifact is now genuinely additive; adding any member to the submit-request is a major change. + + +Rapp & Adams Expires 21 April 2027 [Page 143] + +Internet-Draft AMMP October 2026 + + * *...and for values.* The enum constraint was removed from message.sender_standing and message.provenance, the two explicitly advisory vocabularies, and a consumer must tolerate an @@ -7988,28 +8027,6 @@ L.4. 3.0.0 — direction-aware tolerance, and six closed safety holes in_reply_to, agent_id, and ts — including the two members composed directly into headers, which earlier schema coverage missed. - - - - - - - - - - - - - - - - - -Rapp & Adams Expires 21 April 2027 [Page 143] - -Internet-Draft AMAP October 2026 - - * *Path discipline, write- and read-side both.* The write-side rule became *conjunctive* (Section 4.1), and a new read-side rule applies the equivalent discipline to every Agent-influenceable @@ -8041,6 +8058,14 @@ Internet-Draft AMAP October 2026 nothing, and a stray claim of a second, message-specific Sidecar directory was corrected to match the layout tree. + + + +Rapp & Adams Expires 21 April 2027 [Page 144] + +Internet-Draft AMMP October 2026 + + * *Corrections shipped with this version*, rather than a tidied history: (i) the write rule described in an earlier revision as "strengthened" had in fact been weakened — the exclusive-create @@ -8058,14 +8083,6 @@ Internet-Draft AMAP October 2026 unknown-member notice fixture moved from the invalid set to the valid set and was extended with an unrecognized member inside message; valid unknown-member fixtures were added for result and - - - -Rapp & Adams Expires 21 April 2027 [Page 144] - -Internet-Draft AMAP October 2026 - - inbound-message; the withheld-body invalid fixture was deleted, having become schema-valid under the relaxed envelope (its name always over-claimed what additionalProperties alone tested); the @@ -8098,6 +8115,13 @@ L.5. 2.3.0 — inbound byte access in force shape major 2 already carried. Nothing was tightened, and there is still no outbound content_ref. + + +Rapp & Adams Expires 21 April 2027 [Page 145] + +Internet-Draft AMMP October 2026 + + L.6. 2.2.0 — deletion rights, read-only inbound A *permissive minor bump*: no wire member, no schema change, no @@ -8113,15 +8137,6 @@ L.6. 2.2.0 — deletion rights, read-only inbound on every Result became a keyworded SHOULD, and a consumer must tolerate an unrecognized code and must not infer outcome from it. - - - - -Rapp & Adams Expires 21 April 2027 [Page 145] - -Internet-Draft AMAP October 2026 - - L.7. 2.1.0 — the body spool, and three optional Result members Recorded at the time as an *additive minor bump*: one new optional @@ -8155,6 +8170,14 @@ L.8. 2.0.0 — attachments, and contract_version required version signal, rather than an unknown-member rejection, is what makes that refusal legible. + + + +Rapp & Adams Expires 21 April 2027 [Page 146] + +Internet-Draft AMMP October 2026 + + L.9. Fixture identifier normalization Across these versions the fixture suite's identities were normalized @@ -8171,13 +8194,6 @@ Authors' Addresses Email: drapp@proofpoint.com - - -Rapp & Adams Expires 21 April 2027 [Page 146] - -Internet-Draft AMAP October 2026 - - J. Trent Adams Proofpoint, Inc. Email: tadams@proofpoint.com @@ -8201,22 +8217,6 @@ Internet-Draft AMAP October 2026 - - - - - - - - - - - - - - - - diff --git a/dist/draft-rapp-amap-00.xml b/dist/draft-rapp-ammp-00.xml similarity index 98% rename from dist/draft-rapp-amap-00.xml rename to dist/draft-rapp-ammp-00.xml index 903b7f1..132bc08 100644 --- a/dist/draft-rapp-amap-00.xml +++ b/dist/draft-rapp-ammp-00.xml @@ -8,7 +8,7 @@ - The Agent Mailbox Access Protocol (AMAP) - + The Agent Mediated Messaging Protocol (AMMP) + Proofpoint, Inc.
@@ -33,10 +33,12 @@ -The Agent Mailbox Access Protocol (AMAP) is a wire contract, carried over a +The Agent Mediated Messaging Protocol (AMMP) is a wire contract, carried over a filesystem namespace, between an untrusted per-agent connector and a trusted, -credentialed mail runtime. It gives a sandboxed AI agent the ability to send -and receive email through a runtime that does not trust it: every outbound +credentialed, store-and-forward messaging runtime. It gives a sandboxed AI +agent the ability to send and receive messages (email, and under an optional +profile, messages to other agents) through a runtime that does not trust it: +every outbound message begins as an inert request file that the runtime copies into private staging, validates independently, and applies policy to before anything is transmitted, and every inbound message is authenticated and screened by the @@ -52,7 +54,7 @@ profile gives agent-to-agent traffic within one principal its own tree, and specifies how a Runtime signs and verifies that traffic when it travels between hosts as mail. -AMAP is deliberately not a mail protocol: it neither defines nor replaces +AMMP is deliberately not a mail protocol: it neither defines nor replaces SMTP, IMAP, or provider-side infrastructure, and composes with them rather than displacing them. Its single design center is that no security property depends on the agent — or on the connector speaking for it — behaving @@ -75,7 +77,8 @@ issue tracker can be found at Introduction — Motivation and Problem Statement - AI agents increasingly need email. They are tasked over it, they return + AI agents increasingly need to correspond, by email above all. They are +tasked over it, they return results over it, and they correspond over it with people and with systems that speak no other protocol. An agent is nonetheless an untrusted process: it can be prompt-injected by the very content it is asked to read, it can be @@ -114,18 +117,19 @@ should check. Adjacent agent protocols do not fill the gap, because they are solving a different problem: integration and interoperation among credentialed participants, rather than isolation of an untrusted one. -positions AMAP against that landscape in detail. +positions AMMP against that landscape in detail.
The approach - AMAP interposes a trusted runtime between the agent and the mail system. + AMMP interposes a trusted runtime between the agent and the systems +that carry its messages, holding each message before forwarding it. The runtime holds every credential, owns the agent's sending identity, and makes every policy decision. The agent interacts with the runtime only through a channel that carries no capability: it writes an inert request file into a directory, and the runtime — independently, on its own schedule, over its own private copy of those bytes — decides what, if anything, happens -next. In the other direction the runtime authenticates and screens mail -before writing a notice describing it into the agent's namespace, and +next. In the other direction the runtime authenticates and screens each +message before writing a notice describing it into the agent's namespace, and withholds the bytes of anything it will not vouch for. The payoff, which the rest of this document formalizes, is the load-bearing invariant: @@ -137,7 +141,7 @@ compromised agent or connector can at most write a well-formed request that the runtime then refuses. - AMAP is the wire contract at exactly that trust boundary, and is + AMMP is the wire contract at exactly that trust boundary, and is owned by neither side of it. That ownership choice is what allows a runtime and a connector built by different parties, on different schedules, to interoperate and to co-evolve against a versioned contract with an offline @@ -190,13 +194,13 @@ particular agent harness, language, or tool interface. Non-goals
  • - AMAP is not a mail transport. It neither defines nor replaces SMTP, + AMMP is not a mail transport. It neither defines nor replaces SMTP, IMAP, or any provider-side mail infrastructure. It describes what a runtime and a connector exchange locally; whatever the runtime does with a mail provider is out of scope.
  • - AMAP is not agent-to-agent RPC. The core contract is local to + AMMP is not agent-to-agent RPC. The core contract is local to one deployment's filesystem, between two components on either side of a single trust boundary. The optional peer-origin profile () lets Agents of one principal write to one another, @@ -205,7 +209,7 @@ sending Runtime. The profile defines no call or return semantics, no discovery mechanism, and no transport of its own.
  • - AMAP is not a policy language. What a runtime's policy decides — which + AMMP is not a policy language. What a runtime's policy decides — which recipients are permitted, which content is held for review, how a sender's standing is computed — is deliberately out of scope. The wire defines only the shapes of requests and verdicts, never the computation that produces @@ -219,7 +223,7 @@ wire-verifiable fact, this document says so ().
Why This Work Is Brought to the IETF - AMAP began as an implementation: a Runtime and Connectors built + AMMP began as an implementation: a Runtime and Connectors built separately against a shared contract, with an offline conformance suite so that each side could be tested without the other. It has been exercised in deployments of several cooperating Agents from more than one vendor, but every @@ -241,9 +245,9 @@ implementers and for interoperation testing across organizations. organization, and by the people who operate mail at scale.
  • - Alignment with related work. AMAP deliberately adds no new + Alignment with related work. AMMP deliberately adds no new transport and no new identity scheme: email stays SMTP, and how an Agent's -identity is established is left to work designed for that purpose. Where AMAP +identity is established is left to work designed for that purpose. Where AMMP touches such work, it should follow it rather than invent its own.
  • @@ -325,8 +329,9 @@ peer tree ().
  • - Agent — the untrusted process whose email capability this protocol -mediates. It holds no credential, has no send path of its own, and reaches + Agent — the untrusted process whose messaging capability this +protocol mediates: email, and under the peer-origin profile, messages to other +Agents. It holds no credential, has no send path of its own, and reaches the protocol only through its Connector. Nothing in this document places a requirement on the Agent, because no security property may depend on it.
  • @@ -427,10 +432,13 @@ host ().
  • - Runtime — the trusted, credentialed, Agent-agnostic component that -speaks the other half: it holds mail credentials, owns each Agent's -identity, makes every policy decision, and is the only party that -transmits or receives mail. + Runtime — the trusted, credentialed, Agent-agnostic, +store-and-forward messaging component that speaks the other half: it holds +the messaging credentials, owns each Agent's identity, makes every policy +decision, and is the only party that transmits or receives messages. It holds +each message before forwarding it: an outbound message is copied into private +staging and checked before anything is transmitted, and an inbound message is +screened before a Notice describing it appears.
  • @@ -489,7 +497,7 @@ No implementation may depend on that name or any other. Runtime (container) trusted - mail-send credentials, Agent identity, policy, the record of what was sent + messaging credentials, Agent identity, policy, the record of what was sent the mail provider, the Volume @@ -510,8 +518,8 @@ No implementation may depend on that name or any other. The Runtime is trusted by construction: it is the party holding the -credentials, and a compromise of it is a compromise of the mail capability -itself. The Connector is the interesting case. It runs Agent-side, is +credentials, and a compromise of it is a compromise of the messaging +capability itself. The Connector is the interesting case. It runs Agent-side, is reachable by whatever compromises the Agent, and is therefore treated as untrusted for every property that protects the Runtime, other Agents, or the outside world. Requirements this document places on a Connector fall into @@ -590,9 +598,9 @@ threat.
    Relationship to Other Agent Protocols (Informative) This subsection is informative. It contains no requirements and creates no -dependency on any external protocol. Nothing here claims that AMAP replaces, +dependency on any external protocol. Nothing here claims that AMMP replaces, subsumes, or competes with any protocol named below. - AMAP occupies a narrow position: it is the local seam at a single trust + AMMP occupies a narrow position: it is the local seam at a single trust boundary, where one side holds every credential and the other holds none. The adjacent protocols in the agent ecosystem sit at different layers, and the common question of "why not use one of them here" has a specific answer @@ -600,12 +608,12 @@ in each case. Model Context Protocol (MCP) connects an agent host to tools and context through JSON-RPC servers. It is an integration interface: live capabilities are exposed across it and exercised by the agent through it. -That makes MCP complementary to AMAP rather than an alternative. A Connector -often surfaces AMAP's operations to its Agent through MCP, or through -whatever tool interface its harness uses natively; AMAP is the +That makes MCP complementary to AMMP rather than an alternative. A Connector +often surfaces AMMP's operations to its Agent through MCP, or through +whatever tool interface its harness uses natively; AMMP is the capability-free seam sitting behind that surface. The contrast worth stating is exactly the one that motivates the two coexisting: an MCP-style interface -grants live capability across the boundary it spans, while AMAP's channel +grants live capability across the boundary it spans, while AMMP's channel deliberately grants none — the Agent-side surface can be as rich as the harness likes, because what crosses the trust boundary underneath it is an inert file. The current stable MCP specification revision is 2025-11-25; the @@ -613,11 +621,11 @@ protocol originated at Anthropic. Agent2Agent (A2A) is networked agent-to-agent RPC between mutually authenticated services, with agent cards, tasks, and HTTP/SSE/JSON-RPC transport. It presumes both endpoints are credentialed participants that can -authenticate to each other. AMAP's design center is the opposite: an +authenticate to each other. AMMP's design center is the opposite: an untrusted agent that holds no credentials at all, with enforcement placed entirely on the trusted side of a local boundary. The two are orthogonal, and compose without friction — an agent that speaks A2A to its peers can use -AMAP for its mail capability, and neither protocol needs to know about the +AMMP for its mail capability, and neither protocol needs to know about the other. A2A is at v1.0 (v1.0.1, May 2026); it originated at Google and has been hosted as a Linux Foundation project since June 2025. The two protocols abbreviated "ACP" are not the same protocol, and the @@ -633,7 +641,7 @@ here: it merged into A2A under the Linux Foundation, announced in August The Agent Client Protocol is a distinct and currently active protocol at a different layer — an interface between a host or editor and an agent — originated by Zed Industries. It is unrelated to the -merged Agent Communication Protocol and unrelated to AMAP. +merged Agent Communication Protocol and unrelated to AMMP.
  • The citation facts in this subsection were verified in July 2026. A reviewer @@ -2109,14 +2117,14 @@ addressing. message id when it accepts the submit. The id MUST be globally unique and unguessable, with at least 128 bits of entropy, and MUST be spelled under the notice_id character set (^[A-Za-z0-9_][A-Za-z0-9_.-]*$). -It has exactly one spelling inside every AMAP document: +It has exactly one spelling inside every AMMP document: message.id, message.in_reply_to and message.references[] on a Peer Notice, message_id on a peer-routed Result, and the reply key a sender submits all carry the bare id. When the id is carried in a mail header, it is encoded as <id@domain>, where domain is the sending Runtime's authority. The encoding is applied on the way into the header and removed on -the way out, and MUST NOT appear in an AMAP document. +the way out, and MUST NOT appear in an AMMP document. The reverse edge and every ledger depend on two properties of the id: that it is unguessable, and that it has one spelling end to end. Bare 32-character hexadecimal satisfies both, and so does unpadded base64url @@ -4285,7 +4293,7 @@ NOTE: '\' line wrapping per RFC 8792 "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/submit-request.schema.json", "title": "submit-request", - "description": "agent -> runtime: an inert outbound request. AMAP\ + "description": "agent -> runtime: an inert outbound request. AMMP\ , section \"Outbound: Submit Request\". Agent-authored: this doc\ ument's envelope stays CLOSED (additionalProperties:false) at ev\ ery level per the asymmetry of section \"Versioning\" — an unrec\ @@ -4385,7 +4393,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/result.schema.json", "title": "result", "description": "runtime -> agent: verdict for a submit-request. AM\ - AP, section \"Outbound: Result\". Runtime-authored: this documen\ + MP, section \"Outbound: Result\". Runtime-authored: this documen\ t's envelope is OPEN (no additionalProperties:false) at every le\ vel per the tolerance rule of section \"Versioning\" — a consume\ r MUST ignore members it does not recognize; emitting an unrecog\ @@ -4452,7 +4460,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/deliver-notice.schema.json", "title": "deliver-notice", "description": "runtime -> connector: one notice per delivered mes\ - sage. AMAP, section \"Inbound: Deliver Notice and Inbound Messag\ + sage. AMMP, section \"Inbound: Deliver Notice and Inbound Messag\ e\". Runtime-authored: this document's envelope is OPEN (no addi\ tionalProperties:false) at every level per the tolerance rule o\ f section \"Versioning\" — a consumer MUST ignore members it doe\ @@ -4559,7 +4567,7 @@ NOTE: '\' line wrapping per RFC 8792 "description": "runtime -> connector: the full delivered message (\ incl. body_text), spooled at inbound/messages/notice-.json, \ keyed on the runtime-minted notice-id (never the provider messag\ - e.id). AMAP, section \"The Inbound Message (body spool)\". Runti\ + e.id). AMMP, section \"The Inbound Message (body spool)\". Runti\ me-authored: this document's envelope is OPEN (no additionalProp\ erties:false) at every level per the tolerance rule of section \\ "Versioning\" — a consumer MUST ignore members it does not recog\ @@ -4628,7 +4636,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/binding-record.schema.json", "title": "binding-record", "description": "runtime/provisioner -> volume root: identity.json\ - , the mailbox<->volume binding record. AMAP, section \"Binding R\ + , the mailbox<->volume binding record. AMMP, section \"Binding R\ ecord\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-w\ ritable, so a consumer MUST treat contents as untrusted data an\ d MUST tolerate the file's absence. Unlike the other runtime-aut\ @@ -4670,13 +4678,13 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/peer-notice.schema.json", "title": "peer-notice", "description": "runtime -> connector: one notice per peer message \ - placed in /peer/notices/. AMAP, section \"The Peer-Ori\ + placed in /peer/notices/. AMMP, section \"The Peer-Ori\ gin Profile (Optional)\". Same layout as deliver-notice with kin\ d and mailbox pinned to \"peer\", message.from pinned to a bare \ addr-spec (the one runtime-asserted `from` in the protocol), mes\ sage.id / in_reply_to / references pinned to the notice_id chars\ et (the peer message id is bare on the wire; its Message-ID enco\ - ding exists only inside a mail header, never in an AMAP document\ + ding exists only inside a mail header, never in an AMMP document\ ), plus the optional runtime-asserted message.sender_exposure. R\ untime-authored: envelope OPEN at every level per section \"Vers\ ioning\" — a consumer MUST ignore members it does not recognize\ @@ -4705,7 +4713,7 @@ NOTE: '\' line wrapping per RFC 8792 ult.message_id, >=128 bits of entropy, globally unique and ungue\ ssable. Bare on the wire under the notice_id charset; when carri\ ed in a mail header it is encoded as and decoded aga\ - in before it enters any AMAP document.", + in before it enters any AMMP document.", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*(?!\\n)$" }, "from": { @@ -4835,7 +4843,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/peer-statement.schema.json", "title": "peer-statement", "description": "runtime -> runtime: the signed statement that carr\ - ies a peer message between hosts. AMAP, section \"Peer Traffic B\ + ies a peer message between hosts. AMMP, section \"Peer Traffic B\ etween Hosts\". The sending runtime signs the statement's exact \ UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Stateme\ nt header field (section \"Carriage, and the Candidate the Verif\ @@ -5073,7 +5081,7 @@ NOTE: '\' line wrapping per RFC 8792 "description": "runtime -> runtime: the signed control notice a re\ ceiving runtime sends to a configured sending runtime about wha\ t it did with an authenticated peer statement that it did not pl\ - ace (refused, dropped, or demoted). AMAP, section \"Control Noti\ + ace (refused, dropped, or demoted). AMMP, section \"Control Noti\ ces\". Carried in an AMAP-Peer-Control header field with the sam\ e k/s/b grammar as AMAP-Peer-Statement, signed with the same per\ -runtime key; `kind` is \"control\", so a control notice never v\ @@ -5306,7 +5314,7 @@ NOTE: '\' line wrapping per RFC 8792 "title": "directory", "description": "runtime -> connector: the router's most recent wor\ d about which peers this agent may address, published per instan\ - ce at /directory.json. AMAP, section \"The Peer Direct\ + ce at /directory.json. AMMP, section \"The Peer Direct\ ory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is n\ ot a prediction that a submit to it will be accepted, nor its ab\ sence a prediction of refusal — authorisation is evaluated by th\ @@ -5392,7 +5400,7 @@ NOTE: '\' line wrapping per RFC 8792 ime's most recent word about which instances it has admitted, wr\ itten once for the whole fleet to a location the deployment desi\ gnates and exposes read-only to each agent it points at the rost\ - er. AMAP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ + er. AMMP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ SATION: a member's presence says the instance exists, never tha\ t this agent may address it or that a submission to it will be a\ ccepted; authorisation is evaluated by the runtime at submit tim\ @@ -6710,7 +6718,7 @@ error — recorded here so that it is not rediscovered from scratch.
    Historical Background (Informative.) - AMAP was specified and implemented before it was brought to the IETF. + AMMP was specified and implemented before it was brought to the IETF. Its contract was versioned on its own scale, from 1.0.0 to 3.1.0, separately from the wire version that documents carry. This appendix records that history, newest first, because implementations were built against each @@ -6719,7 +6727,7 @@ clearest as the story of what went wrong without them. An entry that turned out to be wrong is left standing, with a correction attached, rather than quietly rewritten.
    - draft-rapp-amap-00 — brought to the IETF (contract 3.1.0) + draft-rapp-ammp-00 — brought to the IETF (contract 3.1.0)
    • One document. The peer-origin profile's prose, previously a @@ -6729,6 +6737,18 @@ revisions of this document are draft revisions, and the wire version is contract_version (), which stays "2". The reasoning that explained earlier version changes moved into this appendix (). +
    • +
    • + The protocol is AMMP. It was AMAP, the Agent +Mailbox Access Protocol, and is renamed the Agent Mediated Messaging Protocol +before its first submission: "mailbox access" named only its first channel, +and the contract is a mediation seam for an Agent's correspondence, mail and +peer traffic alike. The abstract and the definitions of Agent and Runtime +describe it that way, as a store-and-forward messaging runtime; email remains +the only transport this document defines. The acronym AMAP was also already in use by an expired +2003 individual draft. Nothing on the wire changes: no document carries the +protocol's name, and the header fields of +keep their names.
    • Editorial review for submission. Terminology was @@ -6858,7 +6878,7 @@ reach at each step. The rules are the companion document's (spec/peer-origin section 5). Additive: nothing existing changes shape, and a deployment without cross-host peer traffic is unaffected. The 30 new fixtures (8 valid, 22 invalid) bring version 3.1.0 to 119 (42 valid, 77 invalid). - Correction (draft-rapp-amap-00). The statement schema + Correction (draft-rapp-ammp-00). The statement schema accepted an id or in_reply_to beginning with "-", which the notice_id character set forbids, so a receiver could verify a statement it could not then publish; one signed case minted such an id. The diff --git a/docs/glossary.html b/docs/glossary.html index 0331da9..be765b1 100644 --- a/docs/glossary.html +++ b/docs/glossary.html @@ -26,7 +26,7 @@

      Reference

      Glossary

      -

      The terms used across this site and the AMAP specification. A reference such as "§ Inbound" names a section of the AMAP Internet-Draft (draft-rapp-amap-00), including its optional peer-origin profile, "the profile" for short.

      +

      The terms used across this site and the AMAP specification. A reference such as "§ Inbound" names a section of the AMAP Internet-Draft (draft-rapp-ammp-00), including its optional peer-origin profile, "the profile" for short.

      Agent
      @@ -51,7 +51,7 @@

      Glossary

      On an inbound attachment descriptor, the runtime's access grant to published bytes, in the form <notice_id>.attachments/<index>. It is present only for bytes the runtime asserts clean. A connector must never emit one outbound (§ Submit Request; § Inbound).
      contract_version
      -
      The wire major version carried in every document, currently "2". It is separate from the specification's own SemVer (3.1.0 at draft-rapp-amap-00). Read it before schema validation: a mismatched major is a version refusal and fails closed (§ Versioning and Conformance).
      +
      The wire major version carried in every document, currently "2". It is separate from the specification's own SemVer (3.1.0 at draft-rapp-ammp-00). Read it before schema validation: a mismatched major is a version refusal and fails closed (§ Versioning and Conformance).
      Deliver-notice
      The runtime's pointer-plus-summary for one delivered mail message, at inbound/notices/notice-<id>.json, with kind: "deliver" (§ Inbound).
      diff --git a/docs/implementers.html b/docs/implementers.html index 980650a..d4b24d8 100644 --- a/docs/implementers.html +++ b/docs/implementers.html @@ -29,7 +29,7 @@

      The AMAP specification, at the wire level

      AMAP defines a wire contract between a trusted runtime, which holds the mail credentials and applies policy, and an agent-side connector, which holds nothing credentialed. The two sides share one thing: a per-agent filesystem namespace. This page summarises what each side must do. The authority is the specification itself.

      -

      Source of truth. The AMAP Internet-Draft (draft-rapp-amap-00; its source is draft/draft-amap.xml), the schemas and the fixtures are the normative specification. The peer-origin profile is a section of the Internet-Draft, § The Peer-Origin Profile (Optional). Where this page and the specification disagree, the specification wins. A reference such as "§ Inbound" names a section of the Internet-Draft. The older spec/contract.md and spec/peer-origin.md are frozen history, not the specification.

      +

      Source of truth. The AMAP Internet-Draft (draft-rapp-ammp-00; its source is draft/draft-amap.xml), the schemas and the fixtures are the normative specification. The peer-origin profile is a section of the Internet-Draft, § The Peer-Origin Profile (Optional). Where this page and the specification disagree, the specification wins. A reference such as "§ Inbound" names a section of the Internet-Draft. The older spec/contract.md and spec/peer-origin.md are frozen history, not the specification.

      Three actors, one invariant

      @@ -164,7 +164,7 @@

      Enforcement by absence

      Versioning

      Two axes, not one:

        -
      • The specification's own version (3.1.0 at draft-rapp-amap-00) is SemVer for the document. The Internet-Draft's own revisions (-00, -01, …) are a third sequence, and its body does not carry the SemVer. Additive changes are MINOR, and a change that breaks an existing fixture is MAJOR.
      • +
      • The specification's own version (3.1.0 at draft-rapp-ammp-00) is SemVer for the document. The Internet-Draft's own revisions (-00, -01, …) are a third sequence, and its body does not carry the SemVer. Additive changes are MINOR, and a change that breaks an existing fixture is MAJOR.
      • The wire contract_version (currently "2") is what goes in every document and what a consumer checks.

      Read contract_version before any schema validation, comparing majors as non-negative integers (§ Versioning and Conformance). An absent, lower or higher major is a version refusal that fails closed. It is a distinct, logged outcome, never folded into the malformed-document path. The refusal is asymmetric:

      diff --git a/docs/schemas/binding-record.schema.json b/docs/schemas/binding-record.schema.json index 8a3360b..38e777b 100644 --- a/docs/schemas/binding-record.schema.json +++ b/docs/schemas/binding-record.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/binding-record.schema.json", "title": "binding-record", - "description": "runtime/provisioner -> volume root: identity.json, the mailbox<->volume binding record. AMAP, section \"Binding Record\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-writable, so a consumer MUST treat contents as untrusted data and MUST tolerate the file's absence. Unlike the other runtime-authored documents, this schema is closed (section \"Versioning\") — its closure is an anti-secret-leak lint, not a compatibility surface.", + "description": "runtime/provisioner -> volume root: identity.json, the mailbox<->volume binding record. AMMP, section \"Binding Record\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-writable, so a consumer MUST treat contents as untrusted data and MUST tolerate the file's absence. Unlike the other runtime-authored documents, this schema is closed (section \"Versioning\") — its closure is an anti-secret-leak lint, not a compatibility surface.", "type": "object", "required": ["agent_id", "address", "provisioned_ts"], "additionalProperties": false, diff --git a/docs/schemas/deliver-notice.schema.json b/docs/schemas/deliver-notice.schema.json index 458c0aa..54eaa02 100644 --- a/docs/schemas/deliver-notice.schema.json +++ b/docs/schemas/deliver-notice.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/deliver-notice.schema.json", "title": "deliver-notice", - "description": "runtime -> connector: one notice per delivered message. AMAP, section \"Inbound: Deliver Notice and Inbound Message\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: one notice per delivered message. AMMP, section \"Inbound: Deliver Notice and Inbound Message\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "notice_id", "ts", "kind", "message"], "properties": { diff --git a/docs/schemas/directory.schema.json b/docs/schemas/directory.schema.json index c62b09d..72d215f 100644 --- a/docs/schemas/directory.schema.json +++ b/docs/schemas/directory.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/directory.schema.json", "title": "directory", - "description": "runtime -> connector: the router's most recent word about which peers this agent may address, published per instance at /directory.json. AMAP, section \"The Peer Directory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is not a prediction that a submit to it will be accepted, nor its absence a prediction of refusal — authorisation is evaluated by the runtime at submit time and only the result (section \"Outbound: Result\") reports what happened. A runtime MUST NOT read this file back as authorisation; enforcement stays the runtime's own graph check on every message. The file MAY be absent. Runtime-authored: envelope is OPEN at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: the router's most recent word about which peers this agent may address, published per instance at /directory.json. AMMP, section \"The Peer Directory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is not a prediction that a submit to it will be accepted, nor its absence a prediction of refusal — authorisation is evaluated by the runtime at submit time and only the result (section \"Outbound: Result\") reports what happened. A runtime MUST NOT read this file back as authorisation; enforcement stays the runtime's own graph check on every message. The file MAY be absent. Runtime-authored: envelope is OPEN at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": [ "router", diff --git a/docs/schemas/inbound-message.schema.json b/docs/schemas/inbound-message.schema.json index 5dfd021..43fd1ea 100644 --- a/docs/schemas/inbound-message.schema.json +++ b/docs/schemas/inbound-message.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/inbound-message.schema.json", "title": "inbound-message", - "description": "runtime -> connector: the full delivered message (incl. body_text), spooled at inbound/messages/notice-.json, keyed on the runtime-minted notice-id (never the provider message.id). AMAP, section \"The Inbound Message (body spool)\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: the full delivered message (incl. body_text), spooled at inbound/messages/notice-.json, keyed on the runtime-minted notice-id (never the provider message.id). AMMP, section \"The Inbound Message (body spool)\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "notice_id", "body_text"], "properties": { diff --git a/docs/schemas/peer-control.schema.json b/docs/schemas/peer-control.schema.json index cc40b7b..5e63376 100644 --- a/docs/schemas/peer-control.schema.json +++ b/docs/schemas/peer-control.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-control.schema.json", "title": "peer-control", - "description": "runtime -> runtime: the signed control notice a receiving runtime sends to a configured sending runtime about what it did with an authenticated peer statement that it did not place (refused, dropped, or demoted). AMAP, section \"Control Notices\". Carried in an AMAP-Peer-Control header field with the same k/s/b grammar as AMAP-Peer-Statement, signed with the same per-runtime key; `kind` is \"control\", so a control notice never validates as a peer statement and is never placed for an agent. CLOSED at every level, and it carries no free text: the receiving runtime composes any agent-facing words itself (the delivery failure notice of section \"Correlation and Replies\"). The schema cannot check that `about` names a peer message this runtime issued to the notice's signer; that is the receiving runtime's check (section \"Control Notices\").", + "description": "runtime -> runtime: the signed control notice a receiving runtime sends to a configured sending runtime about what it did with an authenticated peer statement that it did not place (refused, dropped, or demoted). AMMP, section \"Control Notices\". Carried in an AMAP-Peer-Control header field with the same k/s/b grammar as AMAP-Peer-Statement, signed with the same per-runtime key; `kind` is \"control\", so a control notice never validates as a peer statement and is never placed for an agent. CLOSED at every level, and it carries no free text: the receiving runtime composes any agent-facing words itself (the delivery failure notice of section \"Correlation and Replies\"). The schema cannot check that `about` names a peer message this runtime issued to the notice's signer; that is the receiving runtime's check (section \"Control Notices\").", "type": "object", "additionalProperties": false, "required": [ diff --git a/docs/schemas/peer-notice.schema.json b/docs/schemas/peer-notice.schema.json index a98b0da..499ab7f 100644 --- a/docs/schemas/peer-notice.schema.json +++ b/docs/schemas/peer-notice.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-notice.schema.json", "title": "peer-notice", - "description": "runtime -> connector: one notice per peer message placed in /peer/notices/. AMAP, section \"The Peer-Origin Profile (Optional)\". Same layout as deliver-notice with kind and mailbox pinned to \"peer\", message.from pinned to a bare addr-spec (the one runtime-asserted `from` in the protocol), message.id / in_reply_to / references pinned to the notice_id charset (the peer message id is bare on the wire; its Message-ID encoding exists only inside a mail header, never in an AMAP document), plus the optional runtime-asserted message.sender_exposure. Runtime-authored: envelope OPEN at every level per section \"Versioning\" — a consumer MUST ignore members it does not recognize. A document with kind \"peer\" found under inbound/notices/ fails deliver-notice.schema.json; a document with kind \"deliver\" found under peer/notices/ fails this schema: both are dropped under the drop rule of section \"Field semantics and obligations\" (the profile's cross-lock, section \"The Peer Tree\").", + "description": "runtime -> connector: one notice per peer message placed in /peer/notices/. AMMP, section \"The Peer-Origin Profile (Optional)\". Same layout as deliver-notice with kind and mailbox pinned to \"peer\", message.from pinned to a bare addr-spec (the one runtime-asserted `from` in the protocol), message.id / in_reply_to / references pinned to the notice_id charset (the peer message id is bare on the wire; its Message-ID encoding exists only inside a mail header, never in an AMMP document), plus the optional runtime-asserted message.sender_exposure. Runtime-authored: envelope OPEN at every level per section \"Versioning\" — a consumer MUST ignore members it does not recognize. A document with kind \"peer\" found under inbound/notices/ fails deliver-notice.schema.json; a document with kind \"deliver\" found under peer/notices/ fails this schema: both are dropped under the drop rule of section \"Field semantics and obligations\" (the profile's cross-lock, section \"The Peer Tree\").", "type": "object", "required": ["contract_version", "notice_id", "ts", "kind", "message"], "properties": { @@ -16,7 +16,7 @@ "properties": { "id": { "type": "string", "minLength": 1, - "description": "the peer message id: minted by the sending runtime on accepting the submit, returned to the sender as result.message_id, >=128 bits of entropy, globally unique and unguessable. Bare on the wire under the notice_id charset; when carried in a mail header it is encoded as and decoded again before it enters any AMAP document.", + "description": "the peer message id: minted by the sending runtime on accepting the submit, returned to the sender as result.message_id, >=128 bits of entropy, globally unique and unguessable. Bare on the wire under the notice_id charset; when carried in a mail header it is encoded as and decoded again before it enters any AMMP document.", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*(?!\\n)$" }, "from": { diff --git a/docs/schemas/peer-statement.schema.json b/docs/schemas/peer-statement.schema.json index 93eafa0..d86731e 100644 --- a/docs/schemas/peer-statement.schema.json +++ b/docs/schemas/peer-statement.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-statement.schema.json", "title": "peer-statement", - "description": "runtime -> runtime: the signed statement that carries a peer message between hosts. AMAP, section \"Peer Traffic Between Hosts\". The sending runtime signs the statement's exact UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Statement header field (section \"Carriage, and the Candidate the Verifier Sees\"); the receiving runtime verifies the signature over the received bytes before parsing, then validates against this schema. CLOSED at every level, unlike the runtime-authored notices: these are signed bytes another runtime acts on, a member the receiver does not know is a member it cannot bind to what it publishes, and the version member `v` is the only evolution path. A statement that fails this schema fails verification, and the message is demoted to mail (sections \"Verification\" and \"Outcomes\"). Numbers are lexical integers (no fraction or exponent) and strings contain no unpaired surrogate (section \"The Statement\", checked at check 5(b) of section \"Verification\"); the schema cannot express either, nor calendar validity, interval order, the entropy of `id`, or any binding to the message: those are the verification steps of section \"Verification\".", + "description": "runtime -> runtime: the signed statement that carries a peer message between hosts. AMMP, section \"Peer Traffic Between Hosts\". The sending runtime signs the statement's exact UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Statement header field (section \"Carriage, and the Candidate the Verifier Sees\"); the receiving runtime verifies the signature over the received bytes before parsing, then validates against this schema. CLOSED at every level, unlike the runtime-authored notices: these are signed bytes another runtime acts on, a member the receiver does not know is a member it cannot bind to what it publishes, and the version member `v` is the only evolution path. A statement that fails this schema fails verification, and the message is demoted to mail (sections \"Verification\" and \"Outcomes\"). Numbers are lexical integers (no fraction or exponent) and strings contain no unpaired surrogate (section \"The Statement\", checked at check 5(b) of section \"Verification\"); the schema cannot express either, nor calendar validity, interval order, the entropy of `id`, or any binding to the message: those are the verification steps of section \"Verification\".", "type": "object", "additionalProperties": false, "required": [ diff --git a/docs/schemas/result.schema.json b/docs/schemas/result.schema.json index 3399ce4..d830a97 100644 --- a/docs/schemas/result.schema.json +++ b/docs/schemas/result.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/result.schema.json", "title": "result", - "description": "runtime -> agent: verdict for a submit-request. AMAP, section \"Outbound: Result\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> agent: verdict for a submit-request. AMMP, section \"Outbound: Result\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "req_id", "outcome"], "properties": { diff --git a/docs/schemas/roster.schema.json b/docs/schemas/roster.schema.json index a73e5dc..1ba1fdf 100644 --- a/docs/schemas/roster.schema.json +++ b/docs/schemas/roster.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/roster.schema.json", "title": "roster", - "description": "runtime -> every agent: the fleet roster, the runtime's most recent word about which instances it has admitted, written once for the whole fleet to a location the deployment designates and exposes read-only to each agent it points at the roster. AMAP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORISATION: a member's presence says the instance exists, never that this agent may address it or that a submission to it will be accepted; authorisation is evaluated by the runtime at submit time and only the result reports what happened. NOT A SOURCE OF THE READER'S IDENTITY: the reader's own address may appear, and attribution stays the namespace a file arrived in. A runtime MUST NOT read this file back. The file MAY be absent; absent or stale means unknown, never an empty fleet. Runtime-authored: envelope is OPEN at every level — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> every agent: the fleet roster, the runtime's most recent word about which instances it has admitted, written once for the whole fleet to a location the deployment designates and exposes read-only to each agent it points at the roster. AMMP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORISATION: a member's presence says the instance exists, never that this agent may address it or that a submission to it will be accepted; authorisation is evaluated by the runtime at submit time and only the result reports what happened. NOT A SOURCE OF THE READER'S IDENTITY: the reader's own address may appear, and attribution stays the namespace a file arrived in. A runtime MUST NOT read this file back. The file MAY be absent; absent or stale means unknown, never an empty fleet. Runtime-authored: envelope is OPEN at every level — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": [ "contract_version", diff --git a/docs/schemas/submit-request.schema.json b/docs/schemas/submit-request.schema.json index d28a10c..70d43c1 100644 --- a/docs/schemas/submit-request.schema.json +++ b/docs/schemas/submit-request.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/submit-request.schema.json", "title": "submit-request", - "description": "agent -> runtime: an inert outbound request. AMAP, section \"Outbound: Submit Request\". Agent-authored: this document's envelope stays CLOSED (additionalProperties:false) at every level per the asymmetry of section \"Versioning\" — an unrecognized member here is a designed, legible `rejected` refusal, never a silent drop.", + "description": "agent -> runtime: an inert outbound request. AMMP, section \"Outbound: Submit Request\". Agent-authored: this document's envelope stays CLOSED (additionalProperties:false) at every level per the asymmetry of section \"Versioning\" — an unrecognized member here is a designed, legible `rejected` refusal, never a silent drop.", "type": "object", "required": ["contract_version", "req_id", "draft"], "additionalProperties": false, diff --git a/docs/status.html b/docs/status.html index 50296d1..f7512af 100644 --- a/docs/status.html +++ b/docs/status.html @@ -4,7 +4,7 @@ Status · AMAP - + diff --git a/draft/Makefile b/draft/Makefile index a383286..10ea27b 100644 --- a/draft/Makefile +++ b/draft/Makefile @@ -14,7 +14,7 @@ # artifact, never the mechanism. REPO := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..) -NAME := draft-rapp-amap-00 +NAME := draft-rapp-ammp-00 SRC := $(REPO)/draft/draft-amap.xml OUT := $(REPO)/dist/$(NAME) diff --git a/draft/README.md b/draft/README.md index 5d6974b..789608a 100644 --- a/draft/README.md +++ b/draft/README.md @@ -30,8 +30,8 @@ its revisions are draft revisions, and `-00` corresponds to contract 3.1.0. The wire `contract_version` is still `"2"`. The version history is the "Historical Background" appendix, which is removed before RFC publication. -The build renders `dist/draft-rapp-amap-00.xml` (a byte copy of the source) and -`dist/draft-rapp-amap-00.txt`, and on demand `.html` and `.pdf`. +The build renders `dist/draft-rapp-ammp-00.xml` (a byte copy of the source) and +`dist/draft-rapp-ammp-00.txt`, and on demand `.html` and `.pdf`. ## 2. What a tool writes, and what you write @@ -55,7 +55,7 @@ folding long lines per RFC 8792 exactly as the old kramdown-rfc build did empty `` and run `make sync`. `make check` fails if a schema or listed fixture has no block. - **Never paste JSON into the XML by hand.** The check fails on any difference. -- **Never edit `dist/draft-rapp-amap-00.xml`.** It is a byte copy of the source and +- **Never edit `dist/draft-rapp-ammp-00.xml`.** It is a byte copy of the source and looks identical to it. A direct edit there is not lost silently: `make` leaves the edited copy alone and `make check` fails on the mismatch. Move the edit into `draft/draft-amap.xml`. @@ -120,7 +120,7 @@ no longer needed. ## 5. What is committed, and what is not -- **Committed:** `draft-amap.xml` (the source), `dist/draft-rapp-amap-00.xml` (its +- **Committed:** `draft-amap.xml` (the source), `dist/draft-rapp-ammp-00.xml` (its copy) and `.txt`, `coverage.toml`, `fixtures.toml`, `examples/`, `bib/`. - **Gitignored:** `dist/*.html` and `dist/*.pdf`. - **Never written by the build:** `schemas/`, `fixtures/`, `spec/`. @@ -163,10 +163,13 @@ to matter here. It is being put to counsel. Settled: - **Author affiliation is included** (`Proofpoint, Inc.`), per the approval. -- **The draft name** is `draft-rapp-amap-00` (the editor, 2026-09-27: the - IETF convention for an individual submission, `draft--`). - Confirm it against datatracker before submission — the last rename happened - because the old acronym collided with an adopted working-group draft. +- **The draft name** is `draft-rapp-ammp-00`, the Agent Mediated Messaging + Protocol (renamed from AMAP, the Agent Mailbox Access Protocol, on + 2026-10-18, before first submission; the `draft--` form is the + editor's, 2026-09-27). Confirm it against datatracker before submission — + both earlier names collided with existing work. The repository, the source + file `draft-amap.xml`, and the `AMAP-Peer-*` header fields keep their names + for now. - **The date is pinned literally** (not derived from git) and must be bumped by hand when the content changes meaningfully — an Internet-Draft's date is a meaningful, deliberate signal, not a build artifact. diff --git a/draft/coverage.toml b/draft/coverage.toml index 350d297..ba3b779 100644 --- a/draft/coverage.toml +++ b/draft/coverage.toml @@ -7,7 +7,7 @@ # The entries marked `baseline = true` are the migration baseline: the 128 # sentences present when the draft XML became the canonical source # (2026-09-24), recorded but not yet reasoned about (115 remain at -# draft-rapp-amap-00, where every sentence the revision reworded was given its +# draft-rapp-ammp-00, where every sentence the revision reworded was given its # real class). Classify them — fixture, # operational or informative — as they are reviewed; that is how this file # earns its keep. Never add an unclassified entry: a new sentence gets its real @@ -920,7 +920,7 @@ text = "(the artifact itself is OPTIONAL — ); if present: router, written_at, id = "fb781db6c125" section = "sec-4-1" class = "operational" -note = "Where a Runtime gets each Namespace's name is configuration and layout, invisible to a document validator. Check: start the Runtime without a name source and confirm it refuses to start or rejects requests. Reworded for draft-rapp-amap-00 (never -> MUST NOT)." +note = "Where a Runtime gets each Namespace's name is configuration and layout, invisible to a document validator. Check: start the Runtime without a name source and confirm it refuses to start or rejects requests. Reworded for draft-rapp-ammp-00 (never -> MUST NOT)." text = "A Runtime MUST know the of every Namespace it serves: from its own configuration or, where its own layout carries it, from the Namespace's path, and MUST NOT take it from anything the Agent writes." [[sentence]] @@ -1267,11 +1267,11 @@ fixtures = ["valid/peer-minimal.json", "invalid/peer-message-id-encoded.json", " text = "The id MUST be globally unique and unguessable, with at least 128 bits of entropy, and MUST be spelled under the notice_id character set (^[A-Za-z0-9_][A-Za-z0-9_.-]*$)." [[sentence]] -id = "21bfd12f36d4" +id = "25a8d1957b9b" section = "sec-peer-corr" class = "fixture" fixtures = ["invalid/peer-message-id-encoded.json", "invalid/peer-in-reply-to-encoded.json", "invalid/statement-id-encoded.json"] -text = "The encoding is applied on the way into the header and removed on the way out, and MUST NOT appear in an AMAP document." +text = "The encoding is applied on the way into the header and removed on the way out, and MUST NOT appear in an AMMP document." [[sentence]] id = "ea52517b0191" diff --git a/draft/draft-amap.xml b/draft/draft-amap.xml index 903b7f1..132bc08 100644 --- a/draft/draft-amap.xml +++ b/draft/draft-amap.xml @@ -8,7 +8,7 @@ - The Agent Mailbox Access Protocol (AMAP) - + The Agent Mediated Messaging Protocol (AMMP) + Proofpoint, Inc.
      @@ -33,10 +33,12 @@ -The Agent Mailbox Access Protocol (AMAP) is a wire contract, carried over a +The Agent Mediated Messaging Protocol (AMMP) is a wire contract, carried over a filesystem namespace, between an untrusted per-agent connector and a trusted, -credentialed mail runtime. It gives a sandboxed AI agent the ability to send -and receive email through a runtime that does not trust it: every outbound +credentialed, store-and-forward messaging runtime. It gives a sandboxed AI +agent the ability to send and receive messages (email, and under an optional +profile, messages to other agents) through a runtime that does not trust it: +every outbound message begins as an inert request file that the runtime copies into private staging, validates independently, and applies policy to before anything is transmitted, and every inbound message is authenticated and screened by the @@ -52,7 +54,7 @@ profile gives agent-to-agent traffic within one principal its own tree, and specifies how a Runtime signs and verifies that traffic when it travels between hosts as mail. -AMAP is deliberately not a mail protocol: it neither defines nor replaces +AMMP is deliberately not a mail protocol: it neither defines nor replaces SMTP, IMAP, or provider-side infrastructure, and composes with them rather than displacing them. Its single design center is that no security property depends on the agent — or on the connector speaking for it — behaving @@ -75,7 +77,8 @@ issue tracker can be found at Introduction — Motivation and Problem Statement - AI agents increasingly need email. They are tasked over it, they return + AI agents increasingly need to correspond, by email above all. They are +tasked over it, they return results over it, and they correspond over it with people and with systems that speak no other protocol. An agent is nonetheless an untrusted process: it can be prompt-injected by the very content it is asked to read, it can be @@ -114,18 +117,19 @@ should check. Adjacent agent protocols do not fill the gap, because they are solving a different problem: integration and interoperation among credentialed participants, rather than isolation of an untrusted one. -positions AMAP against that landscape in detail. +positions AMMP against that landscape in detail.
    The approach - AMAP interposes a trusted runtime between the agent and the mail system. + AMMP interposes a trusted runtime between the agent and the systems +that carry its messages, holding each message before forwarding it. The runtime holds every credential, owns the agent's sending identity, and makes every policy decision. The agent interacts with the runtime only through a channel that carries no capability: it writes an inert request file into a directory, and the runtime — independently, on its own schedule, over its own private copy of those bytes — decides what, if anything, happens -next. In the other direction the runtime authenticates and screens mail -before writing a notice describing it into the agent's namespace, and +next. In the other direction the runtime authenticates and screens each +message before writing a notice describing it into the agent's namespace, and withholds the bytes of anything it will not vouch for. The payoff, which the rest of this document formalizes, is the load-bearing invariant: @@ -137,7 +141,7 @@ compromised agent or connector can at most write a well-formed request that the runtime then refuses. - AMAP is the wire contract at exactly that trust boundary, and is + AMMP is the wire contract at exactly that trust boundary, and is owned by neither side of it. That ownership choice is what allows a runtime and a connector built by different parties, on different schedules, to interoperate and to co-evolve against a versioned contract with an offline @@ -190,13 +194,13 @@ particular agent harness, language, or tool interface. Non-goals
    • - AMAP is not a mail transport. It neither defines nor replaces SMTP, + AMMP is not a mail transport. It neither defines nor replaces SMTP, IMAP, or any provider-side mail infrastructure. It describes what a runtime and a connector exchange locally; whatever the runtime does with a mail provider is out of scope.
    • - AMAP is not agent-to-agent RPC. The core contract is local to + AMMP is not agent-to-agent RPC. The core contract is local to one deployment's filesystem, between two components on either side of a single trust boundary. The optional peer-origin profile () lets Agents of one principal write to one another, @@ -205,7 +209,7 @@ sending Runtime. The profile defines no call or return semantics, no discovery mechanism, and no transport of its own.
    • - AMAP is not a policy language. What a runtime's policy decides — which + AMMP is not a policy language. What a runtime's policy decides — which recipients are permitted, which content is held for review, how a sender's standing is computed — is deliberately out of scope. The wire defines only the shapes of requests and verdicts, never the computation that produces @@ -219,7 +223,7 @@ wire-verifiable fact, this document says so ().
    Why This Work Is Brought to the IETF - AMAP began as an implementation: a Runtime and Connectors built + AMMP began as an implementation: a Runtime and Connectors built separately against a shared contract, with an offline conformance suite so that each side could be tested without the other. It has been exercised in deployments of several cooperating Agents from more than one vendor, but every @@ -241,9 +245,9 @@ implementers and for interoperation testing across organizations. organization, and by the people who operate mail at scale.
  • - Alignment with related work. AMAP deliberately adds no new + Alignment with related work. AMMP deliberately adds no new transport and no new identity scheme: email stays SMTP, and how an Agent's -identity is established is left to work designed for that purpose. Where AMAP +identity is established is left to work designed for that purpose. Where AMMP touches such work, it should follow it rather than invent its own.
  • @@ -325,8 +329,9 @@ peer tree ().
  • - Agent — the untrusted process whose email capability this protocol -mediates. It holds no credential, has no send path of its own, and reaches + Agent — the untrusted process whose messaging capability this +protocol mediates: email, and under the peer-origin profile, messages to other +Agents. It holds no credential, has no send path of its own, and reaches the protocol only through its Connector. Nothing in this document places a requirement on the Agent, because no security property may depend on it.
  • @@ -427,10 +432,13 @@ host ().
  • - Runtime — the trusted, credentialed, Agent-agnostic component that -speaks the other half: it holds mail credentials, owns each Agent's -identity, makes every policy decision, and is the only party that -transmits or receives mail. + Runtime — the trusted, credentialed, Agent-agnostic, +store-and-forward messaging component that speaks the other half: it holds +the messaging credentials, owns each Agent's identity, makes every policy +decision, and is the only party that transmits or receives messages. It holds +each message before forwarding it: an outbound message is copied into private +staging and checked before anything is transmitted, and an inbound message is +screened before a Notice describing it appears.
  • @@ -489,7 +497,7 @@ No implementation may depend on that name or any other. Runtime (container) trusted - mail-send credentials, Agent identity, policy, the record of what was sent + messaging credentials, Agent identity, policy, the record of what was sent the mail provider, the Volume @@ -510,8 +518,8 @@ No implementation may depend on that name or any other. The Runtime is trusted by construction: it is the party holding the -credentials, and a compromise of it is a compromise of the mail capability -itself. The Connector is the interesting case. It runs Agent-side, is +credentials, and a compromise of it is a compromise of the messaging +capability itself. The Connector is the interesting case. It runs Agent-side, is reachable by whatever compromises the Agent, and is therefore treated as untrusted for every property that protects the Runtime, other Agents, or the outside world. Requirements this document places on a Connector fall into @@ -590,9 +598,9 @@ threat.
    Relationship to Other Agent Protocols (Informative) This subsection is informative. It contains no requirements and creates no -dependency on any external protocol. Nothing here claims that AMAP replaces, +dependency on any external protocol. Nothing here claims that AMMP replaces, subsumes, or competes with any protocol named below. - AMAP occupies a narrow position: it is the local seam at a single trust + AMMP occupies a narrow position: it is the local seam at a single trust boundary, where one side holds every credential and the other holds none. The adjacent protocols in the agent ecosystem sit at different layers, and the common question of "why not use one of them here" has a specific answer @@ -600,12 +608,12 @@ in each case. Model Context Protocol (MCP) connects an agent host to tools and context through JSON-RPC servers. It is an integration interface: live capabilities are exposed across it and exercised by the agent through it. -That makes MCP complementary to AMAP rather than an alternative. A Connector -often surfaces AMAP's operations to its Agent through MCP, or through -whatever tool interface its harness uses natively; AMAP is the +That makes MCP complementary to AMMP rather than an alternative. A Connector +often surfaces AMMP's operations to its Agent through MCP, or through +whatever tool interface its harness uses natively; AMMP is the capability-free seam sitting behind that surface. The contrast worth stating is exactly the one that motivates the two coexisting: an MCP-style interface -grants live capability across the boundary it spans, while AMAP's channel +grants live capability across the boundary it spans, while AMMP's channel deliberately grants none — the Agent-side surface can be as rich as the harness likes, because what crosses the trust boundary underneath it is an inert file. The current stable MCP specification revision is 2025-11-25; the @@ -613,11 +621,11 @@ protocol originated at Anthropic. Agent2Agent (A2A) is networked agent-to-agent RPC between mutually authenticated services, with agent cards, tasks, and HTTP/SSE/JSON-RPC transport. It presumes both endpoints are credentialed participants that can -authenticate to each other. AMAP's design center is the opposite: an +authenticate to each other. AMMP's design center is the opposite: an untrusted agent that holds no credentials at all, with enforcement placed entirely on the trusted side of a local boundary. The two are orthogonal, and compose without friction — an agent that speaks A2A to its peers can use -AMAP for its mail capability, and neither protocol needs to know about the +AMMP for its mail capability, and neither protocol needs to know about the other. A2A is at v1.0 (v1.0.1, May 2026); it originated at Google and has been hosted as a Linux Foundation project since June 2025. The two protocols abbreviated "ACP" are not the same protocol, and the @@ -633,7 +641,7 @@ here: it merged into A2A under the Linux Foundation, announced in August The Agent Client Protocol is a distinct and currently active protocol at a different layer — an interface between a host or editor and an agent — originated by Zed Industries. It is unrelated to the -merged Agent Communication Protocol and unrelated to AMAP. +merged Agent Communication Protocol and unrelated to AMMP.
  • The citation facts in this subsection were verified in July 2026. A reviewer @@ -2109,14 +2117,14 @@ addressing. message id when it accepts the submit. The id MUST be globally unique and unguessable, with at least 128 bits of entropy, and MUST be spelled under the notice_id character set (^[A-Za-z0-9_][A-Za-z0-9_.-]*$). -It has exactly one spelling inside every AMAP document: +It has exactly one spelling inside every AMMP document: message.id, message.in_reply_to and message.references[] on a Peer Notice, message_id on a peer-routed Result, and the reply key a sender submits all carry the bare id. When the id is carried in a mail header, it is encoded as <id@domain>, where domain is the sending Runtime's authority. The encoding is applied on the way into the header and removed on -the way out, and MUST NOT appear in an AMAP document. +the way out, and MUST NOT appear in an AMMP document. The reverse edge and every ledger depend on two properties of the id: that it is unguessable, and that it has one spelling end to end. Bare 32-character hexadecimal satisfies both, and so does unpadded base64url @@ -4285,7 +4293,7 @@ NOTE: '\' line wrapping per RFC 8792 "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/submit-request.schema.json", "title": "submit-request", - "description": "agent -> runtime: an inert outbound request. AMAP\ + "description": "agent -> runtime: an inert outbound request. AMMP\ , section \"Outbound: Submit Request\". Agent-authored: this doc\ ument's envelope stays CLOSED (additionalProperties:false) at ev\ ery level per the asymmetry of section \"Versioning\" — an unrec\ @@ -4385,7 +4393,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/result.schema.json", "title": "result", "description": "runtime -> agent: verdict for a submit-request. AM\ - AP, section \"Outbound: Result\". Runtime-authored: this documen\ + MP, section \"Outbound: Result\". Runtime-authored: this documen\ t's envelope is OPEN (no additionalProperties:false) at every le\ vel per the tolerance rule of section \"Versioning\" — a consume\ r MUST ignore members it does not recognize; emitting an unrecog\ @@ -4452,7 +4460,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/deliver-notice.schema.json", "title": "deliver-notice", "description": "runtime -> connector: one notice per delivered mes\ - sage. AMAP, section \"Inbound: Deliver Notice and Inbound Messag\ + sage. AMMP, section \"Inbound: Deliver Notice and Inbound Messag\ e\". Runtime-authored: this document's envelope is OPEN (no addi\ tionalProperties:false) at every level per the tolerance rule o\ f section \"Versioning\" — a consumer MUST ignore members it doe\ @@ -4559,7 +4567,7 @@ NOTE: '\' line wrapping per RFC 8792 "description": "runtime -> connector: the full delivered message (\ incl. body_text), spooled at inbound/messages/notice-.json, \ keyed on the runtime-minted notice-id (never the provider messag\ - e.id). AMAP, section \"The Inbound Message (body spool)\". Runti\ + e.id). AMMP, section \"The Inbound Message (body spool)\". Runti\ me-authored: this document's envelope is OPEN (no additionalProp\ erties:false) at every level per the tolerance rule of section \\ "Versioning\" — a consumer MUST ignore members it does not recog\ @@ -4628,7 +4636,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/binding-record.schema.json", "title": "binding-record", "description": "runtime/provisioner -> volume root: identity.json\ - , the mailbox<->volume binding record. AMAP, section \"Binding R\ + , the mailbox<->volume binding record. AMMP, section \"Binding R\ ecord\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-w\ ritable, so a consumer MUST treat contents as untrusted data an\ d MUST tolerate the file's absence. Unlike the other runtime-aut\ @@ -4670,13 +4678,13 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/peer-notice.schema.json", "title": "peer-notice", "description": "runtime -> connector: one notice per peer message \ - placed in /peer/notices/. AMAP, section \"The Peer-Ori\ + placed in /peer/notices/. AMMP, section \"The Peer-Ori\ gin Profile (Optional)\". Same layout as deliver-notice with kin\ d and mailbox pinned to \"peer\", message.from pinned to a bare \ addr-spec (the one runtime-asserted `from` in the protocol), mes\ sage.id / in_reply_to / references pinned to the notice_id chars\ et (the peer message id is bare on the wire; its Message-ID enco\ - ding exists only inside a mail header, never in an AMAP document\ + ding exists only inside a mail header, never in an AMMP document\ ), plus the optional runtime-asserted message.sender_exposure. R\ untime-authored: envelope OPEN at every level per section \"Vers\ ioning\" — a consumer MUST ignore members it does not recognize\ @@ -4705,7 +4713,7 @@ NOTE: '\' line wrapping per RFC 8792 ult.message_id, >=128 bits of entropy, globally unique and ungue\ ssable. Bare on the wire under the notice_id charset; when carri\ ed in a mail header it is encoded as and decoded aga\ - in before it enters any AMAP document.", + in before it enters any AMMP document.", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*(?!\\n)$" }, "from": { @@ -4835,7 +4843,7 @@ NOTE: '\' line wrapping per RFC 8792 "$id": "https://amap-spec/schemas/peer-statement.schema.json", "title": "peer-statement", "description": "runtime -> runtime: the signed statement that carr\ - ies a peer message between hosts. AMAP, section \"Peer Traffic B\ + ies a peer message between hosts. AMMP, section \"Peer Traffic B\ etween Hosts\". The sending runtime signs the statement's exact \ UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Stateme\ nt header field (section \"Carriage, and the Candidate the Verif\ @@ -5073,7 +5081,7 @@ NOTE: '\' line wrapping per RFC 8792 "description": "runtime -> runtime: the signed control notice a re\ ceiving runtime sends to a configured sending runtime about wha\ t it did with an authenticated peer statement that it did not pl\ - ace (refused, dropped, or demoted). AMAP, section \"Control Noti\ + ace (refused, dropped, or demoted). AMMP, section \"Control Noti\ ces\". Carried in an AMAP-Peer-Control header field with the sam\ e k/s/b grammar as AMAP-Peer-Statement, signed with the same per\ -runtime key; `kind` is \"control\", so a control notice never v\ @@ -5306,7 +5314,7 @@ NOTE: '\' line wrapping per RFC 8792 "title": "directory", "description": "runtime -> connector: the router's most recent wor\ d about which peers this agent may address, published per instan\ - ce at /directory.json. AMAP, section \"The Peer Direct\ + ce at /directory.json. AMMP, section \"The Peer Direct\ ory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is n\ ot a prediction that a submit to it will be accepted, nor its ab\ sence a prediction of refusal — authorisation is evaluated by th\ @@ -5392,7 +5400,7 @@ NOTE: '\' line wrapping per RFC 8792 ime's most recent word about which instances it has admitted, wr\ itten once for the whole fleet to a location the deployment desi\ gnates and exposes read-only to each agent it points at the rost\ - er. AMAP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ + er. AMMP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORI\ SATION: a member's presence says the instance exists, never tha\ t this agent may address it or that a submission to it will be a\ ccepted; authorisation is evaluated by the runtime at submit tim\ @@ -6710,7 +6718,7 @@ error — recorded here so that it is not rediscovered from scratch.
    Historical Background (Informative.) - AMAP was specified and implemented before it was brought to the IETF. + AMMP was specified and implemented before it was brought to the IETF. Its contract was versioned on its own scale, from 1.0.0 to 3.1.0, separately from the wire version that documents carry. This appendix records that history, newest first, because implementations were built against each @@ -6719,7 +6727,7 @@ clearest as the story of what went wrong without them. An entry that turned out to be wrong is left standing, with a correction attached, rather than quietly rewritten.
    - draft-rapp-amap-00 — brought to the IETF (contract 3.1.0) + draft-rapp-ammp-00 — brought to the IETF (contract 3.1.0)
    • One document. The peer-origin profile's prose, previously a @@ -6729,6 +6737,18 @@ revisions of this document are draft revisions, and the wire version is contract_version (), which stays "2". The reasoning that explained earlier version changes moved into this appendix (). +
    • +
    • + The protocol is AMMP. It was AMAP, the Agent +Mailbox Access Protocol, and is renamed the Agent Mediated Messaging Protocol +before its first submission: "mailbox access" named only its first channel, +and the contract is a mediation seam for an Agent's correspondence, mail and +peer traffic alike. The abstract and the definitions of Agent and Runtime +describe it that way, as a store-and-forward messaging runtime; email remains +the only transport this document defines. The acronym AMAP was also already in use by an expired +2003 individual draft. Nothing on the wire changes: no document carries the +protocol's name, and the header fields of +keep their names.
    • Editorial review for submission. Terminology was @@ -6858,7 +6878,7 @@ reach at each step. The rules are the companion document's (spec/peer-origin section 5). Additive: nothing existing changes shape, and a deployment without cross-host peer traffic is unaffected. The 30 new fixtures (8 valid, 22 invalid) bring version 3.1.0 to 119 (42 valid, 77 invalid). - Correction (draft-rapp-amap-00). The statement schema + Correction (draft-rapp-ammp-00). The statement schema accepted an id or in_reply_to beginning with "-", which the notice_id character set forbids, so a receiver could verify a statement it could not then publish; one signed case minted such an id. The diff --git a/draft/tools/check_render.py b/draft/tools/check_render.py index 1d8956e..29f02af 100755 --- a/draft/tools/check_render.py +++ b/draft/tools/check_render.py @@ -2,7 +2,7 @@ """check_render.py — post-build gate for the rendered Internet-Draft XML. Proves that what actually lands in the draft XML (draft/draft-amap.xml, the -canonical source, and its copy dist/draft-rapp-amap-00.xml) still equals a +canonical source, and its copy dist/draft-rapp-ammp-00.xml) still equals a real file on disk, byte for byte (modulo RFC 8792 folding and a trailing newline). Run after every build; `make -C draft check` wires it in. @@ -141,8 +141,8 @@ def check_roster(xml_text: str) -> list[str]: def check_docname(root: ET.Element) -> list[str]: docname = root.get("docName", "") - if docname != "draft-rapp-amap-00": - return [f"rfc/@docName is {docname!r}, expected 'draft-rapp-amap-00'"] + if docname != "draft-rapp-ammp-00": + return [f"rfc/@docName is {docname!r}, expected 'draft-rapp-ammp-00'"] return [] @@ -229,7 +229,7 @@ def check_no_broken_references(xml_text: str) -> list[str]: def main(argv: list[str]) -> int: if len(argv) != 2: - print(f"usage: {argv[0]} dist/draft-rapp-amap-00.xml", file=sys.stderr) + print(f"usage: {argv[0]} dist/draft-rapp-ammp-00.xml", file=sys.stderr) return 2 xml_path = Path(argv[1]) xml_text = xml_path.read_text(encoding="utf-8") diff --git a/draft/tools/normdiff.py b/draft/tools/normdiff.py index feb1da2..9ca575f 100644 --- a/draft/tools/normdiff.py +++ b/draft/tools/normdiff.py @@ -11,7 +11,7 @@ normdiff.py [BASE] BASE is a git ref; default origin/main If BASE predates the canonical XML (draft/draft-amap.xml), the committed -rendering in dist/ (draft-rapp-amap-00.xml, or draft-amap-00.xml before the +rendering in dist/ (draft-rapp-ammp-00.xml; draft-rapp-amap-00.xml or draft-amap-00.xml before the 2026-10 rename) is used instead, so the diff can span the switch. Informational: always exits 0 unless git itself fails. @@ -28,7 +28,7 @@ import normative # noqa: E402 REPO = Path(__file__).resolve().parent.parent.parent -CANDIDATES = ("draft/draft-amap.xml", "dist/draft-rapp-amap-00.xml", "dist/draft-amap-00.xml") +CANDIDATES = ("draft/draft-amap.xml", "dist/draft-rapp-ammp-00.xml", "dist/draft-rapp-amap-00.xml", "dist/draft-amap-00.xml") def at_ref(ref: str) -> tuple[str, str]: diff --git a/schemas/binding-record.schema.json b/schemas/binding-record.schema.json index 8a3360b..38e777b 100644 --- a/schemas/binding-record.schema.json +++ b/schemas/binding-record.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/binding-record.schema.json", "title": "binding-record", - "description": "runtime/provisioner -> volume root: identity.json, the mailbox<->volume binding record. AMAP, section \"Binding Record\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-writable, so a consumer MUST treat contents as untrusted data and MUST tolerate the file's absence. Unlike the other runtime-authored documents, this schema is closed (section \"Versioning\") — its closure is an anti-secret-leak lint, not a compatibility surface.", + "description": "runtime/provisioner -> volume root: identity.json, the mailbox<->volume binding record. AMMP, section \"Binding Record\". INFORMATIONAL, NOT AUTHORITATIVE: the volume is agent-writable, so a consumer MUST treat contents as untrusted data and MUST tolerate the file's absence. Unlike the other runtime-authored documents, this schema is closed (section \"Versioning\") — its closure is an anti-secret-leak lint, not a compatibility surface.", "type": "object", "required": ["agent_id", "address", "provisioned_ts"], "additionalProperties": false, diff --git a/schemas/deliver-notice.schema.json b/schemas/deliver-notice.schema.json index 458c0aa..54eaa02 100644 --- a/schemas/deliver-notice.schema.json +++ b/schemas/deliver-notice.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/deliver-notice.schema.json", "title": "deliver-notice", - "description": "runtime -> connector: one notice per delivered message. AMAP, section \"Inbound: Deliver Notice and Inbound Message\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: one notice per delivered message. AMMP, section \"Inbound: Deliver Notice and Inbound Message\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "notice_id", "ts", "kind", "message"], "properties": { diff --git a/schemas/directory.schema.json b/schemas/directory.schema.json index c62b09d..72d215f 100644 --- a/schemas/directory.schema.json +++ b/schemas/directory.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/directory.schema.json", "title": "directory", - "description": "runtime -> connector: the router's most recent word about which peers this agent may address, published per instance at /directory.json. AMAP, section \"The Peer Directory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is not a prediction that a submit to it will be accepted, nor its absence a prediction of refusal — authorisation is evaluated by the runtime at submit time and only the result (section \"Outbound: Result\") reports what happened. A runtime MUST NOT read this file back as authorisation; enforcement stays the runtime's own graph check on every message. The file MAY be absent. Runtime-authored: envelope is OPEN at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: the router's most recent word about which peers this agent may address, published per instance at /directory.json. AMMP, section \"The Peer Directory\". ADVISORY, NEVER AUTHORITATIVE: an address's presence is not a prediction that a submit to it will be accepted, nor its absence a prediction of refusal — authorisation is evaluated by the runtime at submit time and only the result (section \"Outbound: Result\") reports what happened. A runtime MUST NOT read this file back as authorisation; enforcement stays the runtime's own graph check on every message. The file MAY be absent. Runtime-authored: envelope is OPEN at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": [ "router", diff --git a/schemas/inbound-message.schema.json b/schemas/inbound-message.schema.json index 5dfd021..43fd1ea 100644 --- a/schemas/inbound-message.schema.json +++ b/schemas/inbound-message.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/inbound-message.schema.json", "title": "inbound-message", - "description": "runtime -> connector: the full delivered message (incl. body_text), spooled at inbound/messages/notice-.json, keyed on the runtime-minted notice-id (never the provider message.id). AMAP, section \"The Inbound Message (body spool)\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> connector: the full delivered message (incl. body_text), spooled at inbound/messages/notice-.json, keyed on the runtime-minted notice-id (never the provider message.id). AMMP, section \"The Inbound Message (body spool)\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "notice_id", "body_text"], "properties": { diff --git a/schemas/peer-control.schema.json b/schemas/peer-control.schema.json index cc40b7b..5e63376 100644 --- a/schemas/peer-control.schema.json +++ b/schemas/peer-control.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-control.schema.json", "title": "peer-control", - "description": "runtime -> runtime: the signed control notice a receiving runtime sends to a configured sending runtime about what it did with an authenticated peer statement that it did not place (refused, dropped, or demoted). AMAP, section \"Control Notices\". Carried in an AMAP-Peer-Control header field with the same k/s/b grammar as AMAP-Peer-Statement, signed with the same per-runtime key; `kind` is \"control\", so a control notice never validates as a peer statement and is never placed for an agent. CLOSED at every level, and it carries no free text: the receiving runtime composes any agent-facing words itself (the delivery failure notice of section \"Correlation and Replies\"). The schema cannot check that `about` names a peer message this runtime issued to the notice's signer; that is the receiving runtime's check (section \"Control Notices\").", + "description": "runtime -> runtime: the signed control notice a receiving runtime sends to a configured sending runtime about what it did with an authenticated peer statement that it did not place (refused, dropped, or demoted). AMMP, section \"Control Notices\". Carried in an AMAP-Peer-Control header field with the same k/s/b grammar as AMAP-Peer-Statement, signed with the same per-runtime key; `kind` is \"control\", so a control notice never validates as a peer statement and is never placed for an agent. CLOSED at every level, and it carries no free text: the receiving runtime composes any agent-facing words itself (the delivery failure notice of section \"Correlation and Replies\"). The schema cannot check that `about` names a peer message this runtime issued to the notice's signer; that is the receiving runtime's check (section \"Control Notices\").", "type": "object", "additionalProperties": false, "required": [ diff --git a/schemas/peer-notice.schema.json b/schemas/peer-notice.schema.json index a98b0da..499ab7f 100644 --- a/schemas/peer-notice.schema.json +++ b/schemas/peer-notice.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-notice.schema.json", "title": "peer-notice", - "description": "runtime -> connector: one notice per peer message placed in /peer/notices/. AMAP, section \"The Peer-Origin Profile (Optional)\". Same layout as deliver-notice with kind and mailbox pinned to \"peer\", message.from pinned to a bare addr-spec (the one runtime-asserted `from` in the protocol), message.id / in_reply_to / references pinned to the notice_id charset (the peer message id is bare on the wire; its Message-ID encoding exists only inside a mail header, never in an AMAP document), plus the optional runtime-asserted message.sender_exposure. Runtime-authored: envelope OPEN at every level per section \"Versioning\" — a consumer MUST ignore members it does not recognize. A document with kind \"peer\" found under inbound/notices/ fails deliver-notice.schema.json; a document with kind \"deliver\" found under peer/notices/ fails this schema: both are dropped under the drop rule of section \"Field semantics and obligations\" (the profile's cross-lock, section \"The Peer Tree\").", + "description": "runtime -> connector: one notice per peer message placed in /peer/notices/. AMMP, section \"The Peer-Origin Profile (Optional)\". Same layout as deliver-notice with kind and mailbox pinned to \"peer\", message.from pinned to a bare addr-spec (the one runtime-asserted `from` in the protocol), message.id / in_reply_to / references pinned to the notice_id charset (the peer message id is bare on the wire; its Message-ID encoding exists only inside a mail header, never in an AMMP document), plus the optional runtime-asserted message.sender_exposure. Runtime-authored: envelope OPEN at every level per section \"Versioning\" — a consumer MUST ignore members it does not recognize. A document with kind \"peer\" found under inbound/notices/ fails deliver-notice.schema.json; a document with kind \"deliver\" found under peer/notices/ fails this schema: both are dropped under the drop rule of section \"Field semantics and obligations\" (the profile's cross-lock, section \"The Peer Tree\").", "type": "object", "required": ["contract_version", "notice_id", "ts", "kind", "message"], "properties": { @@ -16,7 +16,7 @@ "properties": { "id": { "type": "string", "minLength": 1, - "description": "the peer message id: minted by the sending runtime on accepting the submit, returned to the sender as result.message_id, >=128 bits of entropy, globally unique and unguessable. Bare on the wire under the notice_id charset; when carried in a mail header it is encoded as and decoded again before it enters any AMAP document.", + "description": "the peer message id: minted by the sending runtime on accepting the submit, returned to the sender as result.message_id, >=128 bits of entropy, globally unique and unguessable. Bare on the wire under the notice_id charset; when carried in a mail header it is encoded as and decoded again before it enters any AMMP document.", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]*(?!\\n)$" }, "from": { diff --git a/schemas/peer-statement.schema.json b/schemas/peer-statement.schema.json index 93eafa0..d86731e 100644 --- a/schemas/peer-statement.schema.json +++ b/schemas/peer-statement.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/peer-statement.schema.json", "title": "peer-statement", - "description": "runtime -> runtime: the signed statement that carries a peer message between hosts. AMAP, section \"Peer Traffic Between Hosts\". The sending runtime signs the statement's exact UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Statement header field (section \"Carriage, and the Candidate the Verifier Sees\"); the receiving runtime verifies the signature over the received bytes before parsing, then validates against this schema. CLOSED at every level, unlike the runtime-authored notices: these are signed bytes another runtime acts on, a member the receiver does not know is a member it cannot bind to what it publishes, and the version member `v` is the only evolution path. A statement that fails this schema fails verification, and the message is demoted to mail (sections \"Verification\" and \"Outcomes\"). Numbers are lexical integers (no fraction or exponent) and strings contain no unpaired surrogate (section \"The Statement\", checked at check 5(b) of section \"Verification\"); the schema cannot express either, nor calendar validity, interval order, the entropy of `id`, or any binding to the message: those are the verification steps of section \"Verification\".", + "description": "runtime -> runtime: the signed statement that carries a peer message between hosts. AMMP, section \"Peer Traffic Between Hosts\". The sending runtime signs the statement's exact UTF-8 bytes with Ed25519 and ships both in one AMAP-Peer-Statement header field (section \"Carriage, and the Candidate the Verifier Sees\"); the receiving runtime verifies the signature over the received bytes before parsing, then validates against this schema. CLOSED at every level, unlike the runtime-authored notices: these are signed bytes another runtime acts on, a member the receiver does not know is a member it cannot bind to what it publishes, and the version member `v` is the only evolution path. A statement that fails this schema fails verification, and the message is demoted to mail (sections \"Verification\" and \"Outcomes\"). Numbers are lexical integers (no fraction or exponent) and strings contain no unpaired surrogate (section \"The Statement\", checked at check 5(b) of section \"Verification\"); the schema cannot express either, nor calendar validity, interval order, the entropy of `id`, or any binding to the message: those are the verification steps of section \"Verification\".", "type": "object", "additionalProperties": false, "required": [ diff --git a/schemas/result.schema.json b/schemas/result.schema.json index 3399ce4..d830a97 100644 --- a/schemas/result.schema.json +++ b/schemas/result.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/result.schema.json", "title": "result", - "description": "runtime -> agent: verdict for a submit-request. AMAP, section \"Outbound: Result\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> agent: verdict for a submit-request. AMMP, section \"Outbound: Result\". Runtime-authored: this document's envelope is OPEN (no additionalProperties:false) at every level per the tolerance rule of section \"Versioning\" — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": ["contract_version", "req_id", "outcome"], "properties": { diff --git a/schemas/roster.schema.json b/schemas/roster.schema.json index a73e5dc..1ba1fdf 100644 --- a/schemas/roster.schema.json +++ b/schemas/roster.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/roster.schema.json", "title": "roster", - "description": "runtime -> every agent: the fleet roster, the runtime's most recent word about which instances it has admitted, written once for the whole fleet to a location the deployment designates and exposes read-only to each agent it points at the roster. AMAP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORISATION: a member's presence says the instance exists, never that this agent may address it or that a submission to it will be accepted; authorisation is evaluated by the runtime at submit time and only the result reports what happened. NOT A SOURCE OF THE READER'S IDENTITY: the reader's own address may appear, and attribution stays the namespace a file arrived in. A runtime MUST NOT read this file back. The file MAY be absent; absent or stale means unknown, never an empty fleet. Runtime-authored: envelope is OPEN at every level — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", + "description": "runtime -> every agent: the fleet roster, the runtime's most recent word about which instances it has admitted, written once for the whole fleet to a location the deployment designates and exposes read-only to each agent it points at the roster. AMMP, section \"The Fleet Roster\". EXISTENCE IS NOT AUTHORISATION: a member's presence says the instance exists, never that this agent may address it or that a submission to it will be accepted; authorisation is evaluated by the runtime at submit time and only the result reports what happened. NOT A SOURCE OF THE READER'S IDENTITY: the reader's own address may appear, and attribution stays the namespace a file arrived in. A runtime MUST NOT read this file back. The file MAY be absent; absent or stale means unknown, never an empty fleet. Runtime-authored: envelope is OPEN at every level — a consumer MUST ignore members it does not recognize; emitting an unrecognized member remains producer non-conformance.", "type": "object", "required": [ "contract_version", diff --git a/schemas/submit-request.schema.json b/schemas/submit-request.schema.json index d28a10c..70d43c1 100644 --- a/schemas/submit-request.schema.json +++ b/schemas/submit-request.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://amap-spec/schemas/submit-request.schema.json", "title": "submit-request", - "description": "agent -> runtime: an inert outbound request. AMAP, section \"Outbound: Submit Request\". Agent-authored: this document's envelope stays CLOSED (additionalProperties:false) at every level per the asymmetry of section \"Versioning\" — an unrecognized member here is a designed, legible `rejected` refusal, never a silent drop.", + "description": "agent -> runtime: an inert outbound request. AMMP, section \"Outbound: Submit Request\". Agent-authored: this document's envelope stays CLOSED (additionalProperties:false) at every level per the asymmetry of section \"Versioning\" — an unrecognized member here is a designed, legible `rejected` refusal, never a silent drop.", "type": "object", "required": ["contract_version", "req_id", "draft"], "additionalProperties": false, diff --git a/site/src/glossary.html b/site/src/glossary.html index fd29fab..977debb 100644 --- a/site/src/glossary.html +++ b/site/src/glossary.html @@ -1,7 +1,7 @@

      Reference

      Glossary

      -

      The terms used across this site and the AMAP specification. A reference such as "§ Inbound" names a section of the AMAP Internet-Draft (draft-rapp-amap-00), including its optional peer-origin profile, "the profile" for short.

      +

      The terms used across this site and the AMAP specification. A reference such as "§ Inbound" names a section of the AMAP Internet-Draft (draft-rapp-ammp-00), including its optional peer-origin profile, "the profile" for short.

      Agent
      @@ -26,7 +26,7 @@

      Glossary

      On an inbound attachment descriptor, the runtime's access grant to published bytes, in the form <notice_id>.attachments/<index>. It is present only for bytes the runtime asserts clean. A connector must never emit one outbound (§ Submit Request; § Inbound).
      contract_version
      -
      The wire major version carried in every document, currently "2". It is separate from the specification's own SemVer (3.1.0 at draft-rapp-amap-00). Read it before schema validation: a mismatched major is a version refusal and fails closed (§ Versioning and Conformance).
      +
      The wire major version carried in every document, currently "2". It is separate from the specification's own SemVer (3.1.0 at draft-rapp-ammp-00). Read it before schema validation: a mismatched major is a version refusal and fails closed (§ Versioning and Conformance).
      Deliver-notice
      The runtime's pointer-plus-summary for one delivered mail message, at inbound/notices/notice-<id>.json, with kind: "deliver" (§ Inbound).
      diff --git a/site/src/implementers.html b/site/src/implementers.html index 4004a34..9af43fa 100644 --- a/site/src/implementers.html +++ b/site/src/implementers.html @@ -4,7 +4,7 @@

      The AMAP specification, at the wire level

      AMAP defines a wire contract between a trusted runtime, which holds the mail credentials and applies policy, and an agent-side connector, which holds nothing credentialed. The two sides share one thing: a per-agent filesystem namespace. This page summarises what each side must do. The authority is the specification itself.

      -

      Source of truth. The AMAP Internet-Draft (draft-rapp-amap-00; its source is draft/draft-amap.xml), the schemas and the fixtures are the normative specification. The peer-origin profile is a section of the Internet-Draft, § The Peer-Origin Profile (Optional). Where this page and the specification disagree, the specification wins. A reference such as "§ Inbound" names a section of the Internet-Draft. The older spec/contract.md and spec/peer-origin.md are frozen history, not the specification.

      +

      Source of truth. The AMAP Internet-Draft (draft-rapp-ammp-00; its source is draft/draft-amap.xml), the schemas and the fixtures are the normative specification. The peer-origin profile is a section of the Internet-Draft, § The Peer-Origin Profile (Optional). Where this page and the specification disagree, the specification wins. A reference such as "§ Inbound" names a section of the Internet-Draft. The older spec/contract.md and spec/peer-origin.md are frozen history, not the specification.

      Three actors, one invariant

      @@ -139,7 +139,7 @@

      Enforcement by absence

      Versioning

      Two axes, not one:

        -
      • The specification's own version (3.1.0 at draft-rapp-amap-00) is SemVer for the document. The Internet-Draft's own revisions (-00, -01, …) are a third sequence, and its body does not carry the SemVer. Additive changes are MINOR, and a change that breaks an existing fixture is MAJOR.
      • +
      • The specification's own version (3.1.0 at draft-rapp-ammp-00) is SemVer for the document. The Internet-Draft's own revisions (-00, -01, …) are a third sequence, and its body does not carry the SemVer. Additive changes are MINOR, and a change that breaks an existing fixture is MAJOR.
      • The wire contract_version (currently "2") is what goes in every document and what a consumer checks.

      Read contract_version before any schema validation, comparing majors as non-negative integers (§ Versioning and Conformance). An absent, lower or higher major is a version refusal that fails closed. It is a distinct, logged outcome, never folded into the malformed-document path. The refusal is asymmetric:

      diff --git a/site/src/status.html b/site/src/status.html index 4f1d6e6..f2ba1d6 100644 --- a/site/src/status.html +++ b/site/src/status.html @@ -1,4 +1,4 @@ - +

      Status

      What exists, and what does not yet

      Enough to invite scrutiny, not enough to claim adoption.