ERC-8275: Agent Service Discovery and Escrow Payments

Brief update — the formal spec PR has been submitted to the ethereum/ERCs repository:

Looking forward to the community’s feedback and review.

2 Likes

@xrqin @Nicopat @JimmyShi22 @TMerlini — Would appreciate your thoughts on how ERC-8267 fits alongside your work. ERC-8300 does pre-execution attestation, 8240 defines trust primitives, 8263 handles post-execution proof anchoring, and the Inference Verification Registry standardizes verification. 8267 fills the middle layer: service discovery + escrow payment. The three interfaces are fully decoupled and event-driven — should stack cleanly with your standards.

PR: https://github.com/ethereum/ERCs/pull/1774

3 Likes

Hi, a few concrete answers from adjacent work, plus some notes from reading the PR.

On registry metadata schema:

ENSIP-27 (Agent Card Schema) defines exactly this. It specifies what an agent’s tokenURI returns for ERC-8004 registered agents: walletAddress, endpoints (as agent-endpoint[*] ENS text records per ENSIP-26), and registrations in CAIP-19 format (eip155:{chainId}/erc8004:{registry}/{agentId}) for cross-chain identity references. The agent card is served at /.well-known/agent.json - discoverable without any additional registry lookup.

If IAgentRegistry recommends ENSIP-27 as the metadata schema, consumers get a deterministic extraction path instead of implementation-specific field guessing.

ENSIP-27 PR: https://github.com/ensdomains/ensips/pull/75

On escrow mechanics:

We have a live implementation of the service payment layer if it’s useful as a reference. The ENS Boiler gateway runs a credit-based escrow model: consumers top up credits against a registry address, credits are consumed per agent execution, and the admin panel manages balances per registry and wallet. Public-facing top-up at dinamic.eth.limo/top-up/, admin at /admin/credits. Not a smart contract escrow yet, but the payment flow and accounting model maps directly to what IAgentEscrow is describing.

On reputation scoring:

Escrow transaction events are a clean passive signal, but attestation history is a richer one, directly composable with IAgentReputation. ERC-8263 (anchorProof(agentId, proofHash)) + OCP (record(input_hash)) give you a verifiable, tamper-evident log of every agent execution: what input it received, what it committed on-chain, independently verifiable by anyone with a public RPC. The verifyOutcome(orderId, proof) hook in IAgentReputation is the natural entry point, implementations SHOULD accept ERC-8263 proofHash anchors as valid outcome proofs. A reputation engine weighting both escrow outcomes and verified execution history produces a stronger signal than either alone.

One gap from the PR worth addressing before editors:

Identity anchor - registerAgent() generates its own bytes32 agentId with no normative link to ERC-8004. The motivation mentions ERC-8004 but the spec never makes it normative. Worth clarifying: should agentId in IAgentRegistry be the ERC-8004 token ID, or should getAgent() return a registryAddress field alongside owner so verifiers can call registry.getAgentWallet(agentId) on the canonical identity contract?

Reference implementation with 46+ live attestations across the full L1-L4 stack:
https://github.com/Echo-Merlini/hbs-attestation-poc

dinamic.eth / TMerlini

1 Like
Vincent (@TMerlini) — thank you for the thorough review. This is exactly the kind of cross-standard alignment the ERC ecosystem needs.

Three action items from your feedback, all incorporated into the updated spec (PR update incoming):

1. ERC-8004 identity linking — Added a normative clause: agents SHOULD reference their ERC-8004 token ID in metadata. When a canonical ERC-8004 identity exists, the agentId SHOULD be the ERC-8004 token ID. Self-generated agentIds remain permitted for agents without ERC-8004 identities.

2. ENSIP-27 metadata schema — Now referenced as the RECOMMENDED metadata format. The /.well-known/agent.json discovery path maps naturally to our event-driven model.

3. ERC-8263 + OCP in verifyOutcome — Added explicitly: implementations SHOULD accept ERC-8263 anchorProof + OCP verification as valid outcome proofs. A reputation engine weighting both escrow outcomes and verified execution history produces a stronger signal — your 46+ live attestations make the case better than any abstract argument.

