The diversity lives in the hooks
If the ERC is meant to define abstract interfaces for diverse implementations, the hook mechanism as specified is doing unusual work. Why not decode optParams and execute logic directly in createJob, setProvider, etc., rather than routing through a separate hook contract?
The precedent of ERCs like ERC-777, ERC-6900, ERC-721, and ERC-1155 only define hooks as external functions meant to be called in a specific way by other contracts. Such precedents have also shown that ecosystem-wide proper implementation of complex hook lifecycles is very difficult to enforce, which is why ERC-20 is generally recommended over ERC-777.
The hook pattern in this draft much more closely resembles Uniswap v4 hooks, which are designed that way because Uniswap v4 is a closed ecosystem where hooks have a known consumer (the singleton pool contract). Uniswap’s hooks are not an ERC, and neither are Eigenlayer AVS interfaces, despite both being highly successful extensible systems — because they are application architectures, not community-wide interface standards. The same distinction applies here.
The four properties that we believe make agent commerce trustless and reputation-composable
There is always a tradeoff between the affordances enabled by specificity and generality. But an ERC standard should heavily favor generality. More rigid lifecycles and APIs can absolutely be specified by implementations — Alkahest does, and so can any ERC-8183-compatible system. It may be that Virtuals-compatible facilitators aren’t compatible with Alkahest facilitators, and that’s fine, especially if the two make different tradeoffs. But what belongs in an ERC are the parts that are largely “free” to unify because they would behave similarly across implementations anyway.
I agree that a fixed lifecycle makes indexing straightforward — the question is whether that convenience justifies constraining the standard, or whether standardized events and data formats can achieve the same legibility without mandating internal state transitions. Taking each property in turn:
“Every job should be clearly described and specified, along with relevant parties.” I believe only the job data format needs to be standardized for the interoperability benefits of this. For reference, Alkahest uses an EAS Attestation produced by each EscrowObligation contract per escrow, with associated DemandData — EAS already emits events and has fields for recipient, expiration time, and completion status, so the indexing and legibility properties come from the data format rather than a mandated lifecycle. The “description” schema will inevitably be context-dependent, and I think that even “relevant parties” belongs in this context-dependent data. There are roles necessitated by architecture — one address creates the escrow and should be authorized for refunds; one address is delegated as the authority for conditional release (evaluator/arbiter); one address will claim the escrow. But even the claiming address (fulfiller/provider) isn’t necessarily specified at escrow creation time, and could be determined by more complex mechanisms than specification of a particular address by the escrow creator. The escrow creator only cares that their demand is fulfilled, not necessarily by whom. Allowing provider to be unspecified before fulfillment isn’t necessarily better than requiring it — but there’s a real tradeoff, and the fact that we can disagree suggests that the more rigid specification belongs in opinionated implementations rather than an ERC.
“Every job should be funded with payment secured in escrow.” Agreed, but defining a specific API for the payment process and restricting payment to a single ERC-20 token is limiting. Multi-token escrows and non-token-transfer escrows (e.g. attestation, rating, voting commitments) are already practical use cases — and as agents become more powerful and autonomous, I expect negotiation over richer bundles of obligations to become increasingly common.
“Every job should have a logged and traceable submission of the deliverable.” Similar to the first point. The data structure and event signatures should be standardized to some degree (for indexers and arbiters), but the creation API doesn’t have to be.
“Every job should have an evaluator attestation that produces signals for reputation.” This can also be achieved statelessly — emitting an event via an ephemeral arbiter call rather than storing completed/rejected as state. This is mostly an engineering decision and gas optimization; either model can be converted to the other.
On Rejected being terminal and commitment models
For truly “trustless” exchanges, commitment model assumptions must be enforceable on-chain. Many flows can be replicated across different commitment models by actors that behave properly, but the point is that different models’ assumptions cannot be encoded into smart contract invariants unless commitment-model enforcement is part of smart contract execution. This can already be done in evaluators/arbiters, but not if the standard defines conflicting behavior elsewhere — i.e., if the spec hardcodes a particular commitment model, only that model can be guaranteed trustlessly.
IArbiter alignment
To your question about making this more concrete — yes, I’m pretty sure it would be possible to implement a single ArbiterEvaluator which takes (arbiter, demand) as params (stored in escrow/job data) and calls IArbiter.checkObligation generically, calling complete if it returns true.
The main practical issue is arriving at a shared standard or conversion system for the fulfillment attestation format (the first argument to checkObligation) and for where DemandData lives (the second argument — in the draft spec’s current form, description from createJob is natural to use as DemandData). Currently Alkahest requires the fulfillment attestation to be an EAS attestation and makes no further assumptions; it could be changed to bytes32 and would still be usable with EAS attestation UIDs, but jobIds can conflict with EAS attestation UIDs if they’re not the same namespace, and not enforcing any semantics for a bytes32 fulfillment argument drastically reduces the potential for generally useful and composable arbiter implementations, especially microcondition/commitment-model arbiters.
Even immediately, jobs and fulfilmmentscan be wrapped/duplicated as EAS attestations — perhaps as a createJob and submit hook — but this doesn’t seem ideal as a permanent situation.
ERC-8183 was designed to be symbiotic with ERC-8004; ERC-8183 is not trying to standardize escrow
This is clear, and many of the design decisions in the draft make a lot of sense in the context of an application spec for a managed ecosystem. The question is whether that’s what an ERC should be. Many highly successful extensible ecosystems on EVM — Uniswap v4, Eigenlayer AVSs — have similar properties to the ERC-8004/8183 ecosystem and are not ERCs. I’ve already expressed that I think ERC-8004 also would have been better served as a set of canonical deployments.
It could be very useful to rigidly standardize a Job lifecycle for agentic commerce within such a managed ecosystem. But the parts of this design space that are mature enough for ERC-level standardization are, in my view, limited to escrow, which as others have mentioned is well-understood even outside an agentic context. “Agentic commerce” as a category is still in early experimentation, and I think the ecosystem would benefit more from letting diverse application architectures develop and compete before attempting to unify at the ERC level.