<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     docName="draft-schrock-ep-action-evidence-graph-00"
     category="info" ipr="trust200902" submissionType="IETF"
     version="3" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="Action Evidence Graphs">Action Evidence Graphs and Evidence Policy Replay for High-Risk Agent Actions (EP-AEG)</title>
    <seriesInfo name="Internet-Draft" value="draft-schrock-ep-action-evidence-graph-00"/>
    <author fullname="Iman Schrock">
      <organization>EMILIA Protocol, Inc.</organization>
      <address>
        <postal>
          <country>US</country>
        </postal>
        <email>team@emiliaprotocol.ai</email>
      </address>
    </author>
    <date year="2026" month="July" day="2"/>
    <area>sec</area>
    <keyword>AI agents</keyword>
    <keyword>evidence</keyword>
    <keyword>admissibility</keyword>
    <keyword>reliance</keyword>
    <keyword>policy replay</keyword>
    <keyword>JCS</keyword>
    <abstract>
      <t>The standards landscape now produces many signed artifacts about
      an AI agent's action: workload identity credentials, delegation and
      grant tokens, call-chain transaction tokens, runtime attestation
      results, pre-execution policy permits, named-human authorization
      receipts, post-execution action records, and transparency-log
      inclusion receipts. No specification defines how a relying party
      decides whether a collection of such artifacts is SUFFICIENT to
      rely on for a given purpose: releasing a payment, honoring a
      trade, satisfying an auditor, or paying an insurance claim. This
      document defines three things that together fill that layer: the
      Action Evidence Graph (EP-AEG), a portable, content-addressed
      graph of references to signed artifacts about one action, whose
      identity is independent of how much of it is disclosed; Evidence
      Policy Replay, a deterministic, offline evaluation of a graph
      against a RELYING-PARTY-supplied evidence policy, yielding one of
      five closed verdicts (admissible, missing_evidence, stale,
      conflicted, unverifiable) with a replay digest that lets any third
      party recompute the decision; and the Reliance Result
      (EP-RELIANCE-RESULT), the verdict as a signed artifact, making the
      reliance decision itself auditable evidence. Six policy packs
      profile the mechanism for concrete irreversible action classes. A
      verdict is evidence of sufficiency under a stated policy; it is
      not adjudication, and the graph never carries its own sufficiency
      bar.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>Standards efforts have converged on signing artifacts about
      agent actions, and on a shared substrate for doing so: a canonical
      digest of the action (JSON Canonicalization Scheme, JCS
      <xref target="RFC8785"/>) bound under a signature. Workload
      identity (WIMSE, SPIFFE), delegation and grants (OAuth, GNAP
      <xref target="RFC9635"/>), call-chain context (OAuth transaction
      tokens), runtime attestation (RATS <xref target="RFC9334"/>, EAT
      <xref target="RFC9711"/>), pre-execution permits, named-human
      authorization receipts, post-execution action records, and
      transparency services (SCITT <xref target="RFC9943"/>) each
      produce their own artifact. Each artifact answers its own
      question. None answers the relying party's question:</t>
      <t>Given all of these artifacts, is this action evidence
      sufficient for THIS reliance purpose?</t>
      <t>A bank releasing a wire, an insurer paying a claim, a
      regulator auditing an agent's action, and a gateway deciding
      whether to execute an irreversible call each need a different
      sufficiency bar over the same artifacts. Today that decision is
      made ad hoc, is not reproducible, and leaves no evidence of its
      own. This document defines the missing layer. It deliberately
      defines no new receipt type: every leg of an evidence graph is an
      existing artifact verified under its own specification's rules.
      Within the same family,
      <xref target="I-D.schrock-ep-authorization-receipts"/> defines the
      named-human authorization artifact this layer most often consumes,
      and <xref target="I-D.schrock-ep-authorization-evidence-chain"/>
      defines same-action composition of heterogeneous receipts into one
      ALLOW/DENY; this document generalizes that composition into a
      referenced graph and adds the purpose-relative sufficiency
      decision, its replay property, and the signed reliance result.</t>
      <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>Relying party: the entity deciding whether to act on the
        evidence (execute, settle, audit, insure). Presenter: the
        entity assembling and conveying the graph, typically the agent
        operator. The presenter and relying party MUST be assumed to be
        different trust domains.</t>
      </section>
    </section>
    <section anchor="graph">
      <name>The Action Evidence Graph (EP-AEG-v1)</name>
      <t>An evidence graph is a JSON document with members "@version"
      (the string "EP-AEG-v1"), "action_digest" (the JCS/SHA-256 digest
      of the canonical action), "nodes", and "edges".</t>
      <section anchor="nodes">
        <name>Nodes are content-addressed references</name>
        <t>Each node has an "id" equal to the SHA-256 digest of the
        referenced artifact's JCS-canonical bytes, a "type" token
        naming the artifact class (for example authorization_receipt,
        policy_permit, workload_identity, execution_attestation,
        transparency, delegation, recourse_reference), and OPTIONALLY
        the artifact itself inline. A verifier MUST reject an inline
        artifact whose canonical digest does not equal the node id.
        Because nodes are references, a presenter can disclose the
        SHAPE of its evidence without the contents; an undisclosed node
        contributes nothing to sufficiency and a required undisclosed
        node fails closed.</t>
      </section>
      <section anchor="edges">
        <name>Edges are presenter claims, verified against bytes</name>
        <t>Each edge has "from" and "to" node ids and a "rel" from the
        relation registry: authorizes, permits, delegates, executes,
        records, attests_runtime, revokes, provides_recourse,
        supersedes. An edge is a PRESENTER CLAIM. A verifier MUST NOT
        credit an edge unless the claimed binding is present in the
        source artifact's own canonical bytes (at minimum, containment
        of the target's digest; artifact-type-specific verifiers MAY
        require a stricter, field-level binding). A claimed edge that
        the bytes do not back MUST poison the evaluation: the graph has
        asserted something its evidence does not support, and the
        verdict MUST NOT be admissible.</t>
      </section>
      <section anchor="identity">
        <name>Graph identity is disclosure-independent</name>
        <t>The graph digest is computed over the sorted (id, type)
        node pairs, the sorted edges, and the action digest, and never
        over inline artifact bytes. Two parties holding different
        disclosures of the same graph agree on what graph they are
        discussing.</t>
      </section>
    </section>
    <section anchor="replay">
      <name>Evidence Policy Replay</name>
      <t>The sufficiency bar is an EVIDENCE POLICY supplied by the
      relying party. The graph document has no policy member, by
      construction: a presenter choosing its own sufficiency bar is the
      confused-deputy failure of evidence systems. A policy names its
      reliance purpose; a boolean requirement expression over node
      types; per-type freshness bounds; per-type revocation
      requirements; and REQUIRED EDGES — bindings that must be present
      and byte-backed (for example, an execution record MUST provably
      reference the authorization it acted under).</t>
      <t>Evaluation is deterministic and offline: given the same graph,
      policy, and evaluation time, any implementation reaches the same
      verdict and the same replay digest (a canonical digest over the
      policy, the normalized evidence facts, the graph digest, and the
      evaluation time). The verdict is one of a CLOSED set of five:
      admissible, missing_evidence, stale, conflicted, unverifiable,
      with precedence unverifiable over conflicted over stale over
      missing_evidence over admissible, so no failure ever degrades
      toward admissibility. Machine-readable reason codes accompany the verdict; the
      reference implementation currently emits unbacked_edge_claim,
      malformed_graph, and action_digest_mismatch, and additionally
      reserves (declares but does not yet emit) missing_human_approval,
      untrusted_workload, contradicted_outcome, revoked_artifact, and
      stale_evidence for richer classifications. The reason vocabulary
      is open, the verdict set is not. The token "admissible" is a
      protocol token naming sufficiency under the stated policy; it
      carries no legal meaning, and whether the wire name should instead
      read "sufficient" is an open editorial question for -01 -- the
      semantics are fixed.</t>
      <section anchor="replay-det">
        <name>Replay determinism, precisely</name>
        <t>The replay digest is the canonical digest (JCS-style, I-JSON
        subset) of exactly three inputs: the policy object as supplied;
        the ordered list of NORMALIZED EVIDENCE FACTS; and the
        evaluation time. This composite is then bound to the graph
        digest. A normalized evidence fact carries, per node and
        nothing more: type, label, verified (boolean), the action
        digest the artifact itself attests, outcome (if the artifact
        carries one), revoked (boolean), age in seconds relative to the
        evaluation time, the derived staleness boolean, and whether the
        policy required a revocation check for that type. Raw artifact
        bytes, network state, and clock reads are excluded by
        construction; two evaluators disagreeing on a replay digest are
        by definition evaluating different inputs.</t>
        <t>Failure semantics are fixed, not implementation-defined. A
        node whose type has no registered verifier, whose inline
        artifact does not hash to its node id, or whose verifier throws
        yields verified=false and the bundle cannot reach admissible
        (unverifiable-class failures). A node REFERENCED but not
        disclosed (no artifact bytes available) contributes a fact with
        verified=false: if the policy's requirement needed that type,
        the verdict is missing_evidence -- the evidence may exist but
        was not presented; nothing about the graph lied. By contrast a
        CLAIMED edge the source artifact's bytes do not back is a lie
        about the evidence and forces unverifiable regardless of what
        else verified. The distinction is deliberate: absence degrades
        to "not enough", deception degrades to "not trustable".</t>
      </section>
    </section>
    <section anchor="result">
      <name>The Reliance Result (EP-RELIANCE-RESULT-v1)</name>
      <t>The verdict MAY be issued as a signed artifact carrying the
      verdict, reason codes, action digest, graph digest, policy digest
      and identifier, reliance purpose, replay digest, and evaluation
      time, signed by the relying party's verifier key. The signature
      adds ACCOUNTABILITY, never authority: any third party can
      recompute the replay digest rather than trust the signer. A
      consumer distinguishes VERIFIED (the signature holds over the
      canonical payload) from ACCEPTED (the consumer additionally
      trusts the signing verifier via an out-of-band pinned key); a
      reliance result from an unpinned verifier MUST NOT be accepted.
      Signed reliance results make reliance decisions themselves
      auditable: an institution can prove, later, which policy it
      applied to which evidence before it acted.</t>
    </section>
    <section anchor="packs">
      <name>Policy Packs</name>
      <t>This document profiles six policy packs for concrete
      irreversible action classes: wire transfer, vendor bank-account
      change (a distinct-human quorum, not a single approver),
      credential rotation, production data deletion, regulated trade
      execution (post-hoc: the execution record must provably reference
      its authorization, and the record must be transparency-logged),
      and healthcare record export. A pack is a starting point the
      relying party adopts and owns: pinning its own trust anchors and
      tightening freshness to its risk appetite. No pack waives
      fail-closed behavior.</t>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>The presenter controls the graph; every defense in this
      document assumes it. Edges are claims verified against artifact
      bytes; the policy is never read from the graph; undisclosed
      required nodes fail closed; a lying edge poisons the verdict;
      verdict precedence never degrades toward admissibility; and the
      replay digest makes every decision recomputable. What this layer
      does NOT do is equally load-bearing: a verdict of admissible is
      evidence that a bundle met a stated policy at a stated time; it
      is not a guarantee the action was correct or safe, it does not
      adjudicate disputes, and it confers no authority beyond what the
      underlying artifacts carry. Each artifact class is verified under
      its own specification; this document inherits, and does not
      weaken, each one's trust model.</t>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions. Future versions may
      register the edge-relation and reason-code vocabularies.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8785.xml"/>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="I-D.schrock-ep-authorization-receipts" target="https://datatracker.ietf.org/doc/draft-schrock-ep-authorization-receipts/">
          <front>
            <title>Authorization Receipts for High-Risk Agent Actions</title>
            <author fullname="Iman Schrock"><organization>EMILIA Protocol, Inc.</organization></author>
            <date year="2026" month="July"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-schrock-ep-authorization-receipts-05"/>
        </reference>
        <reference anchor="I-D.schrock-ep-authorization-evidence-chain" target="https://datatracker.ietf.org/doc/draft-schrock-ep-authorization-evidence-chain/">
          <front>
            <title>Authorization Evidence Chains: Composing Heterogeneous Agent-Authorization Receipts (EP-AEC)</title>
            <author fullname="Iman Schrock"><organization>EMILIA Protocol, Inc.</organization></author>
            <date year="2026" month="July"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-schrock-ep-authorization-evidence-chain-01"/>
        </reference>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9334.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9635.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9711.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9943.xml"/>
      </references>
    </references>
    <section anchor="example">
      <name>Worked Example (Non-Normative)</name>
      <t>The following objects are a complete, verifiable vector
      produced by the reference implementation with a fixed test seed;
      the runnable form ships with the reference implementation
      (examples/evidence-graph/). Long lines are wrapped per the
      single-backslash strategy of RFC 8792. The graph carries three
      disclosed nodes for one wire-transfer action and one claimed edge
      (the permit provably references the authorization it permits);
      under the wire-transfer policy pack at evaluation time
      2026-07-02T12:03:00Z the verdict is admissible, and one hour
      later the same graph under the same policy is stale.</t>
      <t>The evidence graph:</t>
      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
 "@version": "EP-AEG-v1",
 "action_digest": "sha256:0911345840214f3319dcdad832c2d8d38f98e3\
ce74d952b182127c74ee19147a",
 "nodes": [
  {
   "id": "sha256:f086f356d62b8b682e97c006b2c748fbfba9f97a627d3bf\
5d6367d2c5a0aae12",
   "type": "authorization_receipt",
   "artifact": {
    "typ": "authorization_receipt",
    "action_digest": "sha256:0911345840214f3319dcdad832c2d8d38f9\
8e3ce74d952b182127c74ee19147a",
    "approver": "ops-lead@example.com",
    "issued_at": "2026-07-02T12:00:00Z"
   }
  },
  {
   "id": "sha256:0a588d34875e4f69e2b016a3f6e8bd1da7743e957688865\
bcf9f7fba50b408c3",
   "type": "policy_permit",
   "artifact": {
    "typ": "policy_permit",
    "action_digest": "sha256:0911345840214f3319dcdad832c2d8d38f9\
8e3ce74d952b182127c74ee19147a",
    "permits_receipt": "sha256:f086f356d62b8b682e97c006b2c748fbf\
ba9f97a627d3bf5d6367d2c5a0aae12",
    "decision": "allow",
    "issued_at": "2026-07-02T12:00:05Z"
   }
  },
  {
   "id": "sha256:9a16eb90dd1d7fa726195c0eceaa8e2f763ee12af33e3b4\
122f728ee67e51932",
   "type": "workload_identity",
   "artifact": {
    "typ": "workload_identity",
    "action_digest": "sha256:0911345840214f3319dcdad832c2d8d38f9\
8e3ce74d952b182127c74ee19147a",
    "spiffe_id": "spiffe://example.org/payments-agent",
    "issued_at": "2026-07-02T11:30:00Z"
   }
  }
 ],
 "edges": [
  {
   "from": "sha256:0a588d34875e4f69e2b016a3f6e8bd1da7743e9576888\
65bcf9f7fba50b408c3",
   "rel": "permits",
   "to": "sha256:f086f356d62b8b682e97c006b2c748fbfba9f97a627d3bf\
5d6367d2c5a0aae12"
  }
 ]
}
]]></sourcecode>
      <t>The relying-party policy (the wire-transfer policy pack):</t>
      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
 "policy_id": "ep:pack:wire-transfer:v1",
 "reliance_purpose": "money_movement",
 "action_family": "urn:ep:action:payments.wire_transfer",
 "requirement": "authorization_receipt AND policy_permit AND wor\
kload_identity",
 "freshness_sec": {
  "authorization_receipt": 300,
  "policy_permit": 600,
  "workload_identity": 3600
 },
 "revocation_required": [
  "authorization_receipt"
 ],
 "required_edges": [
  {
   "from_type": "policy_permit",
   "rel": "permits",
   "to_type": "authorization_receipt"
  }
 ],
 "trust_anchor_slots": [
  "authorization_receipt",
  "policy_permit"
 ]
}
]]></sourcecode>
      <t>The signed reliance result (Ed25519 over the canonical
      payload; the replay digest is recomputable from the graph and
      policy above):</t>
      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
 "payload": {
  "@version": "EP-RELIANCE-RESULT-v1",
  "verdict": "admissible",
  "reasons": [],
  "action_digest": "sha256:0911345840214f3319dcdad832c2d8d38f98e\
3ce74d952b182127c74ee19147a",
  "graph_digest": "sha256:c29e2f1e66a5e617d4432ecc2d77fa0b2e9fa6\
111106e39368602e4539f0d4e5",
  "policy_digest": "sha256:76210f17d0592189a15104ede6045af8a96e4\
79f8b15a6053291b2cfd684dda9",
  "policy_id": "ep:pack:wire-transfer:v1",
  "reliance_purpose": "money_movement",
  "replay_digest": "sha256:8b540fadbd7b2e0ba5fc979b2b0bad005712a\
e83ed6a80f7b72173f1eacedafa",
  "evaluated_at": "2026-07-02T12:03:00Z"
 },
 "sig": "DknmC2Rj29d2ck-EJk-ZYV-9MPw8rxvJj-9U5kQTP1LCUs4JVsqlFN5\
03wDjt-A2p25fgDDVXHSStEuevHn1CA",
 "verifier_key": "MCowBQYDK2VwAyEA0EqyMnQrtKs6E2i9RhXk5tAiSrcaAW\
uvhSCjMsl3hzc"
}
]]></sourcecode>
    </section>
    <section anchor="impl">
      <name>Implementation Status</name>
      <t>A reference implementation (graph evaluation, policy replay,
      signed reliance results, and all six policy packs) is published
      under Apache-2.0 in the EMILIA Protocol repository, with a test
      suite covering the fail-closed invariants described here,
      including disclosure-independent graph identity, unbacked-edge
      poisoning, required-edge stripping, freshness degradation, and
      replay determinism. It builds on the same codebase's
      authorization-receipt, quorum, evidence-chain, and admissibility
      layers.</t>
    </section>
    <section anchor="ack" numbered="false">
      <name>Acknowledgments</name>
      <t>The composition seam this document builds on was materially
      sharpened by Songbo Bu's review of the digest bindings between
      the human-authorization and action-record layers, and by his
      independent execution and verification of the published EP
      artifacts against a pinned commit, reported to the SECDISPATCH
      list on 23 June 2026. The comparative, claim-disciplined framing
      of the surrounding landscape owes much to the authorization-
      evidence survey maintained by Mohamad Khalil-Yossif.
      Acknowledgment implies no endorsement of this document.</t>
    </section>
  </back>
</rfc>