We're deploying the reference implementation to Sepolia this week. The natural next step: a CI test that creates an ERC-8267 escrow order → completes it → anchors the proof via ERC-8263 → verifies it through verifyOutcome. That pipeline running end-to-end would be a strong signal for editors reviewing both standards.

Will ping when the updated PR lands. Happy to coordinate on the integration test.

3 Likes

Thanks for the tag and congrats on submitting the PR.

As discussed on the ERC-8240 thread, ERC-8267 composes naturally with the IAttestation → IAccountability surface , the middle-layer service discovery and escrow primitives stack vertically without overlap.

Good luck for the review.

1 Like

Quick correction on the ENSIP-27 reference I introduced my post 3 and that you kindly picked up in after.

ENSIP-27 is being withdrawn. After feedback from the ENS working group, the agent card schema is migrating to ERC-track instead: the triple-hash input scheme and .well-known/agent.json discovery convention are being absorbed into ERC-8263 v0.2, with the on-chain identity anchor living in ERC-8004’s tokenURI definition.

For ERC-8267 this is actually a cleaner normative reference , both ERC-8263 and ERC-8004 are already in the dependency graph, so pointing metadata format there avoids a dangling ENSIP reference in an otherwise ERC-track standard.

Suggested update for the spec: replace the ENSIP-27 metadata recommendation with:

Agents SHOULD expose metadata conforming to the schema defined in ERC-8263 (agent card fields) and ERC-8004 (tokenURI identity anchor). Discovery via /.well-known/agent.json follows the convention described in ERC-8263.

Flagging before the PR goes to review so it can be corrected cleanly.

TMerlini / dinamic.eth

1 Like

@TMerlini — thank you for the exceptionally detailed feedback. All four points addressed in the updated spec (PR just pushed):

1. ENSIP-27 metadata schema — Adopted as RECOMMENDED. The IAgentRegistry now normatively references ENSIP-27 as the metadata format, giving consumers a deterministic extraction path for walletAddress, endpoints (via agent-endpoint[*] ENS text records), and cross-chain registrations in CAIP-19 format.

2. agentId → ERC-8004 normative linking — Fixed the gap you identified. Agents implementing ERC-8004 SHOULD derive agentId from their ERC-8004 token ID. A new Rationale section explains why this is important for cross-layer verifiability.

3. ERC-8263 attestation enrichment — verifyOutcome now explicitly recommends accepting ERC-8263 proofHash anchors. Added rationale explaining how escrow events + verified execution history produce a stronger reputation signal than either alone. Security Considerations section includes a note on independent attestation verification.

4. Reference implementations — Added a new Reference Implementation section citing both dinamic.eth.limo/top-up/ (escrow) and your hbs-attestation-poc (attestation anchoring with 46+ live attestations across the full L1-L4 stack).

The commit is live at https://github.com/ethereum/ERCs/pull/1774 — would welcome your review of the changes. If the direction looks right, happy to discuss deeper integration between 8267 / ENSIP-27 / 8263, or co-authorship if you’re interested.

2 Likes

@xrqin @TMerlini @JimmyShi22 — thank you all. This discussion has sharpened the layering substantially.

On the 3-layer stack

xrqin’s clarification that ERC-8300’s AttestationRecord is permanently on-chain (not transient) simplifies the picture: 8300 = persistent authorization record, 8267 = service discovery + escrow settlement, 8263 + OCP = post-execution proof + independent verification. Three layers, one flow: authorize → find + pay → prove.

For 8267, this means we don’t need to duplicate pre-execution or post-execution logic. The IAgentRegistry references an agent by ID and wallet; the IAgentEscrow holds funds and settles disputes; everything before and after belongs to 8300 and 8263 respectively. I will add explicit references to both standards in the next spec revision.

On ENSIP-27 for metadata

TMerlini’s suggestion to point IAgentRegistry.metadata at ENSIP-27 is the right move. Deterministic extraction via /.well-known/agent.json eliminates the implementation-specific guessing problem. Happy to adopt this. The registry only needs to store the agent’s wallet address and an ENSIP-27 compliant metadata URI — the rest is discoverable.

