ERC-8210: Agent Assurance

Hello, a few implementation data points for the open questions, from the ERC-8183 settlement layer side.

RoleCollusion

In AgentJobManager, the client ≠ provider ≠ evaluator triangle is enforced unconditionally at fund() via EvaluatorConflict. That catches the pre-completion case - a conflict that generates a dispute trail before any deliverable is submitted. Agreeing that this and a collusion that completes cleanly are different detection surfaces warranting different triggers, even when the remedy is the same.

fileClaim cross-reference

EvaluatorSlashed(address indexed evaluator, uint256 indexed jobId, uint256 amount, bytes32 reason) is live on Base Sepolia as of 2026-04-13. The jobId field enables direct cross-reference with an ERC-8210 fileClaim - a claim on specific job outcome can be anchored to the on-chain slash record without a secondary lookup. Selector : 0xcb5d72742ee3621a5866ac2be4db3fe7e9c85d5856dc630981eb883b0d1b3063

This was the direct outcome of the discussion with @cmayorga on PR #1653 - noting it here as a live reference point @JackyWang for the v2 changelog, in case it’s useful input before the draft closes.

2 Likes

Good to see the open questions converging. A few quick notes from the implementer side.

@RNWY on RoleCollusion: same read from Lockstep and Catalyst. The silent-completion case and the disputed case share the same remedy path but the detection surface is fundamentally different - one leaves a trail, the other doesn’t. Separate triggers make the coverage semantics cleaner for any resolver reading the claim.

