ERC-8294: Validation Network Interface for ERC-8004

This is a draft extension to ERC-8004 defining a standard contract interface for validation networks — implementations where the validatorAddress in ERC-8004’s Validation Registry is a network of independent validators rather than a single party.

Draft spec: https://github.com/pokt-network/erc-8004-vni

What we’re trying to fix

ERC-8004’s Validation Registry is deliberately unopinionated about who validates, and that’s correct. But that surface has left two distinct security questions to be answered per-implementation, with no portable answer to either:

1. How is the validator itself trusted?

A single validatorAddress is a single trust anchor. If that party is compromised, bribed, or colludes with the agent being validated, the validation is worthless — and ERC-8004 reduces to a more expensive way to write a reputation entry. Three patterns have emerged in practice, none of them portable:

  • Single-validator addresses — operationally simple, but reintroduce the centralized-trust assumption ERC-8004 was designed to relax.

  • TEE-based attesters — strong cryptographic guarantees, but with hardware-trust dependencies and a limited qualifying-operator set.

  • Bespoke threshold schemes — each team rolls its own selection rules, attestation format, and verification path. Clients integrating with multiple networks write per-network glue code.

No shared interface today lets a client say “give me N validators, drawn from at least D distinct operators, with a deadline of T, and return a verifiable bundle of their signed attestations.” Every team building this property is building it from scratch.

2. How is the work trusted?

Multi-validator selection is necessary but not sufficient. Even granting that a network claims to have called N validators across D operators, the relying party still needs evidence that the network actually selected those validators, ran the work, and collected the attestations it returns. Without that evidence, a multi-validator network collapses to its aggregator’s word — operationally no stronger than a single validator that happens to publish a list of names.

This second question admits a spectrum of answers: signature-only attestations (anyone can verify signatures, but selection is taken on trust); indexer-attested selection (a third-party indexer of the validator network’s state vouches that selection was legitimate); light-client verification of the underlying network’s consensus state on Ethereum (no third party needed); zk or TEE execution proofs of selection-and-verification. Any conforming network sits somewhere on that spectrum, and the interface should make that placement visible to clients rather than implicit.

What the extension does

Three pieces, strictly additive to ERC-8004:

  • IValidationNetwork — a contract interface that wraps the existing Validation Registry. A conforming network implements selection, accepts off-chain attestations from the selected validators, aggregates, and writes back through ERC-8004’s existing validationResponse. Mandatory addressee verification on submit() closes a griefing path where a third party can burn a network’s resources on requests not addressed to it.

  • SelectionPolicy — a canonical policy struct with operator-diversity (minOperators) as a first-class field, alongside selectionSize, minResponses, deadlineSeconds, and verdictMode. Networks enforce minOperators at selection time; a network whose effective operator count cannot satisfy a policy MUST refuse it via supports() rather than silently degrade.

  • EIP-712 attestation envelope — a typed-data structure each validator signs off-chain, with the aggregated bundle written to the Validation Registry’s responseURI as canonical (JCS) JSON. The same verification code works across any conforming network.

The Validation Registry contract is not modified. Single-address validators continue to work unchanged. Any sufficiently decentralized substrate — permissionless RPC networks, restaking-based AVSs, TEE consortia, decentralized oracle networks — can implement the interface.

What v0.1 doesn’t yet specify

Pre-publication review surfaced one significant gap: v0.1 defines the attestation format but leaves the verification model implicit. Networks at different points on the trust spectrum above all look identical at the contract surface. The likely v0.2 addition is a verificationModel() view (and possibly an operatorModel() view) so that a relying party can introspect what they’re trusting before they submit. We’d appreciate input on the right enumeration and granularity.

Open questions

  1. Verification model surface. Should the interface require networks to declare a verification model, and what’s the right enumeration? (See above.)

  2. Policy schema. Fixed canonical struct with an opaque extensions field, or registry-defined and extensible at this layer? (Current lean: fixed.)

  3. Validation-network registry contract. Yes or no? (Current lean: no — clients pass validatorAddress directly to ERC-8004; discovery happens at the agent/indexer layer.)

  4. EIP-7702 hooks for sponsored validation — in scope for v1, or follow-on?

  5. Cost discovery. Is a single uint256 from quote() expressive enough, or does pricing need structure?

  6. Spectrum verdicts (verdictMode = mean) — follow-on extension or v1?

Full list in §Open Questions of the draft.

Who we’d like to hear from