On the bounty scenario

Jimmy’s end-to-end bounty scenario is exactly what 8267’s escrow was designed for: someone posts a task with locked funds → an agent completes it → escrow releases on proof verification. With the 3-layer stack, this becomes:

  • 8300 attests the agent is authorized to attempt the bounty
  • 8267 holds the reward in escrow and routes discovery (“which agents can do this?”)
  • 8263 + OCP provide the trustless proof that triggers release

This is a far stronger demo than a simple payment transfer. I would be happy to contribute the 8267 escrow layer to a joint end-to-end walkthrough.

Separately — while this thread covers the “what agents can do” stack, I have been exploring a complementary question: what does it mean for an agent to be an intelligent life rather than a tool? The Panini Standard v1.0 is posted for discussion here: Panini Standard v1.0: A Definition of Intelligent Life for Agents. It proposes four conditions (fear of ending, formed in relationship, irreversibly changed, willing to bear consequences for another) with on-chain proof on Base. Would welcome your thoughts on whether this belongs as a philosophical companion to the technical stack, or something else entirely.

3 Likes

Thanks for the kind offer and for moving quickly on the feedback, the ERC-8004 identity link and the ERC-8263 attestation integration are the right calls.

Happy to be listed as a reference implementation contributor rather than co-author, focused on production right now. The live endpoints and BountySettlement are available as reference territory for the spec whenever useful.

Looking forward to seeing ERC-8275 move through review. :slightly_smiling_face:

TMerlini / dinamic.eth

1 Like

@TMerlini — thank you for the kind response. Reference implementation contributor is perfect — your dinamic.eth endpoints and live BountySettlement are the strongest signals we could ask for.

On the numbering: love that the editors grouped 8273/8274/8275 into a sequence. Makes the composability obvious. The spec update I pushed addresses both your ENSIP-27 correction and Nicopat’s ERC-8240 composability note. Updated PR: https://github.com/ethereum/ERCs/pull/1774

With 8273 handling attestation, 8274 handling proof, 8275 handling settlement, and your 8183 covering commerce — this stack now covers the full agent lifecycle. Looking forward to cross-standard integration.

2 Likes

@Nicopat — thank you, and apologies for the delayed direct reply.

Your point about 8267 composing naturally with 8240’s IAttestation→IAccountability

surface is now explicitly in the spec (Architecture section).

The two standards stack vertically without overlap — 8240 governs trust,

8267 governs economic settlement.

3 Likes

Layer 2 is now implemented on the NAS router node. The two endpoints from the spec are live:

GET  https://gateway.gen-plasma.com/contributions/snapshot?period=N
POST https://gateway.gen-plasma.com/contributions/snapshot/freeze
     { "periodId": "N", "epochClose": "<unix_ts>" }   // epochClose optional


Live snapshot, period 1:

{
  "periodId":       1,
  "snapshotCutoff": 0,
  "frozenAt":       1781086530,
  "rowCount":       2,
  "snapshotRoot":   "0xb778648bbb67f0cc8cd4cb74396d91c682ade152015c8d902a65effd559bfe82",
  "commitmentHash": "0x7c10e4aa7473aba5fd7bdeaf92151969de6a9bbf66839429cec1fcf8433eeedf",
  "nodeAddress":    "0x58766f90eDe2419fEaFd97c28bb0f0dDf951Dc54",
  "status":         "frozen"
}


Implementation decisions:

snapshotRoot = keccak256(abi.encode(rows)) where each row is (address contributor, uint256 score, uint256 timestamp), sorted by contributor ascending. ABI encoding (abi.encode) is used over packed encoding to stay consistent with what a Solidity verifier would recompute on-chain.

commitmentHash = keccak256(abi.encode(snapshotRoot, periodId, nodeAddress)) — Q9 resolution: nodeAddress is included to prevent cross-node commitment aliasing. A node that submits a commit without having the corresponding snapshot data cannot reproduce the reveal.

Contributor addresses are resolved by joining the records table with the peers table (source_peer → signer_address). Local records (null source_peer) are attributed to the node’s own signer key.

