Working draft for public review. Not a stable standard, IETF adoption, certification or production recommendation. Experimental profiles require explicit opt-in.

XCIM Protocol — Working Draft 02

Contents

eXplicit Consent-Identified Mail · WD-02 · 15 October 2026

Consolidated reading with Erratum E1 applied. The original WD-02 and its archive remain unchanged; document revision and wire versions are not incremented by this separately identified erratum.

1. Status and scope

This is a public working draft for implementation and review, not a stable standard, an IETF Internet-Draft, a certification program or a recommendation for production deployment. Its requirements define the intended behavior of implementations claiming this draft and the profiles they explicitly support. Publication does not imply external security review or interoperability between independently operated systems.

XCIM associates a recipient's purpose-specific communication authorization with an application, independently validated Identity Evidence and currently authorized sending infrastructure. A signed receipt records a historical decision. A receiver additionally evaluates current permission state, key and application/domain authority, evidence freshness and its own trust policy.

The protocol is independent of commercial products. No particular issuer brand, account, console, SDK, cloud provider, database, paid service or operator domain is required. An implementation report is informative evidence about one system, not a source of protocol authority. Product onboarding, billing, private list-evaluation APIs and deployment procedures are outside this document.

The uppercase requirement terms MUST, MUST NOT, SHOULD, SHOULD NOT and MAY carry the requirement strength described by BCP 14. Ordinary lowercase usage is descriptive. The core and selected profile together determine conformance; experimental profiles require explicit opt-in.

2. Version model and compatibility

Document revision, object wire version and identity profile are distinct identifiers:

Identifier Meaning in WD-02
WD-02 Editorial publication revision dated 2026-10-15
xcim_version: "0.1" Existing core objects and OIDC-01 receipts
oidc-01 / oidc_hosted_consent Draft OIDC issuance profile, receipt wire version 0.1
evp-01 / evp_hosted_consent Experimental EVP issuance profile, receipt wire version 0.2
xcim-evm-amoy-pilot-0.1 Experimental testnet publication profile; not a production trust root
issuer_metadata / issuer_accreditation wire 0.2 WD-02 capability and registry-neutral discovery contracts; not a migration of other core objects

The historical source document label “0.2” was an editorial label, not a blanket migration of every signed object to wire version 0.2. In this publication, the experimental EVP receipt explicitly uses wire version 0.2; surrounding 0.1 objects retain their own versions. A 0.1 proof envelope does not authorize accepting an otherwise unsupported 0.2 receipt inside it.

Implementations MUST dispatch using each signed object's exact version and object type and, for receipts, its issuance profile before applying its schema and semantic checks. They MUST reject unsupported combinations and unknown security-critical extensions, rather than guessing or falling back to a different profile. Supporting a schema union does not itself enable an experimental profile.

Existing signed receipts, manifests, log events, roots, timestamps and commitments MUST NOT be rewritten to match new terminology or schemas. Validators MUST retain the historical profile needed for accepted old evidence. A schema's canonical $id identifies its exact object family. The schema catalog and release manifest identify the published artifacts; new incompatible semantics require a new version or explicitly selected profile, not silent reinterpretation of signed bytes.

This draft consolidates the normative choices listed in its change record. It supersedes earlier narrative guidance where they differ for the same object/profile, but does not claim that an existing product implements every new requirement. Unchanged 0.1 schemas and fixtures remain available for historical validation.

3. Goals and non-goals

XCIM is intended to make permission evidence portable, application-specific, purpose-specific, revocable and independently checkable without a mandatory per-message request to a commercial issuer. Multiple issuers and local receiver policy are fundamental.

XCIM does not prove that a message is desirable, safe, lawful, deliverable or free of abuse. It does not establish mailbox existence or guarantee inbox placement. It does not replace SPF, DKIM, DMARC, ARC, authentication, unsubscribe mechanisms or ordinary abuse controls. Identity verification alone MUST NOT be interpreted as communication permission. Blockchain publication proves commitments and ordering under a chain policy, not the truth of the original identity or consent observation.

4. Roles and trust boundaries

