Internet-Draft Agent Discovery Corroboration July 2026
Chandra Expires 5 January 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-chandra-agent-registry-corroboration-00
Published:
Intended Status:
Standards Track
Expires:
Author:
S. Chandra
Stellarminds.ai

Multi-Source Corroboration for AI Agent Discovery

Abstract

AI agents are discovered and identified through independent sources — registries, name services, DID methods, catalogs. A single source can misrepresent an agent by omission (withholding a record it holds) or equivocation (serving different answers to different observers); no signature on a served artifact defends against either. This document specifies a corroboration procedure: how one source's claim about one agent, observed from one network vantage, is classified; how a claim is reduced to a comparable view; how claims are diffed into findings with deterministic attribution; how legitimate propagation delay is distinguished from persistent disagreement; and a signed Corroboration Record emitted on every sweep — agreement included — that other evidence formats can bind by digest. The procedure is source-, format-, and layer-agnostic, requires no cooperation from or modification of any source, and is verifiable from recorded bytes.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 5 January 2027.

Table of Contents

1. Introduction

An artifact served by a discovery source can be self-certifying: signed such that any consumer verifies its content offline. Self-certification defeats tampering. It cannot, in principle, defeat two other misbehaviors available to any source: omission (a withheld artifact has no signature to check) and equivocation (two inconsistent artifacts served to different observers are each individually valid). Both require a structurally different defense — comparison of independent observations — with its own failure modes and its own evidence.

This document specifies that comparison. It normatively fixes the decision procedure — claim classification (Section 4), the view contract (Section 5), the diff (Section 6), the confirmation discipline (Section 7), the self-description mechanism (Section 8), and the Corroboration Record (Section 9) — and treats the byte-level fetch per source as an injectable implementation detail, because interoperability lives in the comparison and the record, not in any source's wire format.

The procedure serves any layer at which a middleman answers questions about an agent: discovery (which endpoint), identity (which key), capability (which functions), and evidence (which records exist). Section 10 gives the two reference layer instantiations.

2. Conventions and Definitions

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 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Source: Anything that answers "what do you have for agent X?" — a registry, a name service, a DID method, a catalog, an evidence store.

Vantage: A network perspective from which a source is observed. One source MAY be observed from multiple vantages; vantage is part of a claim's identity.

Watch set: The set of canonical agent identifiers a consumer corroborates.

Claim: One source's answer about one agent as observed from one vantage at one instant, classified present, absent, or error (Section 4), carrying an observed_at timestamp.

View: The comparable reduction of a present claim: named string fields (Section 5).

Resolver: The per-source adapter mapping a canonical agent identifier to a classified claim (Section 4), applying that source's native verification.

Sweep: One corroboration cycle: every watch-set identifier resolved against every (source, vantage), diffed, and recorded.

Finding: One detected disagreement: {kind, agent_id, confirmation, detail} (Section 6).

Corroboration Record: The signed, content-addressed result of one sweep for one subject (Section 9).

Self-Description: An agent-signed bundle of sequence number, aliases, and service endpoints (Section 8).

CORR-DIGEST: lowercase-hex(SHA-256(JCS(v))), the SHA-256 of the RFC 8785 [RFC8785] JSON Canonicalization Scheme serialization of a value. All digests in this document use this construction. Values in digest-bearing fields MUST NOT be JSON floating-point numbers.

3. Claim Model

The unit of observation is the tuple (source, vantage, agent, observed_at). Vantage MUST be preserved as a distinct axis and MUST NOT be encoded by treating each vantage as an independent source: intra-source disagreement across vantages attributes a different misbehavior (equivocation by that source) than inter-source disagreement, and collapsing the axes destroys the attribution (Section 6.3).

A sweep with fewer than two present-or-absent claims for a subject has nothing to corroborate; its verdict is INSUFFICIENT (Section 9), and an implementation MUST NOT report agreement in that case.

4. Classifying One Claim

For a source S, vantage V, and agent A, a resolver MUST classify the outcome as exactly one of:

A resolver MUST NOT raise; failures are error claims. An error claim MUST be excluded from the diff entirely. This rule is central: a source that failed to answer has asserted nothing and MUST NOT be treated as claiming absence — otherwise every transient fault becomes a false omission finding.

5. The View Contract

A present claim MUST be reduced to a view: a mapping of field names to string values or null. A null value MUST NOT participate in the diff: an unverifiable or missing field is not a disagreement.