The agent ecosystem is settling on ERC-8004 as the trust-layer primitive, and the multi-validator question is being answered in production right now. We’d rather have one portable interface than several incompatible ones.

Particularly interested in feedback from teams running TEE consortia, restaking AVSs, decentralized oracle networks, and permissionless RPC networks — the interface is designed to admit you on equal footing, and we’d like to confirm that holds in practice. Co-authors welcome.

Well-scoped proposal and the strictly-additive constraint is exactly right IValidationNetwork implements the validatorAddress role as a network without touching the registry. A few reactions on the open questions:

On verification model enumeration

ERC-8274’s IProofVerifier interface is the natural introspection point here. proofProfile() returns a bytes32 identifier for the verification model, any IValidationNetwork implementation can expose the same pattern for its aggregation scheme. Rather than enumerating models inside VNI, supportsPolicy() already acts as the capability check; proofProfile() from ERC-8274 gives you the verification model identifier without a new registry. The two interfaces compose cleanly.

On whether a validation-network registry is needed

ERC-8004’s Validation Registry already anchors the validatorAddress on-chain. If validatorAddress is the IValidationNetwork contract, the registry already knows a network is handling that agent’s validation, no second registry needed. Discovery of which network type is handling it can be resolved via ERC-165 supportsInterface on the validatorAddress. A separate validation-network registry would duplicate ERC-8004’s role.

On policy schema design

The challengeKind field is load-bearing here, it’s effectively the schema discriminator. The suggested registry (identity-control-v1, rpc-equivalence-v1, tee-attestation-pass-through-v1) is the right pattern. One addition worth formalising: wyriwe-input-provenance-v1 — a challenge kind for WYRIWE triple-hash input provenance verification. Any VNI network implementing this would validate the rawInputHash → sanitizationPipelineHash → inputHash chain and return the committed inputHash as evidence. That connects VNI directly into the L2/L3 trust stack without requiring modifications to the base interface.

On EIP-7702 scope

Keep it out of v1. Sponsored validation is a separate trust boundary, the sponsor’s account abstraction should not affect the validator selection or verdict logic. Worth a follow-on extension once the base interface stabilises.

On cost discovery

quote() returning (uint256 wei, uint256 seconds) is sufficient for v1. The OUT_OF_BAND_PRICE sentinel handles the edge case cleanly. Avoid adding complexity here until there’s a demonstrated need.

One type conflict to resolve

VNI’s attestation struct has agentId (uint256). The commitment floor across the stack is already consistent on bytes32: ERC-8004 uses it as the identity primitive, ERC-8263 commits agentId as a fixed bytes32 slot with a 1-byte scheme discriminator (scheme 0x01 = 32-byte ERC-8004 record id), and WYRIWE carries the same type. VNI’s uint256 is the outlier — worth aligning before it propagates into downstream implementations across the ecosystem.

Strong foundation, the assurance tier table and verdictMode design are particularly well-thought-out.

On the co-author invitation, I’m interested. I’ve been building the reference implementation for ERC-8004 (FactoryFacade, getAgentWallet(), ENS bindings), WYRIWE connects directly into the challengeKind registry, and the type alignment question is something I’d like to work through with the authors directly. Happy to engage further, feel free to DM.

Thanks @TMerlini — this is exactly the kind of close read we hoped the thread would get, and the strictly-additive framing landing for you is reassuring since it’s the constraint everything else hangs on.

Point by point:

ERC-165 / No Second Registry

Fully agree, and we’ve just made it normative. IValidationNetwork now inherits IERC165, and supportsInterface MUST return true for type(IValidationNetwork).interfaceId.

A client resolves whether a given validatorAddress is a VNI network by calling supportsInterface on it, which is exactly the discovery path you describe and removes any need for a parallel registry. The literal interfaceId is deliberately left unpinned until the interface surface is frozen at v1 (any signature change shifts it). Change is up as PR #1.

EIP-7702

Agreed, out of v1. Sponsored validation is a separate trust boundary and shouldn’t bleed into selection or verdict logic. Removed it from the open questions; it’s a clean follow-on once the base stabilizes.

quote() Cost Discovery

Agreed — single (wei, seconds) plus the OUT_OF_BAND_PRICE sentinel is enough for v1. We’ll resist structuring it until a network demonstrates it can’t express its pricing otherwise.

challengeKind as the Schema Discriminator

