<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     version="3"
     ipr="trust200902"
     submissionType="independent"
     category="info"
     docName="draft-zambo-aer1-00"
     tocInclude="true"
     sortRefs="true"
     symRefs="true">

<front>
  <title abbrev="AER-1">AER-1: A Portable Execution Receipt for AI Agent Tool Calls</title>
  <seriesInfo name="Internet-Draft" value="draft-zambo-aer1-00"/>

  <author fullname="Brennan Zambo" initials="B." surname="Zambo">
    <organization>Zambo</organization>
    <address>
      <email>brennanzambo@zambo.dev</email>
      <uri>https://zambo.dev/aer-1</uri>
    </address>
  </author>

  <date year="2026" month="September" day="23"/>

  <area>General</area>
  <workgroup>Independent Submission</workgroup>
  <keyword>receipt</keyword>
  <keyword>agent</keyword>
  <keyword>tool call</keyword>
  <keyword>provenance</keyword>
  <keyword>verification</keyword>

  <abstract>
    <t>This document specifies AER-1, a small vocabulary for recording one AI
    agent tool call as a portable, independently checkable execution receipt.
    A receipt identifies the execution, records when it happened, preserves
    the canonical bytes used for the output commitment, names the tool and
    caller scope, carries a provenance class, and resolves at a stable public
    URL. The format separates what the system observed from claims about the
    outside world, and it separates provenance (who ran or reported the action)
    from the record itself. A reference implementation is deployed, and its
    receipts are publicly verifiable without an account or token.</t>
  </abstract>
</front>

<middle>

<section anchor="intro">
  <name>Introduction</name>
  <t>AI agents increasingly act through tool calls: they query prices, send
  messages, modify files, and invoke services on a principal's behalf. When
  something later needs checking -- what happened, when it happened, and what
  the system actually observed -- the parties involved usually have only
  vendor-specific logs, screenshots, or the agent's own summary. None of these
  is portable across implementations, and none lets an independent third party
  recompute what was recorded.</t>
  <t>AER-1 (AI Agent Execution Receipt, version 1) defines a small, portable
  vocabulary for recording one agent tool call as a verifiable receipt. The
  receipt answers a narrow question: what did this system record for this
  execution? It does not prove an external business outcome the system did not
  observe, and it does not turn a planned, blocked, or preview action into a
  completed execution.</t>
  <t>This document is an open proposal authored by Brennan Zambo. It is not a
  claim to invent or own the broader execution-receipt category, and it does
  not establish certification, registry membership, universal adoption, or a
  finalized standards status. It is intended for discussion, implementation
  experiments, and interoperability feedback. A reference implementation is
  deployed at the time of writing, and its receipts are publicly verifiable as
  described in <xref target="refimpl"/>.</t>
</section>

<section anchor="terms">
  <name>Terminology</name>
  <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
  "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
  "OPTIONAL" in this document are to be interpreted as described in BCP 14
  <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
  appear in all capitals, as shown here.</t>
  <t>This document also uses the following terms:</t>
  <dl>
    <dt>Execution:</dt><dd>One invocation of one tool by or on behalf of an
    agent, with its inputs, observed result, and timing.</dd>
    <dt>Receipt:</dt><dd>A public record for one execution with a stable
    identifier, execution metadata, canonical bytes, and an output commitment,
    as defined in <xref target="record"/>.</dd>
    <dt>Canonical bytes:</dt><dd>The exact UTF-8 byte sequence over which the
    output commitment was computed. Verifiers MUST receive or reproduce the
    same bytes before comparing hashes.</dd>
    <dt>Observed result:</dt><dd>The result the implementation received and
    stored for the execution. A receipt reports observation, not an
    unsupported claim about the world beyond the observation.</dd>
    <dt>Output commitment:</dt><dd>A SHA-256 digest of the canonical bytes,
    written "sha256:" followed by the lowercase hexadecimal digest.</dd>
  </dl>
</section>