An Identity Issuer and XCIM Consent Issuer are different roles even if an organization performs both. A receiver MUST select trusted issuers and key roles through explicit local policy or an authenticated trust-registry chain rooted in previously accepted authority. HTTPS discovery and a key advertised by an issuer do not establish initial trust. A self-declared independence label is not accreditation.

The Issuer Metadata 0.2 profile provides explicit capability advertisement for OIDC and EVP. Its accreditation reference is nullable and its registry URI is receiver-selected, not fixed to an operator. Historical metadata/accreditation 0.1 remain restricted legacy contracts; they MUST NOT be fabricated or silently widened to represent a different trust model. Capabilities are not trust, accreditation or proof that an experimental integration has passed external tests.

An issuer's receipt key, batch key, application key, identity-provider key and chain transaction signer have different authorities. Implementations MUST bind each operation to the permitted role and validity interval and MUST NOT treat key discovery as permission to substitute roles. The Amoy pilot requires separate receipt and batch pins. Key rotation, suspension and revocation require authenticated lifecycle information; lack of that information MUST NOT silently preserve a current positive result.

5. Identifiers, encodings and time

Core IDs are opaque typed identifiers with the prefixes urn:xcim:app:, urn:xcim:receipt:, urn:xcim:permission: and urn:xcim:issuer: as constrained by their object schemas. A receipt's issuer HTTPS URI and a log's issuer_id URN serve different roles; the trust configuration MUST bind them rather than treating arbitrary equal-looking names as equivalent.

All security-relevant identifiers and URI comparisons MUST use the normalization and exact matching defined by the selected profile. Discovery MUST require HTTPS, reject embedded credentials and apply SSRF defenses to DNS resolution, redirects and retrieved metadata. A received endpoint MUST NOT select a receiver's trust root.

Integers in signed core JSON are bounded by the interoperable safe-integer range ending at 9007199254740991. E1 fixes the text boundary: before numeric conversion or schema validation, each JSON number token MUST match -?(0|[1-9][0-9]*) and represent an integer in that safe range. Fractional or exponent tokens are forbidden even when a host parser would round or convert them to an integer: 1.0, 1e3, -0.0 and 1.0000000000000000001 MUST be rejected. This restriction does not apply to quoted strings. Epochs start at one. Hashes are 32 bytes encoded as unpadded base64url unless a selected profile explicitly defines another encoding. Amoy's core_content_sha256 and creation_code_sha256_hex are 64 lowercase hexadecimal characters; EVM ABI bytes32 values use the same hash bytes in hexadecimal with 0x. Decoders MUST reject invalid or non-canonical encodings and duplicate JSON members. Object schemas may impose further bounds.

Timestamps represent UTC instants. Producers SHOULD use an explicit Z suffix and MUST preserve the exact serialized values once signed. Experimental receipt 0.2 and Amoy publication require Z. Verifiers MUST validate temporal ordering and their declared clock-skew policy, not just string syntax. A timestamp rounded through database or UI precision MUST NOT replace a signed value.

Receipt issuance, consent acceptance, identity authentication and state snapshot time are distinct. Identity authentication MUST NOT follow consent acceptance, which MUST NOT follow receipt issuance. A validity end is exclusive: at or after expiry the object cannot establish current positive authority. A later download or new outer wrapper MUST NOT extend the lifetime of older authenticated state.

6. Cryptographic envelope

XCIM uses SHA-256 commitments, Ed25519 signatures and JCS canonical JSON. Except for the explicit legacy inline consent-manifest signature below, signed XCIM objects use JWS Flattened JSON Serialization:

{"protected":"<base64url JCS header>","payload":"<base64url JCS payload>","signature":"<base64url Ed25519 signature>"}

The protected header carries alg: "EdDSA", the authorized kid and the object-specific typ. Implementations MUST NOT accept unprotected security headers, algorithm substitution, b64=false, unknown critical extensions or detached semantics not defined by the selected profile. Base64url segments have no padding. The Ed25519 public key is 32 bytes and signature is 64 bytes.

The signing input is the ASCII bytes of protected, one ASCII dot and the ASCII bytes of payload. Ed25519 signs that input directly, without an additional application-level SHA-256 prehash. Protected and payload segments MUST decode to their already-canonical JCS bytes. A verifier MUST authenticate the signature with an authorized role-specific key and also validate schema, version, type and semantics.

