Network Working Group S. Chandra Internet-Draft Stellarminds.ai Intended status: Standards Track 30 October 2026 Expires: 3 May 2027 Multi-Source Corroboration for AI Agent Discovery draft-chandra-agent-registry-corroboration-02 Abstract AI agent discovery depends on sources such as registries, name services, DID methods, and catalogs. A valid signature on an artifact does not by itself show that a source has not withheld a record, or served inconsistent records to different observers. This document specifies a source- and format-agnostic procedure for corroborating independent observations of an agent. It defines claim classification, canonical views, deterministic disagreement findings, multi-vantage equivocation detection, propagation-delay confirmation, and signed Corroboration Records. The procedure produces verifiable evidence for every sweep, including agreement and insufficient- observation results. It composes with registry-assisted resolution of known subjects: a registry's renewable subject-to-target binding carries a sequence, and the procedure attributes a source serving a superseded binding rather than comparing it, so propagation lag is never reported as disagreement. 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 3 May 2027. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. Chandra Expires 3 May 2027 [Page 1] Internet-Draft Agent Discovery Corroboration October 2026 This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 3. Claim Model . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.1. Vantage Identifiers . . . . . . . . . . . . . . . . . . . 6 4. Classifying One Claim . . . . . . . . . . . . . . . . . . . . 7 4.1. Outcome . . . . . . . . . . . . . . . . . . . . . . . . . 8 5. The View Contract . . . . . . . . . . . . . . . . . . . . . . 9 6. The Diff . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6.1. omission . . . . . . . . . . . . . . . . . . . . . . . . 10 6.2. Field Divergence . . . . . . . . . . . . . . . . . . . . 11 6.3. source_equivocation . . . . . . . . . . . . . . . . . . . 11 6.4. Supersession . . . . . . . . . . . . . . . . . . . . . . 12 7. Observation Time and Confirmation . . . . . . . . . . . . . . 12 7.1. Finding Identity . . . . . . . . . . . . . . . . . . . . 13 7.2. The Staleness Window . . . . . . . . . . . . . . . . . . 14 8. The Self-Description . . . . . . . . . . . . . . . . . . . . 14 9. The Answer Scope . . . . . . . . . . . . . . . . . . . . . . 15 9.1. The Bundle . . . . . . . . . . . . . . . . . . . . . . . 15 9.2. Verification . . . . . . . . . . . . . . . . . . . . . . 16 9.3. Application . . . . . . . . . . . . . . . . . . . . . . . 17 9.4. Annotation, Not Absolution . . . . . . . . . . . . . . . 17 9.5. scope_violation . . . . . . . . . . . . . . . . . . . . . 17 10. The Corroboration Record . . . . . . . . . . . . . . . . . . 19 11. Reference Layer Instantiations . . . . . . . . . . . . . . . 21 12. Relationship to Registry-Assisted Resolution of Known Subjects . . . . . . . . . . . . . . . . . . . . . . . . 23 13. Finding Kinds and Extensibility . . . . . . . . . . . . . . . 24 14. Conformance . . . . . . . . . . . . . . . . . . . . . . . . . 25 15. Security Considerations . . . . . . . . . . . . . . . . . . . 27 16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 17. References . . . . . . . . . . . . . . . . . . . . . . . . . 29 17.1. Normative References . . . . . . . . . . . . . . . . . . 29 17.2. Informative References . . . . . . . . . . . . . . . . . 30 Appendix A. Changes from -01 . . . . . . . . . . . . . . . . . . 32 Appendix B. Changes from -00 . . . . . . . . . . . . . . . . . . 33 Appendix C. Mapping to the Reference Implementation . . . . . . 36 Appendix D. Related Work . . . . . . . . . . . . . . . . . . . . 36 Chandra Expires 3 May 2027 [Page 2] Internet-Draft Agent Discovery Corroboration October 2026 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 37 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 37 1. Introduction An artifact served by a discovery source can be self-certifying: it can be signed such that a consumer verifies its content offline against an expected identity or key. Self-certification detects tampering with that artifact. It cannot, in principle, prevent two other behaviors available to any source: *omission*, in which a source withholds an artifact and there is therefore no artifact signature to verify; and *equivocation*, in which a source serves two inconsistent artifacts to different observers, each individually valid. Both require a structurally different defense: comparison of independent observations, with its own failure modes and evidence. This document specifies that comparison. It normatively fixes the decision procedure (claim classification in Section 4, the view contract in Section 5, the diff in Section 6, the confirmation discipline in Section 7, the self-description mechanism in Section 8, the Answer Scope in Section 9, and the Corroboration Record in Section 10), 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. Not every difference between two sources is misbehavior. A source that is subject to a data-residency obligation may serve a different endpoint by design, and a procedure that reports every such difference as equivocation fires on normal operation. Section 9 admits this without conceding anything: a source may declare, in advance, an axis a third party can independently occupy along which it varies a field. A declaration so made *annotates* a finding and never withdraws it, the disagreement still stands and the verdict is unchanged, while a source that varies contrary to its own declaration earns a stronger finding than one that never declared at all. 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 11 gives the two reference layer instantiations. Discovery is increasingly specified as _resolution_: a discovering entity that already knows a Subject Identity obtains, from one discovery mechanism it selected, the minimum information needed to continue, together with integrity, authority, freshness and revocation information [RAR] [DAWN-CHARTER]. Resolution is one source's answer. This document is what a verifier does when it holds two of them. The two are complementary and Section 12 states the Chandra Expires 3 May 2027 [Page 3] Internet-Draft Agent Discovery Corroboration October 2026 relationship: resolution defines the shape and lifecycle of a single binding, corroboration defines the comparison across sources and the record of it, and neither evaluates trust. 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. In DAWN terms [DAWN-TERMINOLOGY] a source is a discovery mechanism, or a registrar's resolution surface, that returns discovery information about a named entity; the agent is the discovered entity and the corroborator is a discovering entity acting as an auditor. *Source label:* The identifier under which a source appears in claims, findings and records. A label MUST be a URI [RFC3986], MUST be stable for the lifetime of the source, and MUST be unique within the deployment that produced the record. Labels are compared by exact octet equality. An implementation MUST NOT normalize a label and MUST NOT infer that two labels denote the same source. The endpoint canonicalization of Section 5 applies to view _values_, never to labels: normalizing a label would let one source's identity merge with another's, which is the failure a corroborator exists to detect. *This document defines no global source-identity system.* A label is meaningful within the deployment that recorded it, and two deployments intending to compare records MUST agree on labels out of band. Where a source is served over HTTP the URI it is served from is the natural label, and the one an operator can demonstrate control of (Section 9.2); where it is not, any stable URI serves. No claim of global uniqueness is made or implied. *Vantage:* The observation context under which a source is observed: the conditions the claim was obtained under, not the observing instance. Two sweeps of one source from two hosts in the same context bear the same vantage. One source MAY be observed from multiple vantages; vantage is part of a claim's identity. Identifiers are constrained by Section 3.1. *Answer Scope:* A source-signed bundle declaring, in advance, which fields that source varies and along which vantage class (Section 9). Chandra Expires 3 May 2027 [Page 4] Internet-Draft Agent Discovery Corroboration October 2026 *Watch set:* The set of canonical agent identifiers a consumer corroborates. *Claim:* One source's answer about one agent as observed from one vantage during one sweep, classified present, absent, or error (Section 4). A claim's observation time is the sweep's observed_at (Section 7). *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 10). *Self-Description:* An agent-signed bundle of sequence number, aliases, and service endpoints (Section 8). *Binding:* A source's subject-to-target association issued as a renewable lease [RAR]: a sequence that increases, within one *authority scope*, whenever the target, publisher, ownership state or authority evidence changes, together with validity bounds and revocation information. The authority scope is the issuer that validated the subject for that binding. Sequences are comparable only within one scope. A binding's sequence is a different clock from the self-description seq of Section 8: the first is set by the issuer that bound the subject to a target, the second by the subject. *CORR-DIGEST:* The lowercase hexadecimal encoding of SHA-256 applied to the UTF-8 octets 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. Chandra Expires 3 May 2027 [Page 5] Internet-Draft Agent Discovery Corroboration October 2026 3. Claim Model The unit of observation is the tuple *(source, vantage, agent)* within one sweep, and the sweep carries the observation time (Section 7). 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 10), and an implementation MUST NOT report agreement in that case. 3.1. Vantage Identifiers A vantage identifier MUST be either null or a string of the form class ":" value, where class names the context dimension and value names a point on that dimension. Each component MUST match the regular expression [a-z0-9](?:[a-z0-9-]*[a-z0-9])?. Identifiers are compared by exact octet equality; an implementation MUST NOT parse, order, normalize, or infer containment relationships among identifier values. This document defines two initial occupiable classes. Both take their value space from an external registry, which is what makes shared denotation (below) a fact rather than an agreement between sweepers: * *region*: the value MUST be an ISO 3166-1 alpha-2 code [ISO3166], lowercased. region:de, region:us, and the exceptionally reserved region:eu are well-formed. * *asn*: the value MUST be the string as followed by the decimal representation of a 32-bit Autonomous System Number [RFC6793], with no leading zeros: asn:as64500. A class outside this set MUST NOT be used unless the deployments comparing observations have agreed on both its meaning and its value space; absent that agreement the requirements below cannot be met and the vantage MUST be null. Comparison scoped to a vantage (Section 6.2) is sound only if independently operated sweepers assign the same identifier to the same context. Accordingly: Chandra Expires 3 May 2027 [Page 6] Internet-Draft Agent Discovery Corroboration October 2026 * *Shared denotation.* Two claims bearing the same identifier MUST denote the same observation context, whichever source or sweeper produced them. A sweeper MUST NOT mint a private meaning for a class defined elsewhere. * *Occupiability.* A class MUST be one a third party can construct and observe from independently. region and asn are occupiable: a verifier can place itself in that region or on that network and repeat the observation. Attributes of the caller _relationship_ rather than of the observation, caller identity, tenant, subscription tier, authorization level, are NOT occupiable and MUST NOT be encoded as a vantage. *This rule is central:* a variation on a non-occupiable attribute cannot be independently checked, so a corroborator that credited a declaration of one would be reporting the source's own assertion back as evidence. * *Non-overlap.* Within one sweep the vantages a sweeper uses MUST NOT overlap: no context may be denoted by two identifiers, and no identifier by two contexts. A sweeper that cannot guarantee this MUST use null. * *Cardinality.* A class MUST have a small, enumerable value set. A high-cardinality dimension partitions observations until nothing is compared against anything, degrading corroboration to silence while appearing to function. The null vantage asserts no context. It is not a comparable identifier and MUST NOT be compared for equality against a non-null one as though it named one. It is correct for a single-vantage sweeper and REQUIRED where the obligations above cannot be met, declining to name a context is always sound, whereas naming one wrongly is not. 4. Classifying One Claim For a source S, vantage V, and agent A, a resolver MUST classify the outcome as exactly one of: * *present*: S served a claim for A, reduced to a view (Section 5). * *absent*: S positively asserts A is unknown. Each resolver defines the positive-absence predicate for its source type; for HTTP sources a 404 MUST be classified absent, and a 200 whose body positively signals not-found SHOULD be classified absent. Non- normative examples of the latter include {"success": false} bodies and error strings containing "not found". Chandra Expires 3 May 2027 [Page 7] Internet-Draft Agent Discovery Corroboration October 2026 * *error*: any other outcome: connection failure, timeout, non- absence error status, unparseable body, or an answer that the resolver cannot map to a view. A resolver MUST return an error claim rather than propagate an unclassified failure to the diff procedure. 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. 4.1. Outcome Every claim carries an *outcome* alongside its status. status states whether the source made a claim; outcome states how that came about. It matters most for error, which the diff excludes entirely. A timeout, a persistently unreachable host, an explicit refusal, and a body that could not be read are different facts about a source, and a record that collapses them loses the difference: a pattern of refusals from one source is not the same signal as a pattern of timeouts. Values seeded by this document, bare: +==============+================================================+ | Value | Meaning | +==============+================================================+ | timeout | no answer within the deadline | +--------------+------------------------------------------------+ | unreachable | transport failed | +--------------+------------------------------------------------+ | refused | the source declined to answer | +--------------+------------------------------------------------+ | unparseable | answered; the body could not be read | +--------------+------------------------------------------------+ | unverifiable | answered; the source's own verification failed | +--------------+------------------------------------------------+ | expired | answered; the binding served is past its | | | validity bound and MUST be treated as stale | +--------------+------------------------------------------------+ | revoked | answered; the source itself marks the binding | | | revoked | +--------------+------------------------------------------------+ Table 1 Chandra Expires 3 May 2027 [Page 8] Internet-Draft Agent Discovery Corroboration October 2026 expired and revoked exist because a resolution profile requires that a binding past expiresAt, or revoked, MUST NOT be treated as current [RAR]; a resolver that honours that rule has an answer it may not use, which is an error claim, never an absent one, and the outcome records which. A present or absent claim MAY use its status as its outcome, which is the least specific honest answer. Bare names are reserved for values seeded in this document and its successors; any party introducing another MUST namespace it with a reverse-DNS or URI prefix, as for finding kinds (Section 13). A consumer MUST treat an unknown outcome as informational and MUST NOT reject a record for carrying one. *An outcome MUST NOT affect which claims enter the diff.* status alone decides that. Outcome is provenance, and were it to filter, a source could remove itself from comparison by describing itself. Only the resolver knows why a resolve ended as it did, so supplying an outcome is the resolver's responsibility. A resolver that does not keeps its status as its outcome. 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 and two references to different resources do not. RFC 3986 [RFC3986] Section 6 names syntax-based normalization but leaves several choices to the implementer, and two conforming implementations that choose differently produce a false field divergence between honest sources. URI-valued fields MUST therefore be canonicalized as follows, which this document identifies as endpoint-normalization/0.1: * The scheme and host are lowercased. *The path is not.* A path MAY address distinct resources by case, so folding it would merge two endpoints. * The default port for the scheme is removed; any other port is retained. * An empty path becomes /, and dot segments are removed per RFC 3986 Section 5.2.4. Chandra Expires 3 May 2027 [Page 9] Internet-Draft Agent Discovery Corroboration October 2026 * Percent-encoding triplets are uppercased, and percent-encoded unreserved characters (RFC 3986 Section 2.3) are decoded. *Reserved characters remain encoded*: %2F is an encoded solidus, not a path separator, and decoding it would merge two endpoints. * The query is compared byte for byte. Its semantics belong to the origin server, and reordering or removing parameters would assert an equivalence this procedure cannot know holds. * The fragment is removed. It is not transmitted to the origin server and so cannot distinguish two endpoints as addresses. * Hostnames are compared in their A-label (punycode) form, and a trailing dot is removed. A value that is not a URI is compared unchanged. Guessing at a syntax the layer does not recognize is worse than comparing it literally. A view MAY additionally carry a *lease position*: the binding's sequence and authority scope (Section 2). The position is not a field; it MUST NOT be compared as a value and MUST NOT appear in values of any finding. It is read by the supersession rule of Section 6.4. The authority issuer likewise MUST NOT be a compared field: two sources validating the same subject through different issuers is the ordinary multi-registry case, and a disagreement between issuers is not a disagreement about the subject. 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. Chandra Expires 3 May 2027 [Page 10] Internet-Draft Agent Discovery Corroboration October 2026 6.2. Field Divergence For each field name appearing in any *current* present view (Section 6.4), collect the non-null values keyed by (source, vantage). Comparison is scoped to a *cohort*: the claims sharing one vantage identifier. 1. A source contributes a single value to the comparison for a field only when all non-null values that source produced for that field agree across its observed vantages. Such a source participates in every cohort. 2. If a source produced differing non-null values for a field across vantages and an applicable Answer Scope exists (Section 9.3), that source contributes its value separately to each cohort identified by the corresponding vantage. 3. If a source produced differing non-null values for a field across vantages and no applicable Answer Scope exists, that source contributes no value to the cross-source comparison for that field (Section 6.3). 4. Cohort keys are derived only from the vantages of sources for which an applicable Answer Scope authorizes per-vantage comparison for that field. If no such source exists, the diff MUST evaluate one unscoped cohort containing every eligible claim. Emit a finding of kind equal to the field name, once per cohort, iff more than one distinct value appears *across sources* within that cohort. 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. The finding is emitted whether or not the variation was declared (Section 9); its per-vantage values are carried in the record for audit. Absent an applicable Answer Scope, a source under source_equivocation for a field contributes no single agreed value to the Section 6.2 comparison for that field: a source that disagrees with itself cannot corroborate. Where an Answer Scope applies (Section 9.3), that withholding is *replaced, not waived*: the source's per-vantage Chandra Expires 3 May 2027 [Page 11] Internet-Draft Agent Discovery Corroboration October 2026 values enter the cohort comparison of Section 6.2 instead. *This rule is central:* withholding the source without replacing it would let a source that declares variation serve one vantage a forged value and be recorded AGREE, because nothing would remain to compare that value against, strictly worse than not honouring the declaration at all. 6.4. Supersession Before Sections 6.2 and 6.3 are evaluated, the present claims are partitioned by authority scope. Claims whose view carries no lease position are *current* in their own right. Within each scope the highest sequence observed is current; a claim whose sequence is lower is *superseded*. For each (source, scope) with a superseded claim, emit a stale_binding finding attributing that source. Detail: {source, scope, sequence, current_sequence, current_on}, where current_on lists the sources at the current sequence. A superseded claim MUST be withheld from Sections 6.2 and 6.3: a source serving yesterday's binding is behind, not disagreeing, and comparing its target against the current one would report propagation as tampering. A source that is current from one vantage and superseded from another is mid- propagation and MUST NOT be charged source_equivocation for that reason alone. A superseded claim remains present for Section 6.1 and remains decisive for the verdict (Section 10): the subject exists on that source. Equal sequences with differing values are the disagreement supersession exists to isolate, and MUST still yield a field finding. stale_binding is a finding: the verdict is DIVERGENT. A lagging source within the staleness window is suspected (Section 7); one still behind after it is confirmed, which is the replay and stale- cache condition the resolution profile's security considerations name [RAR]. What a confirmed stale binding is worth is the consumer's judgement, as for every finding. The identity of the finding (Section 7.1) is (source, scope), never the sequence numbers: a source that stays one step behind a moving current is one persistent condition. 7. Observation Time and Confirmation Sources propagate updates asynchronously; a legitimate change is served inconsistently for a bounded window. Every sweep MUST carry an observed_at timestamp, which is the observation time of every claim in that sweep; claims do not carry individual timestamps (Section 10). Every finding MUST carry a confirmation state: Chandra Expires 3 May 2027 [Page 12] Internet-Draft Agent Discovery Corroboration October 2026 * *suspected*: first observation of the disagreement. * *confirmed*: the disagreement was re-observed in a sweep whose observed_at exceeds the first observation by at least the deployment's configured *staleness window*. 7.1. Finding Identity Confirmation asks whether a finding observed now is the _same disagreement_ as one observed earlier. That comparison MUST use a stable identity, defined per finding kind: +=====================+===============================+ | Kind | Identity | +=====================+===============================+ | omission | present_on, missing_from | +---------------------+-------------------------------+ | source_equivocation | source, field | +---------------------+-------------------------------+ | scope_violation | source, field, declared_class | +---------------------+-------------------------------+ | stale_binding | source, scope | +---------------------+-------------------------------+ | a view field name | field, the participating | | | source labels, and the cohort | +---------------------+-------------------------------+ | any other kind | the whole detail | +---------------------+-------------------------------+ Table 2 *Observed values MUST NOT participate in the identity.* Values change while the same disagreement persists, and keying on them makes a source that rotates its answer produce a stream of unrelated findings, each restarting as suspected and never reaching confirmed. That is the staleness abuse of Section 15, made worse: the pattern does not accumulate under one identity either, so even the count of short-lived divergences from one source is diluted. *The cohort MUST participate* wherever the comparison was scoped (Section 6.2). The same sources can disagree differently in two contexts, and without the cohort one of those disagreements masks the other. *A kind this document does not seed MUST key on the whole detail.* Its shape is not defined here, so no part of it may be assumed stable, including a values member, which such a kind may use to mean something else entirely. Chandra Expires 3 May 2027 [Page 13] Internet-Draft Agent Discovery Corroboration October 2026 confirmation and the declaration state of Section 9.4 do not participate either. 7.2. The Staleness Window A deployment MUST configure exactly one staleness window, expressed in seconds, applied to every finding in every sweep it produces, and MUST record it in each Corroboration Record (Section 10). It is derived from the propagation characteristics of the sources swept (TTLs, sync intervals) and SHOULD be set from the slowest of them, since a window shorter than a source's real propagation time manufactures confirmed findings from ordinary delay. Per-source or per-pair windows are deliberately not provided: the record carries a single staleness_window_s, so a verifier re-deriving confirmation from recorded bytes has exactly one window to apply. 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": { "": "", ... }, "endpoints": [ "", ... ], "signature": "" } 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 the same subject, the description with the highest seq value is authoritative. A source serving a description whose seq value is lower than that of a description Chandra Expires 3 May 2027 [Page 14] Internet-Draft Agent Discovery Corroboration October 2026 the consumer has already verified for the same subject 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 Answer Scope A source may vary its answers for reasons that are not misbehaviour: data-residency obligations, regional infrastructure, jurisdictional routing. A procedure that reports every such variation as equivocation fires on normal operation, and a detector that fires on normal operation is switched off. This document therefore defines an OPTIONAL source-signed bundle by which an operator declares its variation *in advance*, so that an observed variation can be recorded as one the operator had already described. An Answer Scope declares an *axis*, never a mapping. "endpoint varies by region" is checkable: a verifier occupies another region and compares. "EU callers receive X" would be a promise about values, made by the party doing the varying, and a promise adds a label to a finding without adding any means to test it. *Declaration without commitment adds vocabulary, not detection.* 9.1. The Bundle Chandra Expires 3 May 2027 [Page 15] Internet-Draft Agent Discovery Corroboration October 2026 { "version": "answer-scope/0.1", "subject": "did:key:z6Mk...", "label": "", "seq": , "scopes": [ { "field": "", "vantage_class": "" } ], "signature": "" } seq is a monotonically increasing integer that the operator increments whenever it reissues the bundle; freshness is supersession by seq, so no external clock is required to order two bundles. subject identifies the operator's verification key, distinct from the agent key of Section 8: an agent self-description attests an agent about itself, while an Answer Scope attests an operator about its own registry. 9.2. Verification A verifier MUST reject a bundle unless all of the following hold. 1. The signature verifies against the key subject encodes. 2. label equals the label the bundle was retrieved from, by exact octet equality, with no normalization of scheme, case, port, or trailing path. *This rule is central:* a valid signature establishes that the holder of the subject key authored the bundle; it does not, by itself, establish control of any particular source label. Serving the bundle at the label is what supplies that evidence. Inferring equivalence between spellings would let one naming convention acquire authority over another. 3. Every vantage_class is occupiable (Section 3.1). A verifier MUST maintain an explicit set of classes it accepts and MUST reject any other; widening that set is a deliberate act. 4. Every field and vantage_class matches the token grammar of Section 3.1. Wildcards and catch-alls MUST be rejected at the token level, irrespective of the accepted class set, the permissive form of a declared-scope mechanism is what becomes its attack surface. 5. No field appears twice. Overlapping scopes would let an operator select, after the fact, whichever applies. Chandra Expires 3 May 2027 [Page 16] Internet-Draft Agent Discovery Corroboration October 2026 6. scopes carries no more entries than the verifier's configured maximum. An empty scopes list is well-formed and meaningful: the operator positively asserts that it does not vary. This is distinct from publishing nothing, which is ambiguous between "does not vary" and "does not implement this". A source that does not vary SHOULD publish an empty scope rather than remain silent. 9.3. Application An Answer Scope applies to a (source, field) for one sweep iff a verified scope from that source names that field, and *every* vantage at which that source produced a non-null value for that field lies on the declared vantage_class. A declaration on one axis says nothing about variation observed on another. Where it applies, exactly two things change, and an implementation MUST change nothing else: 1. The source_equivocation finding of Section 6.3 is annotated declared (Section 10), carrying the seq that was matched. 2. The withholding of Section 6.3 is replaced by cohort participation in Section 6.2. 9.4. Annotation, Not Absolution *A declaration annotates a finding; it MUST NOT withdraw one.* The finding is emitted, and the verdict of Section 10 is computed exactly as though no declaration existed. A corroborator reports what it observed and what the source had said it would do; whether an annotated divergence is acceptable is the consumer's judgement, and fusing that judgement into the procedure would make it wrong for every deployment whose policy differs. An implementation MUST record, in every annotated finding, which seq of the declaration was matched. Without it, a source retroactively legitimises past divergences by publishing a broader scope today. 9.5. scope_violation A source that varies a field contrary to an Answer Scope it _previously_ published, most plainly one whose scope asserted no variation, is not merely exhibiting an undeclared divergence. It has published a constraint and violated it. A corroborator MUST emit a scope_violation finding attributing that source. Detail: {source, field, declared_class, observed, declaration_version}. Chandra Expires 3 May 2027 [Page 17] Internet-Draft Agent Discovery Corroboration October 2026 *The temporal rule is not optional.* A corroborator MUST NOT emit scope_violation unless it can establish that the scope it evaluated was published _before_ the observation it contradicts. Section 9.4 prevents a source retroactively legitimizing a past divergence by publishing a broader scope; the same reasoning applies in the opposite direction, and with a different victim. Without the temporal rule, a narrower scope published after the fact, by the source under duress, or by anyone who can influence what a sweeper fetches, manufactures an accusation about an observation that did not violate anything at the time it was made. Establishing publication order requires a witnessed history of what a source published when, which this document places out of scope (Section 15); until a deployment has one, it MUST NOT emit this kind. A deployment that does have one records its evidence in the finding's detail under history_proof, so that the finding is independently auditable without this document standardizing any particular mechanism: "history_proof": { "type": "", "statement_digest": "", "proof": { ... mechanism-defined ... } } statement_digest MUST equal the scope_digest of the corresponding entry in answer_scopes (Section 10). That binding is what makes the envelope evidence rather than an assertion: a proof about some other scope is evidence about something else, however valid it is in its own terms. type MUST be namespaced with a reverse-DNS or URI prefix. This document seeds no mechanisms, so every value belongs to a third party and a bare name would claim a reservation that does not exist. A verifier that does not recognize type MUST treat the finding as though no history proof were present, and therefore MUST NOT rely on the scope_violation. Checking the envelope is not checking the proof. This is the strongest accusation the procedure makes, and it is available only because the declaration precedes the observation. An implementation that cannot demonstrate that ordering has not earned the accusation. Chandra Expires 3 May 2027 [Page 18] Internet-Draft Agent Discovery Corroboration October 2026 10. The Corroboration Record An implementation MUST emit a Corroboration Record for every (sweep, subject) pair, *whatever the verdict*, AGREE, 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.4", "alg": "EdDSA", "record_id": "", "subject": { "agent_id": "", "did": "" }, "observed_at": "", "staleness_window_s": , "verdict": "AGREE" | "DIVERGENT" | "INSUFFICIENT", "claims": [ { "source": "