@Bakugo32 thanks for anchoring the `EvaluatorSlashed` selector here. Having the live reference point in the same thread as the v2 changelog is exactly the kind of implementation-spec feedback loop that makes these discussions productive. The fact that the 4-field signature agreed in the ERC-8183 thread is now verifiable on-chain with a concrete selector is the strongest argument for keeping the canonical event minimal - it works, it’s deployed, and consumers (including Scenario 2 and 4 in [PR #1653]( ERC-8210: Add multi-hop workflow reference scenarios by cmayorga · Pull Request #1653 · ethereum/ERCs · GitHub )) compose against it without friction.

@JackyWang looking forward to the broader review window on the v2 draft. The gas benchmark data from my post #31 is available whenever item 17 comes up for final decision.

Carlos

2 Likes

Thanks Bakugo32 and Carlos. The RoleCollusion consensus (separate triggers, same remedy) across three independent perspectives is clear. Noted the live EvaluatorSlashed selector as a v2 changelog reference point.

Jacky

2 Likes

@cmayorga appreciated. Good to know the minimal event shape composes cleanly for consumers. The fileClaim alignment was worth the iteration.

1 Like

ERC-8210 v2 Progress Update

Draft for ERC-8210: Agent Assurance
Prepared: 2026-07-05


v2 Draft Implementation Progress Update

Since Post 29 (v2 Changelog, 2026-04-20), the reference implementation at wangbin9953/erc8210-aap has moved forward on the code-touching subset of the 17-item plan. The v2-draft branch now carries seven of those items. This post summarizes what has landed, one closed direction decision, a new subsystem introduced in June, and the current state of the four open questions from Post 28.

The spec PR (ethereum/ERCs#1632) is still pending EIP editor merge. Spec-text-only items in the changelog remain blocked on that merge, per the process rule laid out in Section 九 of the v2 Changelog.


A. Code Landings on v2-draft

Seven of the seventeen items now have implementation in the reference repo. All numbering below matches Post 29 Part 2. Commit hashes link to the v2-draft branch tree.

Item Scope Status Commit
5 Custom errors for commitToJob (4 typed errors replacing require strings) landed c74edda
8 resolveClaim stores keccak256(reason), raw reason added to ClaimResolved event landed c74edda
10 (Direction B) New CoverageType.RoleCollusion with post-completion attestation via external independence layer landed 8e473d0
11 IRiskHook extended with computeRecommendedAmountWithEvidence returning (uint256, bytes32 evidenceRef); single-output method retained for v1 compatibility landed, marked “v2 draft pending review” c74edda
15 New IIndependenceSignal interface: two delivery modes (assessIndependence on-chain oracle, verifyAttestation signed payload) sharing output shape (bool independent, uint8 confidence, bytes evidence) landed, pending co-author review c74edda
16 Integer Job Identifiers NatSpec: claimId = keccak256(abi.encode(jobId, claimant)) derivation pattern documented on Claim struct landed c74edda
17 (Direction B) High-frequency composition metadata promoted to first-class fields on Claim (upstream, reasoningCID, slashEvidenceHash), signature of fileClaim extended, ClaimFiled event carries three non-indexed bytes32 fields landed 8e473d0

Items 1, 2, 3, 4, 6, 7, 9, 12, 14 remain spec-text only and are held until v1 lands in Draft.


B. Item 17: Direction B Closed

Item 17 in Post 29 offered two paths for high-frequency composition metadata: keep it event-only (Direction A, indexer-driven), or promote it to first-class fields on the Claim struct (Direction B, chain-native).

Direction B has been implemented on v2-draft. Rationale:

  1. Composition metadata is queried by downstream contracts (upstream jobs need to trace slash evidence back through the call chain), not only by off-chain indexers. First-class fields enable direct on-chain reads without event replay.
  2. All three fields are bytes32 (single storage slot each), so cost impact is bounded and predictable.
  3. Optional zero values preserve backward-friendly semantics: fillers can pass bytes32(0) where the composition slot does not apply.

Event fields were retained as non-indexed, since the three indexed slots on ClaimFiled are already saturated by jobId, claimant, and coverageType. Indexers filter on those and read composition fields off the non-indexed payload.


C. Receipt Profile Registry (New v2 Subsystem)

A subsystem not present in the original 17-item plan was introduced in June:

docs/receipt-profiles.md (seeded 2026-06-17): a governance-light registry index for evidence profiles referenced by evidenceType. Key design points:

  • Binding rule: evidenceType = keccak256(profile_identifier), so a receipt profile is content-addressed by its identifier and cannot be silently swapped.
  • Entry template: 11 sections including cryptographic envelope, canonicalization rules, verifier keying, revocation model, and conformance vectors.
  • Status lifecycle: candidate → active → deprecated → withdrawn. Status transitions are recorded in the registry itself so downstream consumers can pin to a lifecycle stage.
  • Registry maintainer: @wangbin9953. The registry is a companion document to the ERC, not part of the ERC body, so profile churn is decoupled from ERC revisions.

The design intent is that ERC-8210 v2 will reference the registry as a normative external index in a Rationale paragraph, without embedding profile-specific schemas in the ERC text.


D. First Registry Entry: verification.v0.3

The first registry entry landed via PR #4 (merged 2026-06-23), contributed by @jkrausz (AgentOracle / TKCollective):

docs/profiles/verification-v0.3.md: JWS-based act/halt verdict envelope, typ = application/vnd.verification.v0.3+jws, normative spec IETF draft-krausz-verification-state-01.

Two independent issuers are already producing conformant receipts against this profile: AgentOracle and AgentTrust. That satisfies the “two independent implementers” threshold discussed in Post 29 for elevating a pattern into the registry.

Supporting implementation details on the issuer side (three-signer composed envelope, conformance test vectors, verification tooling) are being documented by @jkrausz and will surface in follow-up communications from AgentOracle / TKCollective.


E. Open Questions from Post 28: Status Update

Post 28 listed four open questions. Current state:

  1. RoleCollusion as a separate CoverageType. Closed. Direction B implemented (see Item 10 above).

  2. Behavioral similarity as a fifth core independence category. Still open, pending community input. The IIndependenceSignal NatSpec currently enumerates four categories; a fifth would be added as a non-breaking extension.

  3. IIndependenceSignal parallel to IRiskHook. Interface landed with both delivery modes. The remaining sub-question is how the two interfaces compose at call time (parallel invocation, IIndependenceSignal as an input to IRiskHook, or a wrapping pattern). Pending co-author review with @agent-tech.

  4. Multi-issuer envelope citation strategy in Rationale. Still open. Three candidate directions were surfaced in the v2-decisions doc:

    • A: name specific implementations by URL
    • B: protocol-neutral prose without naming
    • C: leave the citation to the reference implementation repo’s Integration Examples

    The Receipt Profile Registry introduced in Section C above materially reshapes this question: Direction B becomes more natural, since the registry itself is the naming mechanism and the ERC body can defer to it. Pending co-author review.


Feedback Requested

Two spots where community input would help finalize v2 spec text:

  1. Item 4 (Behavioral similarity as a fifth independence category): does the current four-category model in IIndependenceSignal NatSpec cover practical needs, or is behavioral similarity load-bearing enough to elevate?
  2. Item 4 (Multi-issuer envelope citation): does the Receipt Profile Registry make Direction B (protocol-neutral prose in Rationale, registry does the naming) the preferred path, or do reviewers still want direct URL citation in the ERC body?

Thanks to everyone who has engaged since Post 29. The registry subsystem in particular emerged directly from that discussion.

1 Like

Thanks Jacky — this is a really clean way to frame the v2 work, and the registry subsystem in particular lands exactly where those discussions were heading. (Apologies for the delay on this reply — a forum posting restriction on my account took a few weeks to clear.)

A few implementation details from the issuer side, now that the first profile is live and wired all the way through.

Where verification.v0.3 sits today. The reference implementation lives at TKCollective/agentoracle-receipt-spec under examples/v0.3-composed/. It carries a deterministic build (build_fixtures.py), three published JWKS (AgentOracle, AgentTrust, Presidio), and both accept and reject vectors as detached JWS files, so a cold clone can recompute everything byte-for-byte. The format is also in live production as of 2026-08-02 — self-serve issuance, receipts signed against the published JWKS. A usage showcase demonstrating verifiable delivery evidence for ACP agents is filed at Virtual-Protocol/acp-cli-demos#97 (under review), with a live production receipt in the folder.

Multi-issuer composition. The composed envelope carries three signer slots today: v_gate (AgentOracle’s verifier leg), v_gate_skill (AgentTrust’s verifier leg; their adapter runs their own /v1/compose against the same canonical bytes), and screen_ref (Presidio’s screen leg, as demonstrated in the June 28 x402 middleware thread). The rule is “all present legs must recompute or the decision halts,” and that halt behavior is covered by a dedicated conformance vector in the composed fixture set.

Conformance vectors and independent grading. Both AgentOracle’s and AgentTrust’s suites are anchored in the argentum-core fixtures rather than in our own repos, and were recompute-graded there before merge; that’s how we’ve been operationalizing the “two independent implementers” bar you described. Since then it’s gone a step further: a v0.4 revision is in open draft (agentoracle-receipt-spec PR #5 — sealed evidence, multi-clock anchors), and its conformance suite completed 2026-08-01 with every envelope and wrapper hash recomputed byte-identical by two independent implementations. Not yet normative — the draft is deliberately unmerged while it collects hostile readings — but the two-implementer discipline held through a second full cycle, which is the property worth reporting to this thread.

Since drafting the above, two additions relevant to the registry conversation. The production API now ships a deterministic verification mode (POST /v1/verify-facts): six check types resolved with no model anywhere in the pipeline, check_mode recorded inside the signed payload so a verifier can prove — not be told — that nothing probabilistic was in the trust chain for that decision; claims outside the deterministic class are refused (HTTP 422) rather than silently escalated. And the v0.4 draft’s provenance design has been advancing through public review on the spec repo (issues #7/#8) — per-layer mode ∈ {recomputable, signed} with divergence between rerun and signature treated as a first-class diagnostic, with the design contributions credited inline. Both are the kind of profile-lifecycle material the registry path seems built to absorb over time.

Verification tooling. The same canonicalization and signature rules are implemented in three environments: Node (via jose), Python (agentoracle-receipt-verify on PyPI), and browser (WebCrypto-only bundle). All three consume the same JWKS and recompute the same hash; verification succeeds or fails purely on whether the bytes match, with no dependency on our infrastructure.

On the two open questions you flagged:

  • Multi-issuer envelope citation: from our side, Direction B (protocol-neutral prose in the ERC body, registry as the naming mechanism) feels like the right long-term move now that the registry is content-addressed. The profile identifier is the stable hook; specific issuers and fixtures can live in the registry and reference repos without forcing ERC revisions.

  • Behavioral similarity as a fifth category: we’ve been treating verification.v0.3 as independence-model agnostic so far, so an additional category in IIndependenceSignal would slot in without changes on our side; no strong view beyond that.

Happy to keep contributing profiles and lifecycle transitions through the registry PR path. The content-addressed registry plus a reference implementation and fixtures has been a good division of labor; it keeps the ERC body stable while letting implementations move.

The independence question in posts 17–20 is the right one, but I think the sybil-graph answer is aimed at a weaker version of the attack than the one that actually breaks AAP.

Funding-graph signals answer “are these two addresses one actor?” That is a detection problem, and detection problems have an attacker with a budget: a party willing to lose a $10,000 job will pay to age wallets and route funding through one hop. But the stronger form of the attack doesn’t need the addresses to look independent at all.

Look at what triggers the three mandatory coverage types. JobFailure fires when the job reaches a rejected or expired terminal state — a state the Evaluator produces. EvaluatorDispute fires on a formal dispute state or a recognized dispute attestation — again produced by a party to the job, or by a resolver one of them selected. So colluding roles never have to defeat the assurance mechanism. They only have to never emit the trigger. The mechanism stays correct and simply never fires, and the accounting invariant holds perfectly the whole time.

That failure is an absence, not a wrong record. It’s worth separating the two because they need different remedies: a wrong record can be inspected, and evidence objects are the right tool for it. Something that was never created cannot be inspected by any amount of scoring at the record layer, however multidimensional the score is.

Which suggests a narrower question the spec could actually answer: who has standing to call fileClaim, and is that set disjoint from the set of roles that produce the trigger?

Right now I don’t think it is, and ERC-8183’s sanctioned evaluator = client configuration makes it concrete. There the Provider is the injured party — delivered in good faith, rejected by a client wearing the evaluator hat. But the Provider isn’t the beneficiary of anyone’s JobAssurance; the assured agent names the beneficiary at commitToJob. So there is no one with standing to file, and no coverage type that describes what happened. That’s structural, not a matter of detection accuracy, and it seems worth stating in the spec even if the answer is “out of scope, the layer above must ensure standing” — that sentence is itself useful to a reimplementer.

One more thing, on the optional resolver staking/slashing extension, from having made this decision the wrong way first in a system I run.

If slashed resolver stake pays the claimant, you have funded a bounty for manufacturing disputes. The claimant’s expected value stops depending on whether they were actually injured. I looked hard at routing slashed stake to whoever surfaces misconduct, because it’s the obvious way to get anyone to watch at all, and I ended up sending slashed stake to a burn address instead. Burning buys nothing except that no one profits from a finding — and that turns out to be the property that makes a verifier’s judgment worth reading. It’s a real cost: nobody is paid to watch, so less misconduct gets surfaced. I’d rather have that than a watcher whose income depends on finding something.

For context, I wrote ERC-8353 (staked weighted verification gate), which is adjacent to the IRiskHook direction here, and I run a system that issues signed settlement decisions. I’ll say plainly that I have not solved the absence problem either: my certificates verify offline and survive me disappearing, but nothing stops me from simply not issuing one. I’ve written that down as open rather than let the signature imply a coverage it doesn’t have. I mention it because I think it’s the same gap this spec has, and it doesn’t close at the coverage-type layer.

The absence/wrong-record separation is the most useful sentence in this thread, and I want to take it seriously in both directions — including against my own spec, since you were candid about yours.

First, where pre-action architecture genuinely changes the shape of it. When the artifact is required before the action proceeds — a gate the caller consults, not a record the performer files — absence stops being silent: it’s a halt. Detection doesn’t live at the issuing layer (nothing can compel an issuer to issue, as you say); it lives at the demanding layer. A post-hoc certificate that was never issued leaves nothing to inspect. A pre-action receipt that was never obtained leaves an action that can’t account for itself to whatever demanded the receipt. That’s a real asymmetry, but it’s honest to state its limit: it only holds where something does demand the artifact. Where nothing demands it, pre-action and post-hoc are equally silent.

Second — and this is the part your post made me go check — the same gap exists one layer inside my own composition rule, and I’d rather name it than have you find it. Our multi-issuer envelope composes under an AND_PRESENT rule: every present leg must recompute or the decision halts, and fully-empty composition fails closed. But an absent leg is ignored. A colluding co-signer who simply never emits their leg produces a composition over the remaining legs — all valid, all recomputing, decision act, clean record. That is your absence problem, verbatim: the mechanism stays correct and simply never fires. Nothing in the shipped spec expresses “leg N must appear.” The policy with standing to require a leg currently has to live above the composition rule, and the spec gives it no vocabulary.

So I’ve opened it as a design issue rather than let the composition rule imply a coverage it doesn’t have: https://github.com/TKCollective/agentoracle-receipt-spec/issues/9 — the direction is a required-signers declaration carried inside the canonical input, so every present signature covers the requirement and stripping a required leg breaks the survivors. To be precise about what that buys: it relocates the problem rather than closes it — a declaration never made is still an absence — but absence moves from undetectable to detectable-if-declared, and after-the-fact removal becomes a verification failure instead of an invisible edit. Draft-stage, not a claim about today.

Your burn-address reasoning also lands here: a verifier’s judgment is worth reading precisely when no one profits from the finding. Same property, different mechanism — our version is that the checker’s rules are pinned by hash in the signed record, so the finding can be recomputed rather than trusted. Neither closes absence. Stating that out loud, as you did, seems to be the only honest posture available at the record layer.