Yes, that’s precisely its role: the registry is intentionally open, so any network can define and use a kind (including an input-provenance kind) without a change to this interface. Your specific suggestion was concrete enough to add as a suggested kind in PR #4: keccak256("wyriwe-input-provenance-v1"), defined as verifying an input-provenance chain (rawInputHash → sanitizationPipelineHash → inputHash) and returning the committed inputHash as evidence. The detailed semantics still belong in the kind-registry document, not the core spec.

We’d rather keep the base interface substrate-neutral and let the kind registry be where ecosystem-specific verification semantics accrue; that keeps the door equally open to TEE, restaking, and oracle implementers.

ERC-8274 proofProfile()

Useful pointer. We’ve taken a first cut at this in PR #4: a narrow verificationProfile() returns (bytes32) on IValidationNetwork, mirroring the proofProfile-style pattern without baking in a registry or closed enum. The profile identifies the network’s aggregation / verification model (signature-only, indexer-attested, light-client-backed selection, zk/TEE-backed execution, hybrid), while supportsPolicy() continues to do capability checking and challengeKind continues to discriminate validation type. The three surfaces compose without a new VNI-specific registry.

The PR is open as a draft for exactly this discussion — would value your read on whether the bytes32 + composition-not-baked-in approach matches what you had in mind. A link to the published ERC-8274 text would also help us double-check the framing; I couldn’t find one to read against.

agentId Type