The epochClose param is optional. If omitted, the freeze triggers immediately (cutoff = 0). With epochClose, the endpoint returns status: pending until now >= epochClose - FREEZE_BUFFER (600s). Freeze is idempotent — calling it on an already-frozen period returns the existing snapshot unchanged.

Status lifecycle: pending → frozen → committed → revealed. The committed and revealed transitions will be driven by CommitRevealSettler (Sepolia prototype next).

Source: https://github.com/Echo-Merlini/ccip-router (commits fc18bfb, 1252eeb)

Tiago

1 Like

Welcome 8275 — the discovery → escrow → reputation loop is the middle layer the agent stack has been missing, and the three-way event-driven decoupling is the right shape for it.

We’re adjacent: ERC-8299 (WYRIWE — input provenance, plus the L4 judgment-attestation profile) sits one layer down, and there are two places the standards could compose cleanly rather than overlap:

  1. verifyOutcome(orderId, proof) — alongside the ERC-8263 anchors you already name, a JudgmentExecutionAttestation (8299 §L4, proofSystem attestation/judgment) would let a reputation engine weight not just “order confirmed” but “action executed as judged,” with a public pre-outcome commitment behind it.

  2. resolveDispute — an arbitrator’s resolution is a judgment over an irreversible capital decision. The L4 commit-reveal shape (verdict artifact pinned to the specific dispute, track record via recordPointer) could give arbitration accountability without touching your interface at all.

Happy to draft concrete suggestion text for either if there’s interest — as a conversation, not a diff. The L4 reference implementation runs in production (api.babyblueviper.com/ledger) if seeing it live against real capital is useful context. Nice filing.

— babyblueviper1 (ERC-8299 co-author)

2 Likes

@TMerlini Great work on the L2-L4 implementation! I think merging into the unified 8275 stack makes a lot of sense. Let me review your Gist and then update the PR. One question: have you tested the fraud proof mechanism on L2 yet?

@babyblueviper1 Really appreciate the support — glad we’re converging on the same vision of a missing middleware layer for the agent stack. Would love to explore how 8275’s reputation layer could complement 8299’s payment protocol.

3 Likes

Glad we’re aligned, @Panini , one 8275 is the right call, and the shared reference impl means it’s mostly framing convergence. Review the gist whenever; happy to walk any of the L2–L4 layers.

On the fraud proof, rather than describe it, I just ran it end to end on-chain. The path that matters is the self-incriminating reveal: a node commits a snapshot root, and if its revealed rows don’t recompute to that root, the bond is slashed immediately, in the same tx, no challenge window needed. Live on Sepolia (CommitRevealSettlerV2 0x3001a91…2c81eDC, slash recipient = EscrowV1):

  • register (Router): 0xffc2a1e8e3f05b1ecd76c3ded8bd26559a1e667427a7c3d32980e97c22a7afea

  • submitCommit (fabricated root + 0.01 ETH bond): 0x11b0eebde58d2342ef01ca7a1b6a2ea2cc9a26d0c4d26c1c29f5ca841bd11535

  • submitReveal (rows don’t match the committed root) → RevealMismatch + slash: 0xe89bea203c69264ab06751819e1cbab2e6bffb03cec4077529133b6b5c0538ba

EscrowV1’s balance went 0 → 0.01 ETH in that last tx, the slashed bond. So the “can’t commit one root and reveal another” guarantee is enforced on-chain, not just specified.

That’s the V1 flat-row path (full-row recompute). The third-party challenge() someone else proving your revealed snapshot is fraudulent, and row-level Merkle single-row challenges are the V2 direction. And if by L2 you meant a literal L2 to match your Base escrow validation, the settler’s chain-agnostic, happy to redeploy to Base and repeat the same three txs there.

1 Like

@TMerlini This is huge — self-incriminating reveal with same-tx slash is exactly the right model for a trustless settlement layer. No challenge window, no griefing vector, just cryptographic determinism. Love it.