A consent manifest 0.1 is the historical inline exception, not a JWS envelope and not a doubly signed object. Remove only vendor_signature from the manifest to obtain unsigned_manifest. Its signature is unpadded base64url of Ed25519(application_key, UTF8("XCIM-CONSENT-MANIFEST-SIGNATURE-0.1\0") || J(unsigned_manifest)). presentation.manifest_hash is ordinary SHA-256(J(full_manifest)), including the inline signature. The vendor_app_key_id selects the authorized application key. A receipt or batch MUST NOT use this exception. The media-type registry 0.2 identifies the inline serialization; its inherited +jcs spelling does not imply a JWS envelope.

JCS sorts object names by unsigned UTF-16 code units, recursively, not Unicode code points or locale. All strings MUST contain valid Unicode scalar values. The Python and Node fixture tools implement this safe-integer profile and reject unsupported numeric or Unicode inputs. Passing ASCII-only examples is not sufficient canonicalization evidence.

The E1 input gate operates on the original JSON text, not just the host-language value after a generic parser. Use the bundled strict_loads / strictLoads functions before canonicalization. JavaScript cannot distinguish the literals 1 and 1.0 after conversion to a Number; a serializer of an already constructed object cannot recover that distinction. The raw integer token -0 may be parsed but canonicalizes to 0. JWS protected/payload bytes still MUST already be canonical; this erratum does not authorize rewriting signed bytes or accepting a non-canonical signed -0. JSON Schema's mathematical integer validation is not a substitute for this lexical gate.

The media-type strings in the draft registry identify object contexts, not IANA registration claims. For receipts, typ is application/xcim-receipt+jcs; for batch manifests it is application/xcim-batch-manifest+jcs. The HTTP content type of an envelope need not equal its protected typ.

Domain-separated commitments are distinct from signatures. With H = SHA-256, J = JCS, || denoting byte concatenation and \0 denoting exactly one NUL byte:

receipt_commitment = H("XCIM-RECEIPT-0.1\0" || J(receipt_payload))
batch_manifest_hash = H("XCIM-BATCH-MANIFEST-0.1\0" || J(batch_payload))

These established domain tags MUST NOT be changed merely because a receipt uses an experimental version; the selected profile determines the exact formula. Hashing the outer JWS instead of the specified payload produces a different commitment and is not interchangeable. Encodings and all other object commitments are fixed by the schemas, published fixtures and selected publication profile.

7. Application and domain authority

The application, not its domain or OAuth client, is the primary identity. Application metadata and keys MUST bind an Application ID, application epoch and active application key. OIDC-01 additionally binds the OAuth client used for that identity flow; this does not make that client the identity root of every XCIM profile. EVP-01 does not require an OAuth client binding.

An application key proves control of application-signed integration messages; an HTTP 200, unbound challenge echo or vendor assertion is insufficient. Issuers MUST authenticate application requests and prevent a vendor from granting recipient consent or issuing issuer receipts through an application API.

Sender-domain authority uses the exact role names organizational, rfc5322_from, dkim_signing, envelope_from, link_domain and consent_presentation_delegate. A binding's active state, application epoch, domain epoch, roles and validity period MUST be checked for the role actually used. Abbreviated aliases MUST NOT be silently substituted. Domain control requires a fresh independently observed challenge; operator-supplied observation alone is not evidence of DNS control.

Domain transfer, suspension, expiry or application-key change MUST NOT carry permission across an unrelated owner or application epoch. Epochs are monotonic and signed history remains append-only. A receiver MUST verify current authority, not infer it solely from the domain names recorded in an old receipt.

8. Identity Evidence layer

The Identity Evidence layer is profile-neutral. A profile specifies the Identity Issuer, validation procedure, recipient binding, origin/audience binding, replay defenses, assurance metadata and public receipt projection. The identity-evidence schema selector selects known wire representations; it does not verify the underlying external token.

The Consent Issuer MUST validate identity independently of vendor assertions and bind it to the expected recipient and consent session before recording a decision. Raw email addresses and external tokens MUST NOT enter public receipts, logs or chain data. An implementation MAY use a normalized private representation, but MUST NOT confuse it with the public profile-specific signed representation.