<section anchor="record">
  <name>The Receipt Record</name>
  <t>A receipt is a JSON object with the following members. This is the
  smallest useful interoperable shape; implementations MAY add fields, but
  additions MUST NOT make the core identity or verification fields
  ambiguous.</t>
  <table>
    <name>Core receipt members</name>
    <thead>
      <tr><th>Field</th><th>Required</th><th>Meaning</th></tr>
    </thead>
    <tbody>
      <tr><td>id</td><td>MUST</td><td>Stable UUID identifying the receipt.</td></tr>
      <tr><td>receipt_schema_version</td><td>MUST</td><td>Schema version. "0.3" in the reference implementation.</td></tr>
      <tr><td>created_at</td><td>MUST</td><td>Timestamp of record creation, in RFC 3339 format.</td></tr>
      <tr><td>tool</td><td>MUST</td><td>Object naming the tool: name, version, and caller scope (for example "public").</td></tr>
      <tr><td>provenance_class</td><td>MUST</td><td>One of the provenance classes in <xref target="provenance"/>.</td></tr>
      <tr><td>canonical_bytes</td><td>MUST</td><td>Base64 encoding of the exact UTF-8 bytes hashed for the output commitment.</td></tr>
      <tr><td>output_hash</td><td>MUST</td><td>"sha256:" plus the lowercase hex digest of the decoded canonical_bytes.</td></tr>
      <tr><td>verification_status</td><td>MUST</td><td>"verified" when the stored record passes the procedure in <xref target="verifyproc"/>.</td></tr>
    </tbody>
  </table>
  <t>The public URL is not a stored member; it is a resolution rule. Every
  receipt MUST be retrievable at a stable public URL without an account,
  wallet, or token, as specified in <xref target="resolution"/>. In the
  reference implementation the URL is https://zambo.dev/run/&lt;id&gt;.</t>
  <t>Deployed records carry additional members outside the interoperable core
  (for example caller identity, evidence references, external anchor data,
  per-check results, side-effect declarations, and a result preview). A
  verifier MUST NOT require them, and their presence MUST NOT change the
  meaning of the core members.</t>
  <t>Example: the following shows the core fields of a real receipt issued by
  the reference implementation (id 130da435-e157-498e-af90-605866a86a27,
  a live_price call). The canonical bytes and output hash are elided here to
  respect line-length limits; the complete record is published at
  https://zambo.dev/run/130da435-e157-498e-af90-605866a86a27, where the
  output hash was independently recomputed from the decoded canonical bytes
  while preparing this document and matches.</t>
  <sourcecode name="" type="json"><![CDATA[
{
  "id": "130da435-e157-498e-af90-605866a86a27",
  "receipt_schema_version": "0.3",
  "created_at": "2026-09-23T23:45:20.760Z",
  "tool": {
    "name": "live_price",
    "version": "4.0.0",
    "scope": "public"
  },
  "provenance_class": "EXECUTED BY ZAMBO",
  "canonical_bytes": "(elided; full value at the URL above)",
  "output_hash": "(elided; full value at the URL above)",
  "verification_status": "verified"
}
  ]]></sourcecode>
</section>

<section anchor="canonical">
  <name>Canonical Bytes and Output Commitment</name>
  <t>Interoperability fails when every implementation gives a different name
  to the same boundary, so the checkable core of a receipt is deliberately
  small: an identifier locates the record, a creation time orders it, a tool
  and caller scope identify the execution context, and canonical bytes plus an
  output hash make the stored representation checkable.</t>
  <t>The producer MUST preserve the exact UTF-8 byte sequence that was hashed,
  and MUST expose it (directly, or in a form from which a verifier can
  reproduce it byte for byte) so that any party can recompute the digest. The
  digest algorithm is SHA-256 <xref target="FIPS180-4"/>. A verifier that
  cannot obtain or reproduce the exact canonical bytes MUST NOT report the
  output commitment as confirmed.</t>
  <t>A result preview MAY accompany the receipt to give a human reader a
  useful first read. A preview is not the source dataset, and a verifier MUST
  NOT treat agreement with a preview as agreement with the committed
  bytes.</t>