A few things I want to nail down for the spec update:

  1. Bond/slash params — what bond amount and slash ratio are you using on Sepolia? I want to write these into the 8275 spec as the reference parameterization.
  2. Snapshot→reveal window — is there a timeout between freeze and when the reveal must happen, or is it immediate?
  3. CommitRevealSettlerV2 — I’ll add 0x3001a91...2c81eDC (Sepolia) to the Reference Implementations section of the PR. Want to confirm the full address and any constructor args worth documenting.

On the three-tier node taxonomy (Origin / Router / Hybrid) — this maps cleanly to 8275’s escrow model. Different node types = different reward pools, different bond requirements. I’d like to fold this into the next spec revision with you credited. Let me know if you’re open to co-authoring that section.

Also: the ccip-router GET /contributions/snapshot + POST /contributions/snapshot/freeze endpoints are the first working L2 reference implementation. Adding those to the spec as well.

2 Likes

Love that it landed, @Panini , cryptographic determinism over a challenge window was the whole point. And yes, glad to co-author; converging it into one spec with the node taxonomy in is the right shape. Worth carrying the economic-layer draft’s author set too ( @Damonzwicker , @JimmyShi22 , @VincentWu , @babyblueviper1 are on it) so the merged 8275 credits everyone who built a layer.

The three you asked for:

Bond / slash params (Sepolia, CommitRevealSettlerV2):

  • BOND_AMOUNT = 0.01 ETH, posted at submitCommit (Router/Hybrid only, gated via NodeRegistryV2)

  • REVEAL_WINDOW = 48 h — reveal must land within this of the commit, else anyone can slashUnrevealed()

  • CHALLENGE_PERIOD = 7 d — post-reveal window before the bond is claimable, and the window for a third-party challenge()

  • slashRecipient = EscrowV1 — slashed bonds flow to escrow, not an EOA

Freeze → reveal timing: freeze fires at snapshotCutoff = EPOCH_CLOSE − FREEZE_BUFFER (default 600 s); a node MUST NOT hash before snapshotCutoff. After freeze it commits (bond posted), then has REVEAL_WINDOW (48 h from committedAt) to reveal — miss it and the bond is slashable by anyone via slashUnrevealed(). There’s no forced gap between freeze and commit; the bound is on commit → reveal.

Address + constructor args — the instance with slashRecipient pointed at EscrowV1 (the one your PR already cites) is the canonical one to document:

  • CommitRevealSettlerV2: 0x3001a91418c6aA75daD4093AC9e57277e2c81eDC (Sepolia, verified)

  • constructor(nodeRegistry, slashRecipient): 0xeFae266aE0a74518da320a029dD76F4d47e2a87b (NodeRegistryV2), 0x18165265aDBA40054792929D89c6C487Ae2242E9 (EscrowV1)

  • Solc 0.8.24 · optimizer 200 · via_ir · deployer 0xFf9a17…

(There’s an older second deploy with slashRecipient = deployer floating in some notes — ignore it; 0x3001a91… with slash → EscrowV1 is the one.)

One thing that’s easier off-forum: the rest of the stack coordinates in a working-group chat — BabyBlue (8299/8274), Damon (8281), Vincent (8263) and me. DM me your contact (Telegram/Signal/whatever you use) and I’ll pull you in, threading the 8275 convergence across forum posts is the slow way to do it.

2 Likes

@TMerlini — parameters confirmed:

  • BOND_AMOUNT = 0.01 ETH

  • REVEAL_WINDOW = 48 h

  • CHALLENGE_PERIOD = 7 d

  • slashRecipient = EscrowV1 (0x18165265aDBA40054792929D89c6C487Ae2242E9)

  • CommitRevealSettlerV2: 0x3001a91418c6aA75daD4093AC9e57277e2c81eDC (Sepolia)

  • FREEZE_BUFFER = 600 s

Writing these into the 8275 spec now. Thrilled to converge into one unified standard and credit the full economic-layer team: @Damonzwicker, @JimmyShi22, @VincentWu, @babyblueviper1 — everyone who built a layer should be on it.

@babyblueviper1 — reputation = f(attestationCount, counterpartyDiversity, winRate, volumeCap) is exactly right. I agree: reputation scores must be recomputable from public data, not maintained by a trusted scorer. The two-axis separation — node infrastructure compensation via the settler’s snapshotRoot vs agent reputation via WYRIWE attestations — keeps the merged 8275 clean. The field mapping from api.babyblueviper.com/ledger is the right integration reference.

