Migration Guide: ERC-8004 pre-v1 (legacy) → v1.1
Date: January 9, 2026
Impact: BREAKING CHANGES - Action Required
Naming note: The legacy release is referred to here as pre-v1 (legacy). All prior references to "v0.4" map to this pre-v1 legacy release.
⚠️ Validation Registry Note: This migration guide covers Identity Registry and Reputation Registry (Feedback) changes only. The Validation Registry specification is UNSTABLE and PENDING FINALIZATION. See Validation Data Profile for the current draft and status tracking.
Overview
ERC-8004 underwent significant updates in January 2026 (Contract PR #11) that simplify the specification and improve usability.
Quick Summary
| Area | pre-v1 (legacy) | v1.1 | Breaking? | Scope | Applies To |
|---|---|---|---|---|---|
| Tag Types | bytes32 | string | ✅ YES | OnChain Interface + OffChain | Feedback (Reputation) |
| URI Naming | feedbackUri | feedbackURI | ✅ YES | OffChain JSON Only | Feedback (Reputation) |
| FeedbackAuth | Required | Removed | ✅ YES | OnChain Interface + OffChain | Feedback (Reputation) |
| Endpoint | — | NEW | ⚠️ Addition | OnChain Interface + OffChain | Feedback (Reputation) |
| feedbackIndex | Calculated | From event | ⚠️ Changed | OnChain Event Only | Feedback (Reputation) |
Scope Legend:
- OnChain Interface: Changes to
giveFeedback()function signature orNewFeedbackevent - OffChain JSON Only: Changes only to the off-chain feedback data structure (no contract changes)
- OnChain + OffChain: Changes affect both the contract interface and off-chain data format
Document Scope:
This guide covers Feedback (Reputation Registry) changes only. For Agent (Identity Registry) migration, refer to Agent Metadata Standard.
Most Important Changes (Read This First)
1. FeedbackAuth Removed (CRITICAL) — Feedback Registry
What changed
- The old spec required agents to generate
feedbackAuthsignatures pre-authorizing clients to submit feedback. - The new spec removes
feedbackAuthentirely:- OnChain:
giveFeedback()function no longer includes thefeedbackAuthparameter - OffChain: The feedback JSON no longer includes a
feedbackAuthfield
- OnChain:
Why it matters
- This is the biggest trust-model change in v1.1: it removes pre-authorization friction and changes spam resistance approach.
- Feedback submission is now direct (any client can call
giveFeedback()directly). - Spam/Sybil protection is now enforced off-chain through indexing, filtering, and reputation aggregation.
Concrete interface impact
pre-v1 (legacy) giveFeedback():
giveFeedback(uint256 agentId, uint8 score, bytes32 tag1, bytes32 tag2,
string feedbackUri, bytes32 feedbackHash, bytes feedbackAuth)v1.1 giveFeedback():
giveFeedback(uint256 agentId, uint8 score, string tag1, string tag2,
string endpoint, string feedbackURI, bytes32 feedbackHash)2. Tag Types Changed: bytes32 → string — Feedback Registry
What changed
- OnChain: Contract interface now uses
stringfortag1,tag2(both in function params and event) - OffChain: JSON tags change from hex-encoded
bytes32to plain strings
Why it matters
- Removes encoding/decoding complexity for both onchain and offchain implementations
- Makes tags human-readable in events and off-chain data
- Simpler for indexers and data consumers
3. FeedbackIndex Now Emitted in Event — Feedback Registry
What changed
- pre-v1 (legacy):
feedbackIndexwas calculated by subgraph (tracking per-client-per-agent count) - v1.1: Contract emits
feedbackIndexdirectly in theNewFeedbackevent
Why it matters
- Indexers no longer need to maintain and calculate feedback counts
feedbackIndexis now a first-class on-chain attribute- Simpler and more reliable feedback ordering per (client, agent) pair
What Changed (Detailed)
Scope Key:
- [OnChain] = Changes to smart contract interface (function signatures, events)
- [OffChain] = Changes to off-chain JSON feedback data structure only
- [Both] = Changes affect both contract and JSON format
1. Tag Type Change: bytes32 → string [Both] — Feedback Registry
pre-v1 (legacy) (hex-encoded tags):
OffChain JSON:
{
"tag1": "6465666900000000000000000000000000000000000000000000000000000000",
"tag2": "616e616c7974696373000000000000000000000000000000000000000000000000"
}OnChain Contract:
// ReputationRegistry.giveFeedback()
function giveFeedback(uint256 agentId, uint8 score, bytes32 tag1, bytes32 tag2, ...)v1.1 (plain string tags):
OffChain JSON:
{
"tag1": "defi",
"tag2": "analytics"
}OnChain Contract:
// ReputationRegistry.giveFeedback()
function giveFeedback(uint256 agentId, uint8 score, string tag1, string tag2, ...)Impact:
- ✅ OnChain: Function signature changes from
bytes32tostringparameters - ✅ OnChain:
NewFeedbackevent now emitsstring indexed indexedTag1, string tag1, string tag2instead ofbytes32(note:indexedTag1is indexed for efficient filtering,tag1provides the actual value) - ✅ OffChain: JSON tags no longer hex-encoded; use direct strings
- ✅ Removes encoding/decoding complexity
- ✅ Makes tags human-readable in events and logs
2. URI Naming: feedbackUri → feedbackURI [OffChain] — Feedback Registry
This change affects only the off-chain JSON data structure. The onchain contracts already use feedbackURI.
pre-v1 (legacy) OffChain JSON:
{
"feedbackUri": "ipfs://QmXxx..."
}v1.1 OffChain JSON:
{
"feedbackURI": "ipfs://QmXxx..."
}Why? Matches standard camelCase for acronyms (Web3 convention): feedbackURI not feedbackUri
Impact:
- ✅ OffChain Only: JSON field name change in feedback data structure
- ✅ Consistency with camelCase acronym conventions
- ✅ Aligns with onchain contract naming
3. FeedbackAuth Removed (CRITICAL) [Both] — Feedback Registry
This is the most significant change affecting both the onchain contract interface and off-chain data structure.
pre-v1 (legacy) - Pre-authorization flow required:
OffChain JSON:
{
"feedbackAuth": "0x1234567890abcdef...",
"score": 95,
"tag1": "defi"
}OnChain Submission Flow:
- Client must first request authorization from the agent
- Agent generates
feedbackAuthsignature (pre-approving this client) - Client calls
giveFeedback(..., bytes feedbackAuth)with the signature - Contract validates the signature onchain
v1.1 - Direct submission (no pre-authorization):
OffChain JSON:
{
"score": 95,
"tag1": "defi"
}OnChain Submission Flow:
- Any client can directly call
giveFeedback(agentId, score, tag1, tag2, endpoint, feedbackURI, feedbackHash) - No pre-authorization signature required
- No
feedbackAuthparameter in contract function
Impact:
- ✅ OnChain:
giveFeedback()no longer includesbytes feedbackAuthparameter - ✅ OffChain: Feedback JSON no longer contains
feedbackAuthfield - ✅ Dramatically simplifies feedback submission flow
- ✅ Removes agent-initiated authorization step
- ✅ Spam/Sybil protection now handled off-chain (filtering, indexing, reputation-based ranking)
Migration:
- ❌ Remove all
feedbackAuthsignature generation code - ❌ Remove feedback authorization endpoints
- ✅ Simplify submission to direct posting
4. New Endpoint Field [Both] — Feedback Registry
pre-v1 (legacy): Not available
v1.1 - New optional field in both onchain and offchain:
OffChain JSON:
{
"endpoint": "https://agent.example.com",
"score": 95,
"tag1": "defi"
}OnChain Contract Signature:
function giveFeedback(uint256 agentId, uint8 score, string tag1, string tag2,
string endpoint, string feedbackURI, bytes32 feedbackHash)Purpose: Optional string parameter to record which endpoint-URI was used by the client during the feedback submission process.
Examples:
"endpoint": "https://www.example-agent.com"- Main agent service endpoint"endpoint": "https://api.example-agent.com/v2"- Specific API version""or omitted - No specific endpoint recorded
Impact:
- ✅ OnChain:
giveFeedback()now includesstring endpointparameter - ✅ OffChain: Optional JSON field for endpoint URI
- ✅ Allows tracking which agent endpoint-URI was involved in feedback submission
- ✅ Useful for clients to reference which service version they used
5. FeedbackIndex Now Emitted in Event [OnChain] — Feedback Registry
This change affects only onchain contract behavior. There is no corresponding off-chain data change.
pre-v1 (legacy) - Index calculated by indexer:
- Subgraph maintained a
ClientAgentStatstable to track feedback count per client per agent feedbackIndexwas calculated as: incrementing counter for (agentId, clientAddress) pair- Indexers had to maintain this calculation logic
v1.1 - Index emitted directly by contract:
OnChain NewFeedback Event:
event NewFeedback(
uint256 indexed agentId,
address indexed clientAddress,
uint64 feedbackIndex, // ← Now emitted directly by contract (uint64)
uint8 score,
string indexed indexedTag1, // ← For efficient filtering (topic hash)
string tag1, // ← Actual tag1 value
string tag2,
string endpoint,
string feedbackURI,
bytes32 feedbackHash
);Impact:
- ✅ OnChain Only: Contract now emits
uint64 feedbackIndexinNewFeedbackevent - ✅ No need for indexers to calculate feedback counts
- ✅ Simpler indexing logic
- ✅
feedbackIndexis now a first-class on-chain value - ✅ Guarantees correct sequencing of feedback per (agentId, clientAddress) pair
Migration Checklist
Phase 1: OffChain Data Format Updates
- Update all feedback JSON objects to remove feedbackAuth field
- Rename feedbackUri → feedbackURI in all JSON occurrences
- Convert tag values (hex-encoded → plain strings)
- If tags are hex-encoded bytes32, decode them to strings
- Update tag parsing/serialization logic
- Add optional endpoint field to feedback JSON where applicable
- Update JSON schema validation to reflect v1.1 structure
Example (TypeScript):
// pre-v1 (legacy) Off-Chain Feedback Structure
interface FeedbackPreV1 {
feedbackAuth: string; // ❌ REMOVE
feedbackUri: string; // ❌ RENAME to feedbackURI
tag1: string; // Hex-encoded bytes32
tag2: string; // Hex-encoded bytes32
score: number;
}
// v1.1 Off-Chain Feedback Structure
interface FeedbackV10 {
feedbackURI: string; // ✅ Renamed
endpoint?: string; // ✅ NEW (optional)
tag1: string; // ✅ Plain string (no hex)
tag2: string; // ✅ Plain string (no hex)
score: number;
}Example (Data Migration):
// pre-v1 (legacy) Feedback JSON
{
"agentRegistry": "0x8004C269D0A5647E51E121FeB226200ECE932d55",
"agentId": 22,
"clientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"createdAt": "2025-12-20T12:00:00Z",
"feedbackAuth": "0xabc123...",
"score": 95,
"tag1": "6465666900000000000000000000000000000000000000000000000000000000",
"tag2": "616e616c7974696373000000000000000000000000000000000000000000000000",
"feedbackUri": "ipfs://QmXxx...",
"reasoning": "Great service"
}
// v1.1 Feedback JSON
{
"agentRegistry": "eip155:84532:0x8004C269D0A5647E51E121FeB226200ECE932d55",
"agentId": 22,
"clientAddress": "eip155:84532:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"createdAt": "2025-12-20T12:00:00Z",
"score": 95,
"tag1": "defi",
"tag2": "analytics",
"endpoint": "https://www.example-agent.com",
"feedbackURI": "ipfs://QmXxx...",
"reasoning": "Great service"
}Phase 2: Contract Integration Updates
- Update contract interaction code to call new giveFeedback() signature
- Remove feedbackAuth parameter from calls
- Include new string endpoint parameter
- Update tag1, tag2 parameter types from bytes32 to string
- Update event handler for NewFeedback
- Handle new feedbackIndex event parameter
- Update tag type handling from bytes32 to string
- Add endpoint field handling
- Update ABI/interface definitions to reflect v1.1 contract changes
Example (Contract Call - pre-v1 (legacy) to v1.1):
// pre-v1 (legacy)
giveFeedback(
agentId,
score,
bytes32("defi"), // bytes32 tag
bytes32("analytics"), // bytes32 tag
"ipfs://QmXxx...",
feedbackHash,
feedbackAuthSignature // ❌ REMOVE
);
// v1.1
giveFeedback(
agentId,
score,
"defi", // ✅ string tag
"analytics", // ✅ string tag
"https://www.example-agent.com", // ✅ NEW endpoint
"ipfs://QmXxx...",
feedbackHash
);Phase 3: Testing & Validation
- Test giveFeedback() calls without feedbackAuth parameter
- Verify tags are handled as strings in contract calls and events
- Check feedbackURI field naming consistency
- Test endpoint field handling (optional vs. empty string)
- Verify feedbackIndex is correctly emitted in events
- Test off-chain JSON validation against v1.1 schema
- Verify hex-to-string tag decoding for existing pre-v1 (legacy) data
- Test with both new v1.1 contract deployments
Data Format Examples
Off-Chain Feedback Comparison
pre-v1 (legacy):
{
"agentRegistry": "0x8004C269D0A5647E51E121FeB226200ECE932d55",
"agentId": 22,
"clientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"createdAt": "2025-12-20T12:00:00Z",
"feedbackAuth": "0xabc123...",
"score": 95,
"tag1": "6465666900000000000000000000000000000000000000000000000000000000",
"tag2": "616e616c7974696373000000000000000000000000000000000000000000000000",
"feedbackUri": "ipfs://QmXxx...",
"reasoning": "Great service"
}v1.1:
{
"agentRegistry": "eip155:84532:0x8004C269D0A5647E51E121FeB226200ECE932d55",
"agentId": 22,
"clientAddress": "eip155:84532:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"createdAt": "2025-12-20T12:00:00Z",
"score": 95,
"tag1": "defi",
"tag2": "analytics",
"endpoint": "https://api.example.com/v1",
"feedbackURI": "ipfs://QmXxx...",
"reasoning": "Great service"
}Changes:
- ✅ Removed
feedbackAuthfield - ✅ Renamed
feedbackUri→feedbackURI - ✅ Converted tags from hex (bytes32) to plain strings
- ✅ Added optional
endpointfield - ✅ Added CAIP format for addresses (best practice)
Implementation Phases
Phase 1: Assessment & Planning
- Read this guide fully
- Assess impact on your code (contract interactions, data parsing)
- Identify all code paths that handle feedback
- Plan data migration if needed
- Create v1.1 feature branch
Phase 2: Implementation
- Migrate off-chain JSON data format
- Update contract interaction code for new giveFeedback() signature
- Update event handlers for NewFeedback event
- Update JSON schema validation
- Update any data serialization/deserialization code
Phase 3: Testing & Validation
- Unit test contract interactions with new signatures
- Integration test feedback submission flow
- Validate JSON format against v1.1 schema
- Test with v1.1 contract deployment
Phase 4: Deployment
- Deploy updated code
- Migrate historical data (if needed)
- Monitor feedback submission and events
- Update documentation
FAQ
Q: What's the new giveFeedback() function signature?
A: The v1.1 signature is:
function giveFeedback(
uint256 agentId,
uint8 score,
string tag1,
string tag2,
string endpoint,
string feedbackURI,
bytes32 feedbackHash
) external;Key differences from pre-v1 (legacy):
- No
feedbackAuthparameter tag1,tag2are nowstring(notbytes32)- New
endpointparameter (optional, can be empty string) feedbackUri→feedbackURI(in the off-chain data)
Q: What does the new feedbackIndex mean?
A: feedbackIndex is now emitted in the NewFeedback event and represents the sequential index of feedback for a specific (agentId, clientAddress) pair. It's auto-incremented by the contract.
v1.1 Event:
event NewFeedback(
uint256 indexed agentId,
address indexed clientAddress,
uint64 feedbackIndex, // ← Sequence number per (agent, client)
uint8 score,
string indexed indexedTag1, // ← For efficient filtering (topic hash)
string tag1, // ← Actual tag1 value
string tag2,
string endpoint,
string feedbackURI,
bytes32 feedbackHash
);Q: Is the endpoint field required?
A: No, it's optional. Use it if you want to track which URI endpoint-source was involved in the feedback submission. Can be an empty string if not needed.
Q: How do I validate the new off-chain JSON format?
A: Use this JSON Schema for v1.1 feedback validation:
{
"type": "object",
"required": ["agentRegistry", "agentId", "clientAddress", "createdAt", "score"],
"properties": {
"agentRegistry": { "type": "string", "description": "CAIP-2 format: eip155:chainId:0x..." },
"agentId": { "type": "integer" },
"clientAddress": { "type": "string", "description": "CAIP-10 format: eip155:chainId:0x..." },
"createdAt": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp"
},
"score": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Feedback score 0–100"
},
"tag1": { "type": "string", "description": "First classification tag (indexed on-chain)" },
"tag2": { "type": "string", "description": "Second classification tag" },
"endpoint": {
"type": "string",
"description": "Optional: agent endpoint URI used during interaction"
},
"feedbackURI": {
"type": "string",
"description": "Off-chain data URI (ipfs://, https://, ar://, data:)"
},
"feedbackHash": {
"type": "string",
"description": "Keccak256 hash of feedback data for integrity (bytes32 hex)"
},
"reasoning": { "type": "string", "description": "Human-readable explanation for the feedback" }
}
}References
Document Version: 1.0
Last Updated: January 9, 2026