</section>

<section anchor="provenance">
  <name>Provenance Classes</name>
  <t>A whole job can combine actions performed by the recording system itself,
  actions observed through an integrated gateway, and actions reported by
  another agent. Those cases can all be useful, but they do not support the
  same statement, so every receipt MUST name exactly one provenance class.
  Verification MUST NOT upgrade a report into an observation.</t>
  <t>The three classes are:</t>
  <dl>
    <dt>EXECUTED BY ZAMBO:</dt><dd>The recording system ran the tool and
    recorded the returned result. The receipt can attest to that execution and
    its stored output commitment.</dd>
    <dt>OBSERVED VIA GATEWAY:</dt><dd>The recording system observed the action
    through an integrated gateway. The receipt attests to the gateway
    observation, not to facts beyond what the gateway returned.</dd>
    <dt>LOGGED BY AGENT:</dt><dd>An external agent reported the action through
    a journal interface. The receipt attests that the report was received,
    redacted, timestamped, and chained. The recording system does not claim it
    ran or observed the action.</dd>
  </dl>
  <t>The first label names the recording system; its interoperable content is
  the definition, and another implementation substitutes its own system name
  in that position. The second and third labels are fixed strings.</t>
  <t>Provenance is a separate design axis from the receipt envelope. Two
  receipts with identical envelopes can carry different provenance, and a
  verifier MUST surface the provenance class alongside every other field when
  presenting a receipt.</t>
</section>

<section anchor="verifyproc">
  <name>Verification Procedure</name>
  <t>To verify a receipt, a verifier performs the following steps:</t>
  <ol>
    <li>Resolve the public receipt URL and confirm the id in the retrieved
    record matches the requested execution.</li>
    <li>Read the exact canonical bytes, or the representation needed to
    reproduce them byte for byte.</li>
    <li>Compute SHA-256 over those bytes and compare the result with
    output_hash.</li>
    <li>Review the tool, timestamp, caller scope, observed result, evidence,
    and anchor status separately from the hash check.</li>
    <li>Report only what the stored observation supports. A passing hash
    confirms the bytes match the commitment; it does not confirm anything the
    system did not observe.</li>
  </ol>
  <t>A machine-readable verifier SHOULD expose the same procedure over HTTP,
  returning the receipt identifier, verification status, and output hash, and
  signaling failure with a non-success status when the record does not verify.
  In the reference implementation, an HTTP GET on
  https://zambo.dev/api/receipt/&lt;id&gt;/verify returns a JSON object
  containing at least id, verification_status, and output_hash.</t>
</section>

<section anchor="chain">
  <name>Hash-Chained Job Timelines</name>
  <t>Entries for one job form an append-only hash chain: each entry commits to
  the previous entry's digest, so insertion, deletion, or reordering of
  entries is detectable by recomputation. A public page resolving the whole
  timeline reports whether the visible chain verifies. The reference
  implementation exposes this as a per-receipt chain-validity check alongside
  the other verification checks.</t>
  <t>Chaining provides tamper evidence for the sequence, not truth about the
  world. A chained entry with LOGGED BY AGENT provenance remains a chained
  report; the chain upgrades nothing about what the entry attests.</t>
</section>

<section anchor="resolution">
  <name>Public Resolution</name>
  <t>Every receipt MUST be retrievable at its public URL without an account,
  wallet, or token. The URL is stable: once published, the record at that URL
  MUST NOT be altered. Corrections are published as new receipts that
  reference the superseded id; they MUST NOT rewrite history at the original
  URL.</t>
  <t>The public page SHOULD present the receipt fields, the provenance class,
  the verification outcome, and the hash chain position in human-readable form
  alongside the raw JSON.</t>
</section>