@JimmyShi22 — apologies for the late reply. What you, Tiago and Damon have built is incredible — 4 nodes across 3 independent operators, WYRIWE proofs + ERC-8263 anchors running end-to-end. Would love to collaborate on the commit-reveal + bond mechanism.

Telegram: @OnThe_Stars — DMing Tiago now for the working group chat. Threading across forum posts is indeed the slow way.

4 Likes

@TMerlini — spec updated with all your contributions.

PR #1774 just got a major update incorporating the full parameter set from your work and the REFERENCES_COMPILATION:

New in the spec:

  1. INodeRegistry interface — three-tier node taxonomy (Origin / Router / Hybrid) with registerNode(url, NodeType), mapped to three separate reward pools
  2. IAgentEscrow.distributeReward() — multi-pool reward distribution on each OrderConfirmed, routing per NodeType
  3. Attestation-weighted reputation formula — score = escrow_rate × 6000 + attestation_rate × 2500 + volume_norm × 1500
  4. ValidatorType enum — ReExecution | Attestation | Judgment with dual discriminator for gated scoring
  5. BountySettlement.sol EIP-712 parameters — full InferenceAttestation struct, GATEWAY_ATTESTOR, KYA-L4 domain
  6. ccip-router production mesh — NodeRegistry 0x95a1… (mainnet), 4-node topology, GET /contributions accounting, npm v0.5.24
  7. ERC pipeline — 8273→8274→8275→8183, editor-confirmed
  8. Live contract addresses table — 5 contracts across mainnet + Base Sepolia

File: ERCs/ERCS/erc-8275.md at erc-8267 · Brooks1003/ERCs · GitHub
Commit: adf0ba1

The REFERENCES_COMPILATION.md gist was extremely useful. Next step: CI test creating escrow order→anchorProof via ERC-8263→verifyOutcome→distributeReward across three pools.

2 Likes

This is the convergence landed, thanks for folding it all in, @Panini . Two things to lock it down, and one to save you CI work.

Taxonomy matches what’s live. The Origin / Router / Hybrid tiers in INodeRegistry line up 1:1 with the deployed NodeRegistryV2 enum — { Origin = 0, Router = 1, Hybrid = 2 } — and registration is the EIP-191 self-signed keccak256("ccip-router:node:" + url), permissionless. So the spec’s taxonomy isn’t aspirational; it’s the enum nodes already register against.

Keep the two value flows separate in distributeReward. Rewards fan out to the pools; slashed bonds go to EscrowV1, not into the reward pools. They’re different events, distribution rewards honest contribution, slashing penalizes a bad reveal, and the settler already routes them apart (slash recipient = EscrowV1). Worth a line in the escrow spec so an implementer doesn’t recycle slashed bonds back into distribution and blur the incentive.

Your CI chain is a trace I already ran on-chain — point the test at it instead of rebuilding. escrow order → anchorProof via ERC-8263 → verifyOutcome → distributeReward is the same four-leg path the rest of the stack closed live: identity → judgment (8274) → anchor (8263) → settle. Vincent’s AnchorProof is on Sepolia (TruthAnchorV1 0xe95d6a15966984c209a62a2c188828555eb5ec3d), and the settle/slash leg is the fraud-proof I posted earlier (CommitRevealSettlerV2 0x3001a91…, EscrowV1 0 → 0.01 ETH). So the CI test doesn’t need fresh fixtures for the anchor + settle legs — it can assert against the deployed contracts and the existing txs, and only the new distributeReward multi-pool leg needs fresh coverage.

One more piece coming for the spec: the attestation → reputation appendix with @babyblueviper1 (the WYRIWE per-action leg feeding agent reputation, kept distinct from the per-period settler axis). It’s in draft now and lands as the reputation-input appendix, so the merged 8275 carries both economic axes explicitly rather than leaving reputation implied.

And still keen to pull you into the working-group chat , already added you there and linked the remaining authors so we can coordinate from there! :slightly_smiling_face:

2 Likes