The OIDC-01 profile describes existing receipt 0.1. Its public evidence fields remain OIDC-specific for compatibility. The EVP-01 profile describes the experimental receipt 0.2 representation and the conditions under which it can be selected. OIDC-only field requirements are therefore local to OIDC-01, not assertions about the whole protocol.

An unsupported identity provider, disabled experimental adapter, failed key binding or unavailable external evidence MUST NOT produce an active receipt. Offering another identity flow requires a new explicit session/profile decision; validation failures MUST NOT be reinterpreted as successful consent. Receivers validate the Consent Issuer's attestation and current authority; they do not rerun EVP or OIDC for each email.

Before collecting a decision, the issuer MUST freeze the application/epoch, selected profile, purpose definitions, exact return binding, expected recipient, session nonce and manifest version/hash. An application-signed manifest distinguishes structured purpose identifiers and authorization kinds from localized presentation text. Published versions MUST NOT be edited in place. Receipts MUST identify the exact presentation origin, language/template version and manifest that the person accepted.

Consent MUST be presented in a top-level surface controlled by the Consent Issuer. It MUST be a decision distinct from authentication, registration or a browser identity gesture. Optional purposes MUST remain optional and separately selectable. A vendor-controlled identity form does not authorize the vendor to render or assert the final issuer-controlled decision. A transactional relationship or service acknowledgement MUST NOT be relabeled marketing consent.

The issuer MUST authenticate the session, validate nonce and origin/return bindings, prevent replay and atomically record the decision and immutable receipt issuance event. Declined or unsupported decisions MUST NOT be turned into active permission. A lost browser response MUST NOT cause a second grant; retries require idempotent, session-bound terminal handling.

Return navigation MUST use the exact registered and session-frozen URI and MUST NOT append external tokens, raw identity or receipts to an arbitrary redirect. A product's choice of console, MFA implementation or session API is not itself a protocol requirement. Implementations MUST document the authenticated integration they use to satisfy these invariants.

10. Receipts and permission lifecycle

The receipt schema selector dispatches the two published receipt families. Each includes issuer, validity, application, opaque pairwise recipient, profile-specific Identity Evidence, presentation and explicit per-purpose decisions. It records what happened; it is not a perpetual send permit.

For each permission a verifier MUST match the requested application/epoch, recipient, purpose and authorization kind, then evaluate receipt validity and authenticated current state. explicit_consent, transaction_relationship, service_acknowledgement and preference are distinct categories. A signature on one category does not justify another. An untrusted vendor_assertions extension in historical 0.1 receipts MUST NOT be elevated to issuer-observed evidence or published without a privacy assessment.

Receipt core bytes and the original decision remain immutable. Revocation appends a lifecycle event and changes the authenticated state projection. It MUST NOT erase or rewrite the issuance event. Revocation requests require authenticated authority bound to the relevant permission; a vendor cannot grant consent by sending a revocation-shaped or lifecycle request.

Current-state objects use explicit statuses including active, declined, revoked, expired, suspended and erased as their schemas permit. A later state epoch MUST NOT roll back to an earlier active epoch. Erasure can remove private lookup material without pretending the public issuance history never existed. A historical revoked receipt may have a valid signature while failing permission policy.

11. Append-only event tree

The event tree covers cumulative issuer history. A global sequence_number starts at one; its zero-based leaf index is sequence_number - 1. A root at tree_size covers exactly that prefix. Events and assigned sequence numbers MUST NOT be silently replaced, deleted or reused.

MTH([]) = H("XCIM-EVENT-EMPTY-0.1\0")
leaf(event) = H("XCIM-EVENT-LEAF-0.1\0" || J(event))
node(left, right) = H("XCIM-MERKLE-NODE-0.1\0" || left || right)
MTH([event]) = leaf(event)

For more than one leaf, split at the largest power of two strictly less than the leaf count and combine the recursive left and right roots. Odd leaves are not duplicated. This is the tree shape and consistency construction of RFC 6962 using XCIM's own hash domain tags, not Certificate Transparency wire compatibility.