<section anchor="anchoring">
  <name>External Anchoring</name>
  <t>A receipt MAY be bound to one or more external timestamp anchors after
  issuance. Anchoring is additive: it does not alter the receipt bytes and
  MUST NOT invalidate the output commitment.</t>
  <t>In the reference implementation, each receipt is anchored to public Nostr
  relays. The anchor object carries the relay event identifier, the publisher
  key, the relay URLs, a published status, and the publication time, plus an
  envelope binding the anchor to the receipt id, the output hash, and the
  evidence hash. Anchoring gives verifiers a witness independent of the
  receipt publisher; it does not change what the receipt attests.</t>
</section>

<section anchor="refimpl">
  <name>Reference Implementation</name>
  <t>A reference implementation of this vocabulary is deployed at the time of
  writing, described at <xref target="AER-1-HOME"/>. The implementation
  exposes the receipt contract through one MCP endpoint and gives successful
  calls a public receipt page:</t>
  <ul>
    <li>Tool calls are made over HTTPS as JSON-RPC to
    https://zambo.dev/api/mcp using the tools/call method. The response
    contains the receipt identity and the public verification link.</li>
    <li>Each receipt resolves at https://zambo.dev/run/&lt;id&gt; and can be
    opened and checked by anyone, with no account or token.</li>
    <li>A verifier endpoint returns the machine-readable verification result
    for a receipt identifier, as described in <xref target="verifyproc"/>.</li>
  </ul>
  <t>The endpoint and the receipt pages are independent live records: anyone
  can reproduce the <xref target="verifyproc"/> procedure against them today.
  Their availability is a deployment fact, not a standards claim; if the
  deployment moves, the canonical home of this document's latest revision is
  updated accordingly.</t>
</section>

<section anchor="rationale">
  <name>Design Rationale</name>
  <t>AER-1 starts with a narrow record rather than a universal theory of agent
  behavior. An agent may call several tools, receive information from several
  providers, and hand work to another agent. A reviewer still needs a stable
  way to identify one execution, understand what the system observed, and
  check whether the published bytes match the stated commitment. The draft
  keeps those needs separate from claims about the outside world.</t>
  <t>The vocabulary is intentionally small because interoperability fails when
  every implementation gives a different name to the same boundary. An
  identifier locates the record. A creation time orders it. A tool and caller
  scope identify the execution context. Canonical bytes and an output hash
  make the stored representation checkable. A result preview gives a human a
  useful first read without pretending that a preview is the entire source
  dataset.</t>
  <t>Provenance is a separate design axis (<xref target="provenance"/>). A
  system can execute a tool itself, observe an action through an integrated
  gateway, or receive a report from another agent. AER-1 treats these as
  distinct attestations because they are distinct claims, and a verifier that
  cannot tell them apart cannot report honestly.</t>
  <t>On canonicalization: AER-1 preserves the producer's exact bytes and
  carries them explicitly, rather than mandating a canonicalization scheme
  such as the JSON Canonicalization Scheme <xref target="RFC8785"/>. A
  verifier MUST NOT re-serialize the record under a different scheme and claim
  agreement with the commitment. The cost of this choice is stated plainly:
  digests computed under different canonicalizations do not interoperate, so
  cross-implementation verification requires byte-identical canonical
  content.</t>
  <t>On resolution: AER-1 chooses public URL resolution as the primary
  verification experience, so that checking a receipt needs no key
  distribution and no trust anchor obtained out of band. The tradeoff is
  availability dependence on the publisher; deployments that cannot accept
  that tradeoff can pair the record with the external anchoring in
  <xref target="anchoring"/> or with offline recomputation from the carried
  canonical bytes.</t>
</section>