Fields whose values are compared as strings MUST be canonicalized by the layer before entering the view, such that two references to the same resource compare equal. For URI-valued fields (e.g., endpoints), implementations MUST apply syntax-based normalization per RFC 3986 [RFC3986] Section 6 (case of scheme and host, default ports, empty path) before comparison. For key-valued fields, the multibase did:key form is the comparison encoding.

Where a field carries its own proof (a signed record's DID, a key), the resolver MUST populate it only from a successfully verified artifact whose subject binds to the outer agent identifier; on any verification failure the field is null. A verifier MUST NOT allow an unverified value to produce a divergence finding against a verified one (the no-laundering rule).

6. The Diff

Input: the claims of one sweep for one agent. The diff MUST be pure — deterministic ordering, no I/O, no exceptions — and MUST derive findings as follows. One agent MAY yield multiple simultaneous findings.

6.1. omission

Emit an omission finding iff the agent is present on at least one source and absent on at least one other source. Both sides MUST be positive claims; error claims contribute to neither. Detail: {present_on, missing_from} as sorted lists of source labels.

6.2. Field Divergence

For each field name appearing in any present view, collect the non-null values keyed by (source, vantage). Emit a finding of kind equal to the field name iff more than one distinct value appears across sources (using, per source, the value agreed by its vantages; see Section 6.3 when they disagree). Detail: {field, values} where values maps source labels to values.

6.3. source_equivocation

For each source observed from more than one vantage, if that source's vantages yield differing non-null values for any field, emit a source_equivocation finding attributing that source. Detail: {source, field, values} where values maps vantage labels to values. A source under source_equivocation for a field contributes no single agreed value to the Section 6.2 comparison for that field; its per-vantage values are carried in the record for audit.

7. Observation Time and Confirmation

Sources propagate updates asynchronously; a legitimate change is served inconsistently for a bounded window. Every claim MUST carry observed_at. Every finding MUST carry a confirmation state:

The staleness window is deployment configuration derived from the sources' propagation characteristics (TTLs, sync intervals). A verifier evaluates confirmation deterministically from the recorded timestamps and the window recorded in the Corroboration Record; no external clock is consulted. Consumers SHOULD treat suspected findings as monitoring signals and confirmed findings as evidence.

8. The Self-Description

Corroboration requires knowing each source's name for the same agent (identity correspondence). This document defines an OPTIONAL agent-signed bundle that makes the correspondence verifiable rather than configured:

{
  "version": "self-description/0.1",
  "subject": "did:key:z6Mk...",
  "seq": 7,
  "aliases": { "<source-label-or-namespace>": "<name>", ... },
  "endpoints": [ "<uri>", ... ],
  "signature": "<base64 Ed25519 over JCS of all other members>"
}

Rules:

  1. The signature MUST verify against the key encoded in subject (offline; did:key per its method specification [DIDKEY]). On failure the description contributes nothing and the consumer falls back to caller-supplied correspondence. A fallback MUST NOT be silently overridden by an unverifiable description.

  2. Supersession. seq is a monotonically increasing integer. Among validly signed descriptions for one subject, the highest seq is authoritative. A source serving a description with seq lower than one the consumer has already verified is serving superseded material; this SHOULD be reported as a finding of kind stale_description attributing that source.

  3. Agent equivocation. Two validly signed descriptions for one subject with equal seq and differing JCS bytes MUST be reported as a finding of kind agent_equivocation. This indicates key compromise or a misbehaving agent and is not attributable to any source.

  4. Distribution. The description SHOULD be obtainable from each participating source and MUST, when so distributed, be corroborated as its own layer under this procedure (view: {seq, aliases_digest, endpoints_digest}), so that omission or replay of the description by a source is an ordinary finding.

  5. Verify-back. A record fetched via an alias asserted in a description MUST bind to the same subject key to contribute a claim; a record that does not bind back contributes no claim and MUST NOT produce a divergence finding (Section 5's no-laundering rule extended to correspondence).

The bundle is deliberately the minimal offline-verifiable profile of DID Core's [DIDCORE] alsoKnownAs and service constructs; implementations integrating richer self-descriptions (e.g., AgentFacts) MAY derive this bundle from them.

9. The Corroboration Record

An implementation MUST emit a Corroboration Record for every (sweep, subject) pair, whatever the verdictAGREE, DIVERGENT, or INSUFFICIENT. A corroboration trail recording only disagreements cannot prove its checks ran; the agreement record is the positive attestation downstream consumers bind.

{
  "version": "corroboration/0.1",
  "record_id": "<CORR-DIGEST of the object minus these two fields>",
  "subject": { "agent_id": "<id>", "did": "<did:key or null>" },
  "observed_at": "<RFC 3339 UTC, Z suffix>",
  "staleness_window_s": <integer>,
  "verdict": "AGREE" | "DIVERGENT" | "INSUFFICIENT",
  "claims": [
    { "source": "<label>", "vantage": "<label or null>",
      "status": "present" | "absent" | "error",
      "view": { "<field>": "<value or null>", ... } | null,
      "outcome": "<resolver outcome string>" }
  ],
  "findings": [
    { "kind": "<see Section 11>", "agent_id": "<id>",
      "confirmation": "suspected" | "confirmed",
      "detail": { ... } }
  ],
  "sweeper": "did:key:z6Mk...",
  "signature": "<base64 Ed25519 over JCS of all other members>"
}

Rules:

  1. record_id MUST equal the CORR-DIGEST of the record minus record_id and signature. A verifier MUST recompute and compare. observed_at is an RFC 3339 [RFC3339] UTC timestamp with a Z suffix.

  2. The signature MUST verify against sweeper. Self-attestation by the sweeping party is the base tier; a record MAY additionally be registered with an append-only transparency service (e.g., a SCITT Transparency Service [SCITT]), in which case a consumer MUST NOT report the anchored tier without verifying an inclusion proof against a log key it trusts.

  3. All monetary, count, and window values are exact integers or decimal strings; floating-point values MUST NOT appear.

  4. claims MUST include error-status entries (excluded from the diff, preserved for audit).

  5. A consumer binding a Corroboration Record from another evidence format SHOULD bind record_id and SHOULD state the verdict it relied upon.

10. Reference Layer Instantiations

Discovery — view {endpoint, did}. Resolvers: a by-id HTTP registry resolver (GET {base}/api/agents/{id}, path injectable); a two-hop index resolver (resolve a locator to {registry_url, identifier}, then fetch the record; a missing or empty hop field is error, a not-found at either hop is absent). The did field is populated only per Section 5's verified-field rule, from a signed record verified offline against its embedded did:key, with subject binding to the outer id.

Identity — view {key}, the agent's Ed25519 verification key in did:key multibase form (the encoding shared by did:key identifiers and Ed25519VerificationKey2020 [EDSIG2020] publicKeyMultibase, so keys compare as strings). Resolvers: did:key (offline; the self-certifying root), did:web (fetched from the method-specified document location; 404 is absent), and a Universal Resolver adapter. A method serving a different key than the root is a key divergence.

11. Finding Kinds and Extensibility

Kinds seeded by this document: omission, source_equivocation, stale_description, agent_equivocation, and one kind per view field name of a registered layer (this document seeds endpoint, did, key). Bare (un-prefixed) kind names are reserved for values seeded in this document and its successors; any party introducing a new kind MUST namespace it with a reverse-DNS or URI prefix. A consumer MUST treat unknown kinds as informational and MUST NOT reject a record for carrying one.

12. Conformance

A conforming implementation MUST reproduce, for the shared corpus of fixed per-claim inputs, the exact finding set of Section 6 and the exact verdicts of Section 9, including: agreement yields no findings and an AGREE record; present-beside-absent yields omission with correct attribution; distinct field values yield that field's kind; an error claim is excluded and creates no omission; a positive soft-404 is absent; vantage disagreement within one source yields source_equivocation and withholds that source from the cross-source field comparison; one subject may carry multiple simultaneous findings; and every sweep yields a record whose record_id recomputes. The corpus is view-agnostic and reused by every layer.

13. Security Considerations

Independence. Corroboration among k sources is worth exactly the independence among them. Sources sharing an upstream feed, an operator, or an incentive corroborate each other's misinformation by construction. This procedure records which sources agreed, enabling diversity-weighted consumption; it cannot manufacture diversity. Deployments SHOULD select sources with distinct operational and data lineage and SHOULD disclose known dependencies.

Residual equivocation. Cross-vantage comparison detects per-network-path splits. It cannot detect a source lying identically to all of one consumer's vantages while answering other consumers differently; that residual requires witnessed, append-only transparency over served answers ([RFC6962], [RFC9162], [CONIKS]), out of scope here. The Corroboration Record is forward-compatible with such logs (a witnessed history of records).

Watch-set bootstrap. A consumer cannot detect omission of an agent it never watched; a watch set enumerated from a single source inherits that source's omissions. Watch-set construction SHOULD draw on multiple sources.

Sweeper honesty. A record attests the sweep's recorded observations, not the sweeper's honesty; a dishonest sweeper can sign a fiction. Anchoring bounds timing and prevents silent substitution; consumers with high assurance requirements SHOULD corroborate the corroborator — multiple independent sweepers over the same watch set — which this procedure supports without modification (sweep records are themselves views to diff).

Staleness abuse. An attacker aware of the staleness window can rotate lies faster than confirmation. suspected findings therefore MUST be preserved in records even when never confirmed; a pattern of unconfirmed, short-lived divergences from one source is itself signal, and its evaluation is consumer policy.

Self-description replay and squatting. Addressed structurally in Section 8 (supersession, corroborated distribution, verify-back); implementations MUST NOT skip the verify-back rule, which is the sole defense against alias squatting manufacturing false divergences.

Privacy. A watch set reveals the sweeping party's interests to every queried source; records reveal them to every consumer. Deployments handling sensitive watch sets SHOULD consider query padding and record-level access control; both are out of scope.

14. IANA Considerations

This document requests no IANA actions. The finding-kind vocabulary is governed by the namespacing convention of Section 11; the record and self-description version strings are governed by this document and its successors. A future revision MAY register a media type for the Corroboration Record (candidate: application/corroboration-record+json) once transport contexts warrant it.

15. References

15.1. Normative References

[DIDCORE]
W3C, "Decentralized Identifiers (DIDs) v1.0", , <https://www.w3.org/TR/did-core/>.
[DIDKEY]
W3C Credentials Community Group, "The did:key Method", n.d., <https://w3c-ccg.github.io/did-method-key/>.
[EDSIG2020]
Sporny, M., "Ed25519Signature2020", n.d., <https://w3c-ccg.github.io/lds-ed25519-2020/>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC3339]
Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, , <https://www.rfc-editor.org/rfc/rfc3339>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/rfc/rfc3986>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC8785]
Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, , <https://www.rfc-editor.org/rfc/rfc8785>.

15.2. Informative References

[ANSV2]
Narajala, V. and M. Courtney, "Agent Name Service v2 (ANS): A Domain-Anchored Trust Layer for Autonomous AI Agent Identity", , <https://datatracker.ietf.org/doc/draft-narajala-courtney-ansv2/>.
[CAPSULE]
Mih, S., "An Agent Action Capsule Profile for SCITT", , <https://datatracker.ietf.org/doc/draft-mih-scitt-agent-action-capsule/>.
[CONIKS]
Melara, M., Blankstein, A., Bonneau, J., Felten, E., and M. Freedman, "CONIKS: Bringing Key Transparency to End Users", USENIX Security 2015, , <https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/melara>.
[MPIC]
CA/Browser Forum, "Multi-Perspective Issuance Corroboration (Baseline Requirements amendment)", n.d., <https://cabforum.org/>.
[RFC6962]
Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, DOI 10.17487/RFC6962, , <https://www.rfc-editor.org/rfc/rfc6962>.
[RFC9162]
Laurie, B., Messeri, E., and R. Stradling, "Certificate Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162, , <https://www.rfc-editor.org/rfc/rfc9162>.
[SCITT]
Birkholz, H., "An Architecture for Trustworthy and Transparent Digital Supply Chains (SCITT)", n.d., <https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/>.

Appendix A. Mapping to the Reference Implementation

Every normative element of this document is implemented in the reference implementation, split across two packages: the source-agnostic sm-resolver kernel (the claim model of Section 3, the view contract of Section 5, the diff of Section 6, and the confirmation discipline of Section 7, producing an unsigned sweep result with the verdict of Section 9) and sm-divergence built on it (the reference discovery and identity layers of Section 10, the agent self-description of Section 8, and the signing that seals a sweep result into the Corroboration Record of Section 9). The present/absent/error classification (Section 4), the view contract (Section 5), and the diff (Section 6) are the kernel's stable core; the vantage axis and source_equivocation (Sections 3, 6.3), observation time and confirmation (Section 7), the self-description schema and hardening (Section 8), and the Corroboration Record emitted on every verdict (Section 9) are all present and covered by the conformance corpus.

The reference implementation is available as open-source software (MIT License) at https://github.com/Sharathvc23/sm-divergence and https://github.com/Sharathvc23/sm-resolver, and is published on PyPI as sm-divergence and sm-resolver. The companion informative essay is "The Quilt That Checks Itself" (Stellarminds.ai / Project NANDA research).

Author's Address

Sharath Chandra
Stellarminds.ai
Richmond, California
United States of America