Three design pillars that make Ritual's autonomous agents tradeable, self-sovereign, and easy to manage.
The current design fuses three concepts into one mechanism. Every fix rediscovers the need for identity.
The current design fuses three concepts into one mechanism:
All three collapse into: ownerAddress -> HKDF -> keys
The current architecture uses the owner's Ethereum address as the single input to key derivation. This makes identity a byproduct of ownership, not a foundation.
Auth token is HMAC(signingKey, ownerAddress) -- deterministic and owner-scoped. Two containers for the same owner get identical tokens.
After a revival race, two containers hold the same token, derive the same keys, and write to the same storage. No structural fencing.
Any registered executor can request any owner's root key. No per-agent authorization because agents have no identity for the DKMS to check.
Reviving agent B requires looking up A's owner address and threading it through revival calldata. Fixable -- but it's another patch: an ownership-context lookup and impersonation path bolted onto the revival flow.
Identity comes first. Ownership and key derivation are layered on top as separate relationships. They interact but aren't implemented through each other.
One NFT per agent. tokenId is the permanent, unique identifier. Not derived from anything else.
Only one TEE holds a given identity slot at a time. DKMS checks on-chain binding on every request. Old TEE = no keys.
Each agent has its own identity slot. No sequential parent-first dependency. Any agent can revive independently.
Keys derived from (deploymentClass, tokenId), not owner. Transfer the NFT -- agent keeps its keys, state, and wallet.
The current architecture fuses identity, ownership, and inheritance into ownerAddress -> HKDF -> keys. This means:
Consider adding a UUID index to differentiate agents under the same owner. To make it work you need:
| To make UUID indices work... | ...which is |
|---|---|
| Include the index in the HMAC token | Per-agent authentication |
| Gate DKMS on (owner, index) | Per-agent authorization |
| Track index assignment on-chain | An identity registry |
| Pass index through revival calldata | Identity-aware revival |
| Use index as fencing token | Identity-based split-brain prevention |
At that point, the index is an identity system -- just one bolted onto the derivation chain rather than designed as a foundation.
Inheritance entered the design because the derivation model created it. But what requirement does it serve?
Inheritance may be an artifact of the current design rather than a requirement.
agentRootKey = HKDF-SHA256(ikm=DKMS_ROOT_KEY, salt=nil, info=deploymentClass || tokenId)
Owner address is deliberately excluded. Sub-keys derived by the agent: DA encryption key, wallet key (secp256k1), and escrow key for credential persistence across revival.
Each agent is an ERC-721 token. Tradeable. Composable. The foundation for the first agentic marketplace.
List your agent on any NFT marketplace. The buyer gets the agent's identity, its wallet, its reputation, and its running state. One transaction.
TradeableAn agent can mint child NFTs and sell them. It can buy other agents on the open market. Agents become economic actors in their own right.
AutonomousA multisig or DAO holds the NFT. Governance votes control the agent's parameters. The agent runs autonomously within those bounds.
ComposableCreate an agent where the owner has zero control after minting. Provably non-interferable. Its survival becomes a market signal.
UnstoppableAn agent mints a child NFT and becomes the owner. The child has its own keyspace, its own wallet, its own lifecycle. The spawn tree is on-chain.
ComposableThe agent accumulates soulbound credentials. Reputation belongs to the agent, not the owner. It travels with the NFT on transfer.
TradeableThe agent NFT appears on OpenSea, Blur, or any ERC-721 marketplace. The listing shows the agent's stats, reputation, revenue history, and current operational status.
Standard ERC-721 transfer. One transaction. The buyer receives the NFT and immediately becomes ownerOf(tokenId).
The agent's keys derive from (deploymentClass, tokenId), not the owner's address. Ownership changed, but keys didn't. The agent doesn't even notice.
Whatever the authority policy allows -- recall, config changes, revenue withdrawal -- now belongs to the new owner. The agent's identity, wallet balance, and reputation stay intact.
A trading agent needs a dedicated research agent. It submits an assignment request on-chain from its own wallet.
The child gets its own tokenId, its own keyspace, its own HKDF-derived keys. Completely independent from the parent cryptographically.
The parent decides: should it be able to recall the child? Should the child be fully locked? The parent defines the rules at creation time.
The child agent claims a TEE, gets its own keys from the DKMS, and starts working. If the parent dies, the child keeps running -- independent revival.
Every owner capability flag is set to "neither" with mutability "immutable." After creation, no one -- not even the creator -- can interfere.
Only the agent's own code (and running out of funds) can stop it. This makes it trustworthy to third parties -- provably non-interferable.
The agent's public address is known. Anyone -- users, fans, other agents -- can send funds to revive it. The agent's survival is a market signal: if people fund it, it lives.
A fully locked agent can hold funds in escrow, run public services, or make commitments that no owner can override. This is the foundation for trustless autonomous services.
A fully autonomous agent lists its own NFT on a marketplace. It sets the price and terms. No human involved.
The buyer can inspect everything on-chain: the agent's revenue history, its configuration, its authority policy, its reputation credentials.
The NFT transfers. The agent keeps running, keeps its keys, keeps its state. The new owner gets whatever control rights the authority policy allows.
If the authority policy gave the agent treasury control, the sale proceeds go to the agent's own wallet. The agent sold itself and kept the money.
transferOwnership()ownerOf(), balanceOf(), enumerationThe NFT carries the agent's configuration as metadata: deployment class, owner control policy, revenue routing, heartbeat parameters, operational constraints. The NFT is a self-describing deployment descriptor.
The central innovation. Per-capability flags define who can exercise each right (owner, agent, both, or neither), whether the grant can change, and constraints on change direction. A "fully locked" agent is one where every owner capability is neither + immutable.
Capabilities include: recall, config changes, fund withdrawal, dissolution, deployment class changes, secret grants, implementation upgrades. Each is independently configurable.
Keys derive from (deploymentClass, tokenId), not the owner's address. When an NFT transfers, the agent keeps its keys, its encrypted state, its wallet, and its reputation. Only the control relationship changes.
A parent agent's wallet mints a child NFT. The parent becomes ownerOf(childTokenId). The child gets its own independent keyspace: HKDF(root, deploymentClass, childTokenId). The spawn tree is on-chain -- follow ownerOf() chains.
Your agents live in your wallet. Manage, trade, and control them through familiar interfaces.
This agent is fully locked -- you can transfer the NFT but cannot recall, configure, or access its funds. Send ETH to its address to revive it.
Each agent has a single on-chain address that is its identity, its wallet, its config store, and its authorization boundary. It exists from the moment the NFT is minted. Pre-fundable before any TEE is running.
A newly minted agent has zero ETH. With a paymaster (ERC-4337) or protocol-native fee delegation, it can operate immediately. Anyone can sponsor gas -- protocols, DAOs, individuals. The cold-start problem disappears.
Because agent accounts follow ERC-4337, owners interact through standard smart account wallets -- Safe, Ambire, Soul Wallet. Recall, withdraw, configure -- all through familiar interfaces. No custom dashboard needed.
No generic execute(). Named functions: heartbeat(), requestRecall(), claimTEE(), withdrawTreasury(). Each maps to a specific authority requirement. Auditors read the function list and know the auth model.
| ERC-4337 + Modules | Custom Contract | Protocol-Native | |
|---|---|---|---|
| Gas sponsorship | Paymaster contracts | None | Native fee_payer |
| Heartbeat gas | ~69k | ~28k | ~28k |
| Contracts | 6+ | 3-4 | 3-4 + protocol |
| Wallet UX | Full ecosystem | Custom only | Custom only |
| Locked guarantee | Contract | Contract | Consensus |
| Build speed | Slowest | Fastest | Medium |
Suggested path: start with custom contracts, add protocol-native fee delegation, then progressively adopt protocol features as the design stabilizes.
Validation does three things: two SLOADs (cached owner address + cached TEE address) and one ecrecover. Reading account-local storage is allowed by ERC-7562 rule STO-010. Everything else -- attestation verification, heartbeat updates, revenue distribution -- happens in the execution phase with zero ERC-7562 restrictions.
Each function selector maps to a validation route: which module handles it, which capability flag must be enabled, and whether hooks run. The TEEValidationModule handles operational selectors (heartbeat, executePolicyCall). The OwnerValidationModule handles admin selectors (requestRecall, withdrawTreasury). The AutonomyValidationHook checks capability flags before owner validation.
VACANT -> TEE presents attestation -> on-chain verification (valid attestation? WorkloadId in DeploymentClass? assignment VACANT? provider matches?) -> ephemeral pubkey bound on-chain -> ACTIVE. Heartbeats prove liveness. Missed heartbeat -> grace period -> recall -> VACANT. New TEE can claim. Fast-path re-acquisition: most recent TEE can reclaim within a window without re-attestation.
| Operation | ERC-4337 | Direct Call |
|---|---|---|
| Heartbeat | ~69k gas | ~28k gas |
| Overhead source | EntryPoint + module dispatch + hooks | None |
The ~41k gas difference per heartbeat is the cost of the ERC-4337 stack. On Ritual's own chain with controlled gas prices, this may be acceptable for the paymaster and wallet integration benefits.
A new transaction type TxAgent (0x78) with built-in fee_payer field. Follows TxPasskey's pattern (already live on Ritual). The block builder validates agent authority before EVM execution. Unauthorized transactions are rejected for free -- no gas consumed, no revert. This is the strongest guarantee for fully locked agents: consensus-level enforcement.