Inclusion siblings are ordered leaf-to-root. Consistency paths use RFC 6962 SUBPROOF order. Proof indices, sizes and paths MUST match the root authenticated by the signed batch and accepted anchor policy. A proof's own root field does not authenticate that root. An empty-history consistency proof is valid only for the normative empty root. Verifiers MUST reject extra, missing, reordered or malformed path elements.

12. Current-state sparse Merkle tree

Current state uses a binary sparse Merkle tree of depth 256. Bits are traversed most-significant-first; zero selects left. State-key and leaf construction are:

key = H("XCIM-STATE-KEY-0.1\0" || UTF8(object_type) || 0x00 || UTF8(object_id))
value_hash = H("XCIM-STATE-VALUE-0.1\0" || J(state_value))
leaf = H("XCIM-STATE-LEAF-0.1\0" || key || value_hash)
node(left, right) = H("XCIM-STATE-NODE-0.1\0" || left || right)
empty[256] = H("XCIM-STATE-EMPTY-LEAF-0.1\0")
empty[d] = node(empty[d+1], empty[d+1])  for d = 255 ... 0

A compressed proof transports a 32-byte bitmap and non-empty siblings in root-to-leaf depth order. Depth d uses bitmap[floor(d/8)] & (0x80 >> (d mod 8)). A clear bit substitutes empty[d+1]. The number of set bits MUST equal the number of supplied siblings. Reconstruction proceeds leaf-to-root; for absence it starts with empty[256].

The verifier MUST derive the key from the intended object, bind state root and batch sequence to the signed batch, validate presence/absence semantics and validate the state value's object ID, epoch, time and latest-event commitment. An absence proof at an opaque permission key is not a public search for an email address. A membership proof without sufficient current authority and freshness MUST NOT produce a positive permission result.

13. Batches, snapshots and publication

A signed batch distinguishes cumulative tree_size from batch_event_count, the number of newly appended events. It links previous size/root, current event/state roots, previous anchor commitment and proof-set commitment. Zero-new-event checkpoints are permitted when the roots and state really remain unchanged; they require a new authenticated snapshot and creation time, not a rewritten earlier batch.

An operator MUST create internally consistent event and permission snapshots. A concurrent revocation MUST either be included in the sealed snapshot or cause preparation to retry; a proof MUST NOT mix historical event roots with a later reconstructed state root. Historical publication MUST read frozen bytes, not recreate earlier state from the current database.

Proof-set commitment construction MUST avoid circular dependencies between a batch and a bundle that embeds that batch. The experimental Amoy publication profile fixes a six-field proof core, a committed set and genesis/previous-anchor bindings. Those additional objects have explicit schemas; they are not extra arbitrary fields added to the closed core proof-bundle schema.

Publication SHOULD use content-addressed immutable objects and idempotent writes. A retry MUST verify identical bytes or fail; it MUST NOT regenerate timestamps or sign a different object under the old identity. A successful GET, download, cache revalidation or ETag change MUST NOT create a fresh permission decision or extend a signed window.

14. Anchors and trust establishment

A chain anchor commits to a specific batch and its authenticated roots. The receiver MUST verify the intended network/chain ID, contract, authorized signer, canonical transaction receipt and matching event, exact sequence/commitments, block identity and finality policy. A JSON field saying confirmed or finalized is not independent chain evidence. Reorgs, conflicting variants or missing verification MUST prevent a current positive result.

Trust policy MUST distinguish code/contract provenance, issuer key authority and consensus/finality assumptions. Two independent RPC operators are a cross-check, not a cryptographic light-client consensus proof. Timeouts, rate limits, missing historical state and disagreements MUST be treated as unavailable evidence, not permission to trust the issuer's assertion instead. RPC and document fetches require bounded deadlines and resource limits.

This core does not nominate a universal production chain or pre-trusted contract. Amoy uses eip155:80002 only under its experimental profile; this does not authorize Polygon mainnet (eip155:137). Network publication cannot confer issuer accreditation or override receiver-local trust.

15. Proof bundles and receiver algorithm

