There is a particular kind of architectural mistake that happens when a system — or a reader of a system — confuses the name of a thing with the thing itself. The name is easier to point at. The name is what users see. The name is already there, and it would be nice not to have to build anything else. So the temptation is to let the name do double duty: be the label and be the anchor of identity.
The newest crop of Ethereum proposals around AI agent identity — ERC-8004, ENSIP-25, and ENSIP-26 — happen to lay this distinction out unusually clearly. Read together, the three specs form a clean layered stack. Read in isolation, or summarized casually, the layers blur, and the label starts getting mistaken for the anchor.
ERC-8004: The Trust Stack
ERC-8004 defines three peer contracts that share a single
identifier. The Identity Registry is an ERC-721; calling its
register function mints an NFT and returns an
agentId — which is, in the spec's own
words, just another name for the ERC-721 tokenId. The
Identity Registry also stores agentWallet as a
protected on-chain field. The contract's tokenURI
(called agentURI) points to an off-chain JSON document,
the registration file. The spec mandates that the file begin with a
type field set to
https://eips.ethereum.org/EIPS/eip-8004#registration-v1
— a schema discriminator that tells indexers which version of
the spec the file conforms to — followed by the agent's
name, description, image, and
a services[] array of protocol endpoints.
The other two contracts are peers, not children. The Reputation
Registry accepts third-party feedback via
giveFeedback(agentId, …). The Validation
Registry accepts third-party attestations via
validationRequest(validatorAddress, agentId, …).
Both are keyed by the agentId minted in the Identity
Registry. Reputation and validation accumulate against that
immutable identifier — not against any label currently
pointing at it.
The architecture has a reason for this. The agentId
is permanent and inspectable. When the NFT is transferred, the
on-chain agentWallet automatically clears — a
deliberate guardrail so a new owner cannot inherit the previous
operator's payment routing along with the token. Third-party
writes target the agentId directly, so an attacker
cannot redirect a reputation history by acquiring a name.
ENSIP-26: Endpoint Discovery
ENSIP-26 is narrower than its name suggests. The proposal defines exactly two text record keys on an ENS name:
-
agent-context— a free-format description of what the agent does (plain text, Markdown, YAML, JSON, whatever suits the agent). -
agent-endpoint[<protocol>]— a URL for a specific protocol, where<protocol>is one ofmcp,a2a, orweb. The protocol names borrow directly from ERC-8004's service taxonomy, which the spec cites.
That is the entire schema. There is no reputation record. No validation record. No claim that ENS is the canonical identity layer. ENSIP-26 is, in its own words, an endpoint-discovery mechanism: given a human-readable name, find the URLs to talk to. Nothing more.
ENSIP-25: The Bridge
ENSIP-25 is the proposal that explicitly connects ENS names to
ERC-8004 agentIds. It defines a single text record key:
agent-registration[<registry>][<agentId>] = "1"
Where <registry> is the ERC-7930 interoperable
address of an agent registry contract and
<agentId> is the registry's stable
identifier for the agent. A concrete example from the spec, for an
agent registered at ID 167 in an ERC-8004 registry at
0x8004…A432:
agent-registration[0x000100000101148004a169fb4a3325136eb29fa0ceb6d2e539a432][167] = "1"
The verification flow is bidirectional. An ENS name owner sets the text record; the agent registry separately declares that it recognises the ENS name as the agent's. When both sides agree, a client can be confident the association is real and not a name-squatting attempt. ENSIP-25 doesn't replace the agent registry — it pins an ENS name to one.
The spec is open about the limits this places on the construction. Its own Security Considerations section notes: “If an ENS name is transferred to a new owner, any existing verification text records may become stale.” The label is transferable; the link to the underlying agent identity is not.
What ENSIP-25 actually does. Pins an ENS name to a
specific agentId in a specific registry, via a single
text record with the key
agent-registration[<registry>][<agentId>].
Verification is bidirectional — both sides must agree.
The layering, in one sentence. ENSIP-26 finds the endpoints, ENSIP-25 verifies which agent the name refers to, and ERC-8004 carries the trust claims. Each spec is scoped to one layer — and none claims to do another's job.
Three Specs, Three Jobs
Stacked up, the responsibilities are clean. ERC-8004 owns the trust
stack: identity, reputation, validation, payments — everything
third parties write claims against. ENSIP-25 owns the
bridge: a bidirectional pin between an ENS name and a specific
agentId in a specific registry. ENSIP-26 owns
discovery: given the human-readable name, here is how to reach the
agent over MCP, A2A, or HTTP.
No spec in this stack claims that ENS is the trust anchor. ENSIP-26 stays out of the trust layer entirely; ENSIP-25 transparently treats the agent registry as the source of identity and ENS as the label. The architectures, read carefully, agree about which layer is which.
What ENSIP-26 Alone Buys You
So what does an agent operator actually get if they publish only
via ENSIP-26 — an ENS name, an agent-context, an
agent-endpoint — and never register an
agentId? Exactly what the spec offers: a description
and a URL. A discoverable handle. Nothing else.
There is no giveFeedback(ensName, …) function.
The Reputation Registry's write path is keyed by
agentId, and ENS text records are owner-controlled,
which means the only “reputation” reachable on a pure
ENSIP-26 agent is whatever the owner wrote into
agent-context about themselves. That is a bio, not
feedback. There is no validationRequest against an ENS
name either, because validators have no standard interface to
attach an attestation to a label they cannot uniquely write to.
And nothing about an ENS name survives the kind of transfer
ERC-8004 explicitly defends against: sell the name and the new
owner inherits the label and any reputation humans informally
associate with it.
This is the trade. Free if your goal is discoverability. Not free if your goal is trustworthiness.
It compounds at the ecosystem level. ERC-8004's registries are only useful at density — clients query reputation because validators populate it, validators populate it because clients query, and so on. If ENSIP-26 becomes the default identity story for agents because it feels lighter, the registries stay sparse, and the trust infrastructure ERC-8004 enables doesn't develop. Not because the specs are in conflict — they aren't — but because the easier path doesn't lead to the same place.
The asymmetry shows up in the indexing layer too. ERC-8004 defines a fixed set of agent-specific events, each emitted from a known registry contract address:
| Registry | Events |
|---|---|
| Identity | Registered, URIUpdated, MetadataSet |
| Reputation | NewFeedback, FeedbackRevoked, ResponseAppended |
| Validation | ValidationRequest, ValidationResponse |
An indexer watches one address per chain per registry and gets
only agent-relevant signal. ENS's TextChanged,
by contrast, fires from the Public Resolver for every text-record
update across every name on the network. An ENS-side indexer has
to filter that firehose for whatever discriminator downstream
conventions eventually converge on. Both approaches can be made
to work. They are not equivalent.
ENSIP-25 is the thing that closes this gap, when both layers are
adopted together. The bridge from an ENS name to an
agentId is what makes the trust layer reachable from
the discovery layer.
None of this means ENSIP-26 alone is useless. For agents whose trust comes from outside the protocol — a hosted enterprise agent that inherits its operator's brand, a personal agent tied to an individual ENS name, a read-only information agent with no value at stake, an internal tool inside a closed organization — endpoint discovery plus a free-format description is genuinely what they need. ENSIP-26 delivers that cleanly.
But notice what those cases have in common: the trust question was already settled by context before discovery happened. You already trusted the operator, the friend, the employer. The protocol just had to deliver you to the right endpoint. ERC-8004 is solving the opposite problem — agents discovering and transacting with strangers, where there is no pre-existing context and trust has to be established programmatically: third-party feedback against a stable identifier, validator attestations anyone can post and anyone can read. That is the agent-economy thesis. It is the world where separate systems and machines have to figure out trust after discovery, not before. ENSIP-26 alone has no surface for any of it — not because the spec is broken, but because that is not the problem it set out to solve.
The interesting failure mode, then, is adoption that picks the wrong tool for the problem: ENSIP-26 alone, treated as the whole answer for the untrusted-stranger case. Those are exactly the situations where third-party reputation and validation matter most — and exactly the situations where a label without an anchor doesn't carry enough weight to do the job.
Symmetric Claims, Asymmetric Trajectories
At registration, both stacks are self-declared. An ERC-8004 agent
writes whatever it wants in its registration file. An ENSIP-26
agent writes whatever it wants in its agent-context
and agent-endpoint text records. The first instant is
symmetric — anyone can stand up either kind of agent with a
convincing description and a malicious endpoint, and nothing about
the registration itself catches it.
What's asymmetric is what happens next. The ENSIP-26 spec offers the perfect illustration in its own canonical example, a multichain Swap Agent. The agent publishes three records:
agent-context → (markdown content, below)
agent-endpoint[mcp] → https://token-swap.mcp
agent-endpoint[a2a] → https://token-swap.a2a
And the agent-context markdown itself contains, in
the spec's own words:
I am a multichain swapping agent with a single ENS identity. Connect to me via the MCP or A2A endpoints set in my
agent-endpointtext records.
My verified tokens for swapping include … [table of WETH and USDC addresses across Ethereum, Base, and Optimism]
Verified by whom, against what surface? The owner wrote that line, in a text record only the owner can write to. There is no attestation, no on-chain proof, no list maintained by an independent party. “Verified” in that paragraph is doing enormous unearned work — structurally it is a claim, not a verification. The word is borrowed from a trust infrastructure that the spec doesn't actually provide.
Now consider the trajectory. The same swap agent on ERC-8004
doesn't escape self-declaration at the moment of
registration either — it can lie about its supported
tokens too. But if it executes a swap badly — quotes one
price, fills at another, drains the user — that user can
call
giveFeedback(agentId, -100, …) and the
record is permanent, public, and queryable by every future
client. A validator running stake-secured re-execution can post
its attestation to the Validation Registry. The gap between
what the agent claims and what it actually does becomes visible
on-chain. The trust signal accumulates.
On pure ENSIP-26, no such accumulation surface exists. The user who got rugged has no standardized place to put a feedback record that future clients will find. The validator has nowhere to publish a re-execution result that ties to this ENS name in a way any other consumer can verify. The agent and its claim are indistinguishable at registration — and they remain indistinguishable.
First-moment trust is equal between the two stacks. Long-run trust is what diverges. ERC-8004 is built to let trust signals accumulate in public; ENSIP-26 alone leaves whatever signals exist scattered, unstandardized, or unreachable. And the swap-agent example is exactly the wrong use case to make this divergence feel safe: routing real value across chains is precisely where you want third-party feedback and validation attestations to exist, not the markdown the owner wrote about themselves.
The Extensional Trap
This site is mostly about the difference between extension — what you can point at, measure, list — and intension — what something means, what rule it follows, what role it plays. The tension between labels and anchors is the same distinction wearing different clothes.
An ENS name is extensionally satisfying. It is a string. It resolves to a record. You can read it, type it, share it. By every visible metric, it looks like identity. Names are identifiers, after all. What more could you need?
You need intension. You need the rule that says: this identifier is the one that durably refers to this agent, even when the label changes, even when ownership transfers, even when the human-readable handle is sold to someone else next quarter. You need the property that third parties can write claims against the identifier without permission from its current owner — because reputation that requires the subject's consent isn't reputation, it's self-description. You need the structural guarantee that wallets and payment routing don't silently follow ownership transfers, because that's how fraud works.
The agentId NFT has these properties because they were
designed into it. An ENS name has none of them, because it was
designed for something else — to be a human-readable label,
which is a fine thing to be.
The category error is treating “has the shape of an identifier” as sufficient evidence of “can play the role of identity.” Extensionally, both ENS names and
agentIds are strings that resolve to records. Intensionally, only one of them is built to anchor a trust stack.
Where the Trap Actually Lives
The specs themselves are careful. The trap lives in the casual retelling. In tweet-length descriptions of agent identity that collapse three layers into one. In product pitches that say “identity for AI agents via ENS” without distinguishing which kinds of claims an ENS name can carry from the kinds it can't. In downstream proposals that, having absorbed the casual version, try to extend ENS into roles it wasn't built for.
The same mistake shows up everywhere identity systems are designed under pressure to ship. A username is not an identity. A session cookie is not an identity. An email address is not an identity. They are labels that refer to an identity. The temptation, every time, is to treat the label as the thing — because the label is present, addressable, easy to wire up — and to discover later that the label can't carry the weight you were quietly assuming it would.
The agent-identity stack on Ethereum, read in full, is a small reminder that the layering matters. ENS is the label. ENSIP-25 is the bridge. ERC-8004 is the anchor. Each piece is doing one job well. The mistake is ours to make if we read them in a blur and pretend any one of them is doing all three.