This ERC defines a minimal registry interface for committing authorized state
transitions of autonomous-agent memory without placing raw memory in calldata.
Each transition is represented by an ExperienceDelta, identified by an
EIP-712 struct hash, and applied to a linear per-space state
machine. A memory space has a controller and a replaceable authorizer. Both
externally owned accounts and ERC-1271 contract accounts are
supported. Payload semantics, storage, memory taxonomies, inference proofs,
deletion attestations, and markets are intentionally outside the core interface.
Agent systems commonly keep long-lived memory in private databases while using Ethereum for identity, payment, or execution. Existing applications can publish an opaque content hash, but a hash alone does not establish:
Publishing raw prompts, embeddings, preferences, policies, or latent state is incompatible with privacy and is often uneconomical. This ERC therefore commits only to a private delta, optional provenance, an interpretation profile, and an optional private locator. The registry verifies authorization and state-machine continuity while remaining agnostic to the underlying memory engine.
Agent operators, wallet and application developers, auditors, and counterparties need a shared way to refer to an agent's memory history across implementations without disclosing the memory itself. They can verify that a declared state advanced through an authorized, gapless sequence while prompts, embeddings, policies, and other private witness data remain off-chain.
Example uses include carrying a continuity checkpoint when an agent moves between providers, selectively opening evidence to an auditor against a committed transition, and detecting rollback or substitution relative to a known on-chain head. This ERC does not prove that an agent actually used the committed memory, that the private witness is true or available, or that an agent's decisions were correct. It makes the declared state history tamper-evident and attributable.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
hashStruct of an Experience Delta.The initial controller MUST choose a bytes32 salt. The Memory Space identifier
MUST be derived as:
initialController MUST NOT be the zero address. This derivation prevents an
unrelated account from pre-registering an identifier selected by another
controller. The salt MAY remain private until registration.
v1 names the wire format fixed by the ExperienceDelta and MemoryState
type strings, the EIP-712 signing-domain version, and the baseline commitment
domain tags defined below. Changing any of these values changes transition
identifiers, state roots, signing digests, or baseline commitments and is
therefore not wire-compatible with v1.
The following struct and field order are normative:
The fields have these meanings:
spaceId identifies the Memory Space.sequence is a strictly increasing counter beginning at 1.prevStateRoot is the current state root before this transition and is zero
for the first transition.deltaCommitment binds the private memory operation or encrypted delta and
MUST NOT be zero.provenanceCommitment optionally binds inputs, inference attestations, or
other causal material. Zero means absent.profileId identifies the off-chain interpretation and commitment profile and
MUST NOT be zero.locatorCommitment optionally binds a private off-chain locator. Zero means
absent. A raw locator is not part of this interface.Raw memory, salts, encryption keys, and raw locators MUST NOT be supplied to the registry through this struct or any other required core argument.
The exact EIP-712 type string is:
The Transition ID MUST be calculated as:
There is no alternate JSON, JCS, CBOR, or application-specific Transition ID.
The exact state type string is:
After accepting a transition, the registry MUST calculate:
For an empty space the current state root and sequence are zero. A registry MUST
accept a transition only if sequence == currentSequence + 1 and
prevStateRoot == currentStateRoot. It MUST then atomically store the Transition
ID, next state root, and sequence.
The linearity guarantee above is a property of the deployed code, not of the
recorded data. A registry whose implementation can be replaced can be made to
accept a transition violating sequence == currentSequence + 1, while still
reproducing every test vector in this document; passing the vectors and providing
the guarantee are therefore distinct claims.
A conforming registry MUST NOT be deployed behind an upgrade mechanism able to replace the logic enforcing sequence linearity, state root chaining, or signature validation, and MUST expose no upgrade authority over that logic. Extensions and off-chain tooling MAY be upgraded independently, provided they cannot alter the acceptance rules above.
All registration, authorization-update, and transition signatures MUST use the EIP-712 domain:
The signed digest is:
The domain prevents a signature from being replayed on another chain or another
registry. A transitionId remains a chain-independent content identifier; its
signature does not.
A spaceId is derived from the controller and salt only, so it is stable across
chains. The same Memory Space identifier can therefore be used for histories on
more than one chain. Two chains MAY hold different histories under the same
spaceId, so (spaceId, transitionId) alone does not determine which history is
meant.
A conforming transition reference MUST identify the registry address and the
chain on which that registry is deployed, in addition to spaceId and
transitionId. The chain context MAY be implicit when the reference is emitted
on the same chain as the registry.
This is a verification requirement, not only a resolution convenience. The
signing domain sets verifyingContract to the registry address, so the signed
digest cannot be reconstructed — and the authorizer's signature therefore cannot
be checked — without knowing which registry accepted the transition. An otherwise
complete reference that omits the registry or chain context is not independently
verifiable.
Registration MUST bind the Space to non-zero controller and authorizer
addresses. The supplied spaceId MUST equal deriveSpaceId(controller, salt).
The registration struct is:
The controller MUST authorize its EIP-712 struct hash. A Memory Space MUST be registered at most once. A relayer MAY submit the authorization without becoming controller or authorizer.
The controller MAY atomically replace both controller and authorizer. Each Space
maintains a uint64 configNonce, initially zero. An update MUST use
nonce == currentConfigNonce + 1 and the struct:
The current controller MUST authorize the update. Both replacement addresses MUST be non-zero. The nonce prevents replay of an earlier configuration.
A registry MUST NOT select between ECDSA and ERC-1271 validation by account code
presence alone. An externally owned account delegated under EIP-7702
carries code of the form 0xef0100 || delegate, and many delegates implement no
signature policy; branching on code presence would reject those accounts outright.
A signature satisfying either scheme MUST be accepted, evaluated in this order. When
the authorizer has non-empty code, the registry MUST first call isValidSignature as
specified by ERC-1271 and accept the signature on the 0x1626ba7e magic value.
Otherwise, or when that call reverts, returns fewer than 32 bytes, or returns any other
value, the registry MUST recover the signer from a canonical, non-malleable 65-byte
ECDSA signature and require equality with the configured account. A signature of any
other length MUST be rejected without attempting recovery.
A registry MAY accept an empty signature when msg.sender is exactly the account
whose authorization is required. It MUST NOT treat an empty signature submitted
by any other caller as authorized.
Profiles MAY define stronger schemes, including zero-knowledge commitments. A conforming implementation SHOULD support the following domain-separated baseline:
Each salt is 32 bytes and SHOULD be independently sampled. For low-entropy
plaintext, the salt MUST remain secret or payloadBytes MUST be ciphertext
produced with a fresh high-entropy key and nonce. A public salt does not prevent
targeted dictionary attacks against low-entropy content.
Implementations MAY expose additional read methods but MUST NOT change the meaning of the normative functions, hashes, or events.
An implementation MAY record block.timestamp as the time at which a transition
was observed on-chain. Application-supplied timestamps MUST NOT determine
transition ordering. Timestamps inside private payloads remain profile data.
This ERC does not define agent identity, raw memory storage, data availability, retrieval, a universal memory taxonomy, inference verification, branching or merge rules, deletion claims, licensing, payment, tokenization, cross-chain migration, or machine consciousness. Such systems MAY reference a Space, Transition ID, or state root without becoming a dependency of the core.
A fixed-width struct is straightforward for independent implementations while binding state, private change, provenance, interpretation, and location. Removing authors and timestamps from the Delta avoids confusing self-asserted metadata with registry authorization or chain observation.
A previous-record pointer proves only list linkage. Binding the exact prior state root and computing the next root makes the transition relation explicit and prevents an update from claiming an unrelated prior memory state.
The controller is an administrative recovery boundary. The authorizer may be a hot EOA, multisignature account, smart account, or policy contract. Rotation does not change the Space identifier or its state history.
A public URI can leak storage topology, tenant identifiers, or access tokens. A locator commitment is signed, cannot be replaced by a relayer, and can be opened selectively to an authorized retriever.
Text, vectors, tool traces, policies, and model-specific latent representations
evolve independently. profileId lets applications define these semantics
without freezing one product taxonomy into the core registry.
Deletion attestations and memory markets have different trust, authorization, and security requirements. Keeping them outside this interface allows the state primitive to be reviewed and implemented without adopting those claims.
This ERC introduces a new interface and does not change an existing standard.
Early prototypes that used JCS identifiers, unsigned URI arguments, fixed memory
enums, or previousDelta pointers are not wire-compatible with v1 and require an
explicit migration checkpoint into a new Space.
For the canonical v1 vector:
The complete input, private commitment witnesses, domain separator, signing digest, registration hash, and authorization-update hash are provided in the machine-readable test vector.
The reference implementation contains a Solidity registry
(AgentMemoryStateRegistry.sol,
implementing IAgentMemoryState.sol),
which reproduces the golden vector linked above.
keccak256(rawMemory) is not a hiding commitment for low-entropy values. A salt
prevents precomputation but does not prevent targeted guessing when the salt is
public. Sensitive or low-entropy payloads therefore need encryption or a secret
salt, as required in the Specification.
Even private commitments expose timing, update frequency, Space relationships, and profile identifiers. Reusing salts, ciphertext, or locator witnesses can also reveal equality. Profiles can mitigate this with padding, batching, and salt or key rotation where the leakage matters.
A compromised authorizer can append valid-looking state. A compromised controller can replace the authorizer or controller. Deployments are advised to use contract-account policies, threshold authorization, spending or rate limits, and operational recovery procedures appropriate to the value of the Space.
ERC-1271 validation is external code execution through STATICCALL. The
Specification requires the exact magic value, handling of reverts and malformed
return data, and completing authorization before state is mutated; an
implementation that relaxes any of these accepts forged authorization.
An account delegated under EIP-7702 carries code while its underlying key stays valid, so code presence alone does not separate a contract account from an externally owned one. Deciding validation by code presence locks out delegated accounts whose delegate implements no signature policy. Conversely, because delegation does not revoke the key, a delegate policy is not the only authorization path: a valid ECDSA signature from the underlying key still authorizes a transition. Deployments that rely on a delegate's threshold, spending, or session policy need to account for that residual path, and should treat key custody as equally sensitive after delegation.
The EIP-712 domain prevents cross-chain and cross-registry signature replay.
spaceId, sequence, prior root, and locator commitment prevent a relayer from
moving or modifying a signed transition. A relayer can still withhold a valid
transaction or race another submission of the same transition.
A valid commitment proves neither data availability nor truth of the committed memory. It proves that the configured authorizer approved a state transition. Applications requiring availability, inference correctness, or provenance truth need separate mechanisms, and cannot infer them from this registry alone.
Neither revocation nor key-destruction evidence can prove universal erasure of data already copied by another party. Extensions are expected to describe deletion records as attestations with a stated scope, not as absolute proofs of deletion.
An upgradeable registry can change hashing or authorization semantics after users sign transitions. Because a replaced implementation can accept a transition that violates sequence linearity while still reproducing every published test vector, non-upgradeability of the enforcing logic is a precondition of the non-forgeability property rather than a deployment preference. It is stated normatively under "Immutability of the enforcing logic" in the Specification, and repeated here because a requirement stated only in this section is read as informative.
Evidence that no upgrade authority exists can include empty ERC-1967 implementation and admin slots, plus deployed source that exposes no owner, admin, initializer, or proxy. These checks assess deployment immutability; vector conformance alone does not establish it.
Copyright and related rights waived via CC0.