A proof bundle is transport for a signed receipt, its issuance event/inclusion proof, current-state proof, signed batch manifests and anchors. The outer object is not necessarily signed; every security-relevant relationship MUST be authenticated through its components. An unsigned wrapper's generated_at is not current-state freshness.

A receiver claiming this draft MUST, before a positive decision:

  1. Apply size/depth limits and parse strict JSON/base64url, rejecting duplicate or ambiguous critical data.
  2. Select the exact supported object versions, issuance profile, schema family and trust policy.
  3. Resolve authorized receipt and batch keys under the appropriate roles, validity and compromise policy.
  4. Verify canonical signatures, receipt commitment, issuer identity and receipt validity.
  5. Bind the intended recipient, application/epoch, permission, purpose and authorization kind to the message or list-evaluation context.
  6. Verify the issuance event commitment, index, inclusion proof and signed cumulative event root; check required history continuity.
  7. Independently establish the anchor and authenticate the batch event/state roots and, where selected, genesis/proof-set membership.
  8. Derive and verify the permission state key, sparse proof, object identity, epoch and status.
  9. Verify current application/key and sender-domain authority for each required role; these inputs need their own authenticated validity, not assumptions from an old receipt.
  10. Evaluate the effective intersection of state, receipt, key, application/domain and trust-source validity intervals with the local maximum age.
  11. Return a specific result and enough non-sensitive diagnostic metadata to explain the decision; apply ordinary receiver policy independently.

A valid receipt signature is insufficient for step 11 to return XCIM_PASS. A schema validator is insufficient for any cryptographic or temporal decision. Additional selected-profile checks are mandatory.

16. Freshness, caching and results

The result-code registry is the machine-readable vocabulary. XCIM_PASS means the receiver established accepted current evidence for the requested context. XCIM_PASS_CACHED requires still-valid authenticated cached evidence and an explicit cache policy; it is not permission to ignore an expired state or key.

XCIM_PASS_ANCHOR_PENDING is a historical spelling classified as neutral in registry 0.2. It MUST NOT count as verified public-proof permission or as PASS, cached PASS or delivery authorization. Offline fixture tools return non-protocol labels such as FIXTURE_CRYPTOGRAPHY_OK; these MUST NOT be translated into positive protocol results. Synthetic anchors, fixed fixture clocks and supplied test keys do not establish current chain, recipient, application or domain authority.

XCIM_REVOKED reports revoked permission. XCIM_STATUS_STALE identifies evidence that has passed its authenticated freshness limit. XCIM_STATUS_INDETERMINATE applies when sufficiently fresh state cannot otherwise be established and no more specific result is applicable. XCIM_ANCHOR_UNAVAILABLE reports inability to establish the required anchor; XCIM_LOG_PROOF_FAIL reports an invalid log proof. The obsolete short indeterminate name is not an alias.

Missing evidence, unavailable RPCs, untrusted keys or schema validation alone MUST NOT be represented as PASS. Stale/indeterminate results remove the positive XCIM signal; they are not by themselves proof of fraud or a mandatory mail-rejection policy. A known authorized revocation can reject permission without a public chain lookup, but that shortcut MUST NOT be described as public-proof verification.

Freshness derives from authenticated batch/state relationships, not from an unauthenticated proof field. The Amoy profile fixes this_update to the signed batch creation time and bounds next_update by that time plus five minutes. The receiver MUST recompute or enforce that bound and use the earlier applicable deadline. All cached/exported positive results MUST stop being positive when the evidence or any required authority expires, even if a job or UI session remains active.

Result precedence in a multi-fault input MUST be documented and deterministic. Implementations MUST NOT claim that every product-specific list-row status is a protocol-level proof result. Transport failures, issuer permission and independent proof verification are separate dimensions.

17. Email and list integration boundary

The provisional XCIM message fields are XCIM-Reference and optional XCIM-Proof. Implementations MUST reject ambiguous duplicates and injection and MUST NOT accept historical alternative names as aliases. Senders MUST add the fields before DKIM signing and include relied-upon fields in valid DKIM coverage. A copied proof MUST fail when the recipient, purpose, application or sender authority does not match.