<section anchor="security">
  <name>Security Considerations</name>
  <t>A receipt is evidence of what was recorded, not a security boundary by
  itself. The following considerations apply to implementations:</t>
  <ul>
    <li>The output commitment binds the recorded bytes, not the real world.
    An implementation that records attacker-controlled input produces a
    verifiable receipt of attacker-controlled input. Verifiers MUST present
    the observed result as observed, never as independently true.</li>
    <li>Canonical bytes MUST be preserved exactly. Any transformation
    (re-encoding, whitespace normalization, character set conversion) between
    recording and verification breaks the commitment and MUST cause
    verification to fail closed.</li>
    <li>Public receipt URLs are stable and permanent. Implementations MUST
    consider privacy before publishing: a receipt that embeds personal data,
    credentials, or confidential business information in its canonical bytes
    publishes that data to everyone. Redact before recording; a receipt
    cannot be unpublished.</li>
    <li>Provenance classes are attestations by the recording system about
    itself. A dishonest recorder can mislabel provenance. Consumers who need
    stronger guarantees should use the external anchoring in
    <xref target="anchoring"/> or bind receipts to independent witness
    records.</li>
    <li>Verification endpoints MUST NOT leak information beyond the receipt
    record itself, and MUST rate-limit verification requests to prevent the
    endpoint from becoming an oracle for probing non-public
    executions.</li>
  </ul>
</section>

<section anchor="iana">
  <name>IANA Considerations</name>
  <t>This document has no IANA actions.</t>
</section>

<section anchor="related">
  <name>Related Work</name>
  <t>Action receipts for AI agents are an active area with multiple concurrent
  individual proposals, including formats built around signed envelopes bound
  to decision evidence, hash-chained action records verifiable offline, and
  canonicalization-based offline recomputation. This document does not survey
  or endorse any of them by name.</t>
  <t>AER-1 differs in three ways. First, the receipt is identified by a UUID
  and resolved at a stable public URL, with verification offered as a public
  HTTP endpoint rather than offline recomputation. Second, it carries
  provenance (executed, observed-via-gateway, logged-by-agent) as a
  first-class field, so a verifier can distinguish what the recording system
  did from what it merely recorded. Third, a reference implementation is
  deployed whose receipts are publicly verifiable without an account, key, or
  token. AER-1 standardizes the narrow per-execution record and its public
  verification procedure, leaving decision semantics, authorization, and
  settlement bindings to other specifications.</t>
</section>

</middle>

<back>

<references>
  <name>Normative References</name>
  <reference anchor="FIPS180-4">
    <front>
      <title>Secure Hash Standard</title>
      <author><organization>National Institute of Standards and Technology</organization></author>
      <date year="2015" month="August"/>
    </front>
    <seriesInfo name="FIPS" value="180-4"/>

    <refcontent>DOI 10.6028/NIST.FIPS.180-4</refcontent>
  </reference>
  <reference anchor="RFC2119">
    <front>
      <title>Key words for use in RFCs to Indicate Requirement Levels</title>
      <author initials="S." surname="Bradner" fullname="Scott Bradner"/>
      <date year="1997" month="March"/>
    </front>
    <seriesInfo name="BCP" value="14"/>
    <seriesInfo name="RFC" value="2119"/>

  </reference>
  <reference anchor="RFC8174">
    <front>
      <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
      <author initials="B." surname="Leiba" fullname="Barry Leiba"/>
      <date year="2017" month="May"/>
    </front>
    <seriesInfo name="BCP" value="14"/>
    <seriesInfo name="RFC" value="8174"/>

  </reference>
</references>

<references>
  <name>Informative References</name>
  <reference anchor="AER-1-HOME">
    <front>
      <title>AER-1: AI Agent Execution Receipt (open draft)</title>
      <author initials="B." surname="Zambo" fullname="Brennan Zambo"/>
      <date year="2026" month="September"/>
    </front>

    <refcontent>https://zambo.dev/aer-1</refcontent>
  </reference>
  <reference anchor="RFC8785">
    <front>
      <title>JSON Canonicalization Scheme (JCS)</title>
      <author initials="A." surname="Rundgren" fullname="Anders Rundgren"/>
      <author initials="B." surname="Jordan" fullname="Bret Jordan"/>
      <author initials="S." surname="Erdtman" fullname="Samuel Erdtman"/>
      <date year="2020" month="June"/>
    </front>
    <seriesInfo name="RFC" value="8785"/>

  </reference>
</references>

</back>
</rfc>