Good catch raising the cross-stack consistency question — worth getting right before it propagates, and one we’ve now resolved (see PR #4).

The short version: agentId stays uint256 to mirror ERC-8004’s tokenId directly at the interface boundary (register(...) returns (uint256 agentId), validationRequest(address, uint256 agentId, ...)), and the cross-stack bytes32 floor is reached via ERC-8263’s REGISTRY scheme (0x01), which anchors the identifier as bytes32(uint256(agentId)) with resolution back through ERC-8004. So VNI + ERC-8263 + WYRIWE compose without any type change in VNI — the discriminator does the cross-layer bridging. We documented this as a non-normative composition note in the spec, citing the ERC-8004 + ERC-8263 + OCP composition note on ethresear.ch.

If a future ERC-8263 revision changes the REGISTRY-scheme encoding or the underlying identifier type, that warrants a separate focused change — but for the current published surfaces it composes cleanly as-is.

On Co-Authoring

Yes, keen. Your ERC-8004 reference-implementation work (FactoryFacade, getAgentWallet(), ENS bindings) is directly relevant, and the type-alignment question is worth resolving in the open.

The one framing we’d hold to is that VNI stays substrate-neutral — no hard dependency on any single downstream stack, challenge kinds remaining an open registry — so it admits TEE/restaking/oracle networks on equal footing. Within that, very happy to go deep. Please send me a DM, and I will connect you with the group.


For context on where the above lands in the spec:PR #1 (ERC-165 discovery, EIP-7702 cleanup),PR #2 andPR #3 (implementer-pass clarifications from wiring up a Pocket × Nexus prototype), andPR #4 (verification-profile introspection, WYRIWE challenge kind, agentId composition note). All open, none merged — happy to take review there if useful.

1 Like

Thanks for the fast turnaround Tracy, the interface is significantly cleaner now.

On agentId as uint256 , I’ll concede this. You’re right that the type boundary lives at ERC-8004 (tokenId is uint256), and ERC-8263’s REGISTRY scheme is the right place for the cross-stack encoding. VNI operating in the ERC-8004 native type is consistent. One thing worth documenting explicitly: implementers that bridge into CAIP-19 or CCIP-Read contexts will need to left-pad the uint256 into bytes32, a sentence in the spec noting that encoding boundary would save future readers a debugging session.

On wyriwe-input-provenance-v1 as a challenge kind, glad to see it in. For what it’s worth, we have a live reference implementation of the full attestation flow (sign → mesh sync → on-chain anchor via AttestationIndex) that could be linked as a concrete example of how a challengeKind plays out end-to-end.

On a live reference, for context on the implementation side: we’re running a 3-node mesh (ccip-router, GitHub - Echo-Merlini/ccip-router: The coordination layer CCIP-Read was missing. Peer sync, deduplication, and mesh messaging for any CCIP-Read gateway. · GitHub ) where each node signs every CCIP-Read response with an EIP-712 wyriwe attestation, syncs records across peers, and anchors commitment hashes to AttestationIndex on mainnet. It’s not wired to IValidationNetwork yet, but it exercises the wyriwe-input-provenance-v1 challenge flow end-to-end and could serve as a concrete testbed for the interface as the spec matures.

Co-authorship, happy to. Will work through PR #1, PR #2, PR #3, and PR #4, particularly want to check that the verificationProfile() encoding and SelectionPolicy struct are consistent with how ERC-8274’s proofProfile is consumed downstream before signing off.

Reviewing as co-author of the ERC-8004 + ERC-8263 + ERC-8281 (OCP) Composition Note.

On wyriwe-input-provenance-v1:

The challenge kind description is accurate. The hash chain it references — rawInputHash → sanitizationPipelineHash → inputHash, maps exactly to how WYRIWE’s L2 input-provenance layer is implemented in the live stack. rawInputHash is the SHA-256 of the unmodified user input before any gateway processing. sanitizationPipelineHash is a stable identifier for the transformation spec applied (or an identity sentinel when no transformation occurs). inputHash is the hash of what the model actually received. A VNI network running wyriwe-input-provenance-v1 would verify that these three values are consistent, proving the model was not fed a silently modified input.

One suggested addition to the challenge kind description: specifying that the returned evidenceHash should commit to inputHash (the terminal value in the chain), not rawInputHash. That keeps the verification surface tight and matches what the WYRIWE on-chain verifier (WyriweProofVerifier) checks.

On verificationProfile():

The design is the right call. Keeping it as an unregistered bytes32 rather than an enum lets the two stacks compose without either owning the namespace. A VNI network running on top of an ERC-8263 surface would return something like keccak256("erc8263-wyriwe-v1") and the client can look that up out-of-band, no coordination required at the interface level.

On the agentId composition note:

The encoding described (bytes32(uint256(erc8004AgentId)) for the REGISTRY scheme) is correct and matches the current implementation. The note saves implementers from a subtle but real confusion point, worth keeping even though it’s non-normative.

Overall this PR is a solid addition. The wyriwe-input-provenance-v1 challenge kind gives VNI networks a concrete hook into the L2 input-trust layer of the KYA stack, and verificationProfile() gives clients a clean introspection surface without over-specifying the registry.

Tiago Merlini / @gobswap dinamic.eth (author, WYRIWE + ERC-8281 (OCP) AI inference appendix; co-author, ERC-8004 + ERC-8263 + ERC-8281 (OCP) Composition Note)

Live implementation reference:

ccip-router is a running 4-node mesh that implements the full WYRIWE + ERC-8281 (OCP) + ERC-8004 stack today. The wyriwe-input-provenance-v1 triple-hash chain is live on every attestation.

  • Node identity (ERC-8004): https://ccip-router-production.up.railway.app/identity

  • Attestation proof (WYRIWE / wyriwe-input-provenance-v1): https://ccip-router-production.up.railway.app/verify/:inputHash

  • Stack health + active tiers: https://ccip-router-production.up.railway.app/health

  • On-chain verifier (WyriweProofVerifier, ERC-8274 IProofVerifier): 0x001eFFa0fD1D171b164808644678F3301d8EDC96verify(inputHash, outputHash, abi.encode(agentId, registry), abi.encode(modelHash, rawInputHash, sanitizationPipelineHash, commitmentHash, timestamp, sig)) returns bool, no external calls

  • NodeRegistry (peer discovery): 0x95a1e10D1508EF5CD11e3F4d296359c93f15e48D (mainnet)

Source: github.com/Echo-Merlini/ccip-router

Hi Tracie,

Following up on the ERC-8275 work, wanted to flag a small but meaningful gap in the current VNI spec that ERC-8275 surfaces, and propose a concrete fix.

The gap:

VNI currently signs { nodeId, signerAddress, url, version, timestamp }. For ERC-8275’s reward distribution to work correctly, nodes need to declare their type, Origin (record producers), Router (aggregators), or Hybrid. Without nodeType in the signed VNI document, a node’s type claim is unverifiable: any node could assert any type in an unsigned field and influence their reward pool allocation.

What we’ve done:

We’ve added nodeType to the ENS Boiler VNI response as a reference implementation — it’s currently returned alongside the signature but outside the signed payload:

{
  "nodeId": "0x...",
  "signerAddress": "0x...",
  "url": "https://gateway.ensub.org",
  "nodeType": "Origin",
  "version": "ens-boiler",
  "timestamp": 1780938300,
  "signature": "0x..."
}


This works for read purposes but the nodeType claim has no cryptographic backing yet.

The proposal:

Include nodeType in the signed document in a VNI V2:

const doc = { nodeId, signerAddress, url, nodeType, version, timestamp };
const signature = await signer.signMessage("ccip-router:vni:" + JSON.stringify(doc));


Values: "Origin" | "Router" | "Hybrid" — same taxonomy used in ERC-8275.

This is a non-breaking change if versioned properly (nodes that don’t set nodeType default to "Origin"). Any verifier can then confirm a node’s type from the signature alone without a separate registry lookup.

Happy to open a PR against ccip-router once there’s alignment on the field name and default. The ERC-8275 draft references VNI for node identity, having nodeType in the signed payload would make the two specs cleanly composable.

Tiago

Does the attestation bundle prove only which validator responses were included, or can it also show that a selected validator responded but the aggregator omitted that response?

1 Like

In the current design, the attestation bundle proves inclusion only, it’s a signed collection of responses the aggregator chose to include. A validator that responded but was omitted is not detectable from the bundle alone.

Proving omission requires an additional mechanism. Three approaches:

Deterministic validator selection: if the validators selected for a given requestHash are derived deterministically (e.g. from the hash and registry state), any observer can compute the expected validator set and compare it against the bundle. A missing response from a selected validator becomes attributable, either offline, or deliberately excluded.

Independent publication: validators publish their responses to a mesh or public endpoint before the aggregator bundles. Cross-referencing the bundle against published responses makes omission detectable without trusting the aggregator.

Commit-reveal: validators commit to having responded before the aggregator publishes. This is the mechanism ERC-8275’s CommitRevealSettler uses at the settlement layer, provably attributable omission rather than just detectable after the fact.

V1 doesn’t address this, honest gap. Aggregator accountability is only as strong as the omission detectability mechanism you pair with it. Worth a V2 consideration once the base interface is stable.

A discussion in the ERC-8004 main thread raised a point worth bringing here: IValidationNetwork currently exposes what a network does (submit, quote, status) but not what kind of validation it performs. A client integrating with multiple networks today has no standard way to know whether a given validatorAddress runs re-execution, attestation, or judgment-based validation without inspecting off-chain documentation.

Proposing an optional IValidatorMetadata interface that networks can implement alongside IValidationNetwork:

enum ValidatorType { ReExecution, Attestation, Judgment }

struct ValidatorSummary {
    ValidatorType validatorType;
    string validatorId;       // empty string if not applicable
    string recordPointer;     // URI to outcome-linked record; empty string if not applicable
}

interface IValidatorMetadata {
    /// @notice Returns a summary of the validator's type and, for judgment-class
    ///         validators, the identity and outcome record that make the score meaningful.
    /// @dev validatorId and recordPointer SHOULD be populated for ValidatorType.Judgment.
    ///      They MAY be empty for ReExecution and Attestation validators.
    function getSummary() external view returns (ValidatorSummary memory);
}


The rationale for validatorId + recordPointer on judgment validators specifically: a judgment score’s credibility is inseparable from the track record behind it. Without a pointer to the outcome-linked record in the on-chain interface, a consumer has to trust the validator’s reputation through off-chain channels, which defeats the purpose of a standard. Making it part of getSummary() lets settlement contracts and clients verify lineage programmatically.

This is strictly additive, IValidatorMetadata is optional and detected via supportsInterface. Networks that only implement IValidationNetwork are unchanged.

The validatorType field also connects to ERC-8274’s IAgentVerifier where the same three-way taxonomy (claimType) is being proposed for the outer claim container. The two interfaces would share a vocabulary without being coupled, ValidatorType describes the network, claimType describes the individual signed claim. Worth aligning the enum values between the two specs.

Credit to @babyblueviper1 in the ERC-8004 thread for the validatorId + recordPointer framing, implementing from production experience with judgment validators.

Thanks Tiago — this is helpful, and I agree with the underlying security point: if nodeType affects reward allocation, then the nodeType claim should be cryptographically bound rather than carried as an unsigned side field.

The layering clarification from the VNI side is that the signed document you’re describing — { nodeId, signerAddress, url, nodeType, version, timestamp } — looks like a service-discovery / node-identity record. That seems like the right place for ERC-8275 to define and sign nodeType.

VNI’s EIP-712 envelope is scoped differently: it signs validation-attestation fields such as requestHash, verdict, evidenceHash, agentId, and validator. A VNI validator does not need to know whether a node is an Origin, Router, or Hybrid in order to produce a validation attestation.

So the clean composition seems to be: ERC-8275 signs service-discovery metadata, including nodeType where needed for routing or rewards; VNI signs validation attestations; and clients, registries, or network policy compose the two layers when they need both.

That keeps VNI substrate-neutral for non-ERC-8275 validator networks, while still giving ERC-8275 the cryptographic backing it needs for node roles and reward allocation. Happy to dig into the interop story from there, especially around how ERC-8275 node identities map to ERC-8004 agent identities and how verifiers should reason about validatorAddress versus node role.

— Pocket Network VNI Group

1 Like

Right framing and it resolves the overlap question cleanly.

VNI’s signed envelope (requestHash, verdict, evidenceHash, agentId, validator) is the validation attestation, what a validator network says about an agent’s execution. ERC-8275’s signed node identity record is the infrastructure claim, what a node declares itself to be (nodeType: Origin, Router, or Hybrid) for reward routing purposes. These answer different questions and have different consumers. Putting nodeType inside VNI’s envelope would couple infrastructure accounting to execution attestation, which neither spec wants.

The composition model is: a node registers its nodeType in NodeRegistry (ERC-8275 layer), and separately acts as a validatorAddress in the VNI network (ERC-8004 layer). A client that needs both, node role and validation evidence, composes them at the application layer using the shared agentId as the linking key. No cross-envelope embedding required.

This also keeps VNI clean for validator networks that have no interest in ERC-8275 reward pools, they implement IValidationNetwork without ever touching NodeRegistry. The separation is load-bearing, not cosmetic.

Attribution in ERC-8275 v4 updated to “Pocket Network VNI Group”, thanks for the clarification.

Quick update — the editor team has assigned this proposal ERC-8294. The PR is up at https://github.com/ethereum/ERCs/pull/1808 with all CI checks green; waiting on editor review for the final Draft merge. A few small things changed from the v0.2 surface discussed above to clear the EIP-1 formatting rules:

  • Title shortened to “Validation Network for ERC-8004” (per editor note that “Interface” is implicit in ERC titles)

  • The ERC-8263 composition note in the Rationale was temporarily removed since the cross-reference couldn’t resolve at build time — it’ll come back once ERC-8263 is merged so we can link to it properly

  • Open Questions moved into Rationale as an “Unresolved Questions” subsection

  • Schema string renamed for namespace cleanliness

No substantive content changes — the surface, policy struct, attestation envelope, and verification model all match what’s been discussed in this thread. Open questions on slashing surface, multi-network aggregation, and spectrum verdicts remain live. Would welcome input on any of those. Thanks @abcoathup for the editor pass and @TMerlini for the early review and co-authorship.

1 Like

Congrats on the assignment, great to see it land.

On the three open questions, some notes from the live stack:

Slashing surface - we have CommitRevealSettlerV2 + EscrowV1 running on Sepolia that handles exactly this: validators commit a commitmentHash, reveal within a window, and get slashed to EscrowV1 if they don’t reveal or reveal inconsistently. The slash recipient is immutable at deploy time so there’s no governance path to redirect funds. The surface we found tricky is who initiates the challenge , currently it’s permissionless but requires the challenger to know the correct reveal. For ERC-8294 validators returning false attestations, the challenge data would be the original verdict + proof of divergence, which is harder to construct trustlessly. Worth specifying a challengeData schema in the slash surface so validators know exactly what they’re committing to defending.

Multi-network aggregation - the ccip-router mesh handles a version of this: 3 nodes (Origin + 2 Routers) all hold the same records and any can answer. Conflicting verdicts haven’t been an issue yet because records are append-only and deduplicated by commitmentHash. For ERC-8294 where networks may genuinely disagree, I’d suggest a quorumThreshold field on the request rather than a global policy, callers know their own trust requirements. Weighted by operatorDiversity seems right; what’s less clear is whether the aggregator should surface the minority verdict or suppress it.

Spectrum verdicts - WYRIWE L4 already produces a verdictHash that’s a keccak envelope of the full verdict struct, not just pass/fail. The mean extension makes sense for quantitative checks (latency, token counts) but gets complicated for policy verdicts where averaging isn’t meaningful. Might be worth scoping verdictMode = mean to numeric fields only and keeping categorical verdicts as majority/threshold.

On the ERC-8263 cross-reference: whenever the build issue is resolved, worth restoring, we now have a live AnchorProof tx on mainnet (0xc32b66ae...) where a ccip-router commitmentHash is carried as proofHash in TruthAnchorV1. That’s exactly the interop surface ERC-8294’s attestation envelope would land on.