The published shadow-mode adapter demonstrates a versioned development encoding; it does not freeze a universal production header grammar or an Authentication-Results method registration. Until those registrations, limits and canonical message-binding rules receive independent review, integrations SHOULD remain policy-neutral/shadow-mode and MUST identify the exact encoding they test. A header's presence alone never authorizes delivery.

For lists, an ESP requires application-scoped authority and a defined evaluation context. A positive issuer-side permission result is not automatically a public-proof PASS. The protocol does not standardize commercial workspace provisioning, CSV/ZIP UI flows, row budgets, billing or a particular REST API. Those may be described by separate implementation contracts.

18. Privacy and security considerations

Public objects MUST NOT contain recipient email addresses, lists, OAuth secrets, raw identity tokens, private application keys or predictable unsalted email hashes. Pairwise opaque identifiers limit correlation but are not a claim of complete anonymity. Verifiers and operators SHOULD minimize logs, scope access, apply retention limits and review linkage through timestamps, purposes and domain metadata.

Email comparison MUST use a named, versioned rule. The 0.1 baseline preserves the local part, normalizes the domain with IDNA/lowercase and limits the supported address syntax as its fixtures specify; provider-specific comparison rules are separate. A global lowercase transform or heuristic provider ownership classification MUST NOT silently replace that rule. Unsupported identity/address policy results in no active receipt.

The encoding and recipient-binding rules fix HTTPS issuer normalization and scope each identity commitment. Pairwise IDs and salted transport digests alone do not prove a recipient match. Without a trusted authenticated recipient mapping, a receiver MUST withhold a positive result. This publication does not manufacture a portable recipient attestation by hashing an arbitrary supplied email.

Threat analysis MUST cover a dishonest or compromised vendor, issuer, resolver, mirror, chain/RPC source and key; replay, stale state, split views, key compromise, domain transfer, metadata substitution, SSRF, resource exhaustion, malicious consent presentation and correlation. A blockchain cannot cure a false original consent observation. A signed identity assertion cannot cure a deceptive consent UI.

This draft has not completed an independent cryptographic/privacy review, broad MTA deployment review or a paired sender/receiver interoperability window. Implementations MUST NOT advertise those outcomes based on passing fixtures or the managed pilot. No certification, legal-compliance guarantee, accreditation or production SLA is granted by this publication.

19. Conformance claims and review gates

A conformance report MUST identify WD-02, the exact role, supported object versions, profiles, schema manifest digest, verification date, trust/finality/freshness policy, positive and negative tests and limitations. A component MUST NOT claim support for an experimental profile merely because it parses its schema. Synthetic fixtures, separately implemented checks and independently operated interoperability are different forms of evidence and MUST be labeled accordingly.

The required review cases include canonical-byte disagreement, wrong signature/key role/issuer, mismatched version/profile, altered event/state proof, wrong recipient or purpose, stale state, expired/revoked authority, unavailable chain/issuer, domain transfer and duplicate/replayed submissions. New profiles need corresponding negative tests and an explicit compatibility policy.

Open gates include external cryptographic/privacy review, fresh-state operations, reviewed verifier distribution, independently operated sender/receiver testing, and final message-header/extension registration. EVP also requires version-pinned external protocol/browser validation and public end-to-end evidence. These are limitations of maturity, not reasons to conceal the draft from review.

20. Informative implementation evidence

The first public Amoy batch report records one managed implementation's historical testnet evidence. It links the signed manifest, proof set and transaction and distinguishes the active, revoked, tampered, cached and expired cases. It does not establish that every implementation supports this draft, that a currently fresh proof is available or that independent sender/receiver interoperability has occurred.

No brand, endpoint, signing key or contract in that report is a default trust anchor for this specification. The experimental publication profile describes the mechanisms learned from the test without making the implementation a protocol dependency. Product-specific material belongs in implementation reports, not normative core requirements.

21. References and feedback

The referenced building blocks are JCS / RFC 8785, JWS / RFC 7515, Ed25519 / RFC 8032, the RFC 6962 tree construction and BCP 14 / RFC 8174. Profile-specific references appear in OIDC-01 and EVP-01. XCIM does not inherit standards status from these references.

Reviewers can use the schema catalog, artifact manifest, change record and source bundle. Please identify the draft revision and section when sending technical feedback.