You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current AP2 specification (Section 5.2, Step 8) requires the Shopping Agent to forward the full IntentMandate to Merchant Agents during the discovery and negotiation phase. The reference implementation confirms this design — the Shopping Agent system prompt explicitly states: "Note that this information will be shared with the merchant."
This means merchants receive the user's natural_language_description, intent_expiry, requires_refundability, budget-related signals, and potentially SKU/merchant filters — all before any purchase commitment is made.
While this design provides merchants with context to construct a CartMandate, it conflates two distinct concerns: what the user wants (intent) and what the merchant offers (catalog response). This proposal argues that these should be separated at the protocol level.
Problem: Misaligned Responsibility Boundaries and Unnecessary Data Exposure
1. Verification Responsibility Leaks to Merchants
Under the current design, if a CartMandate deviates from the user's original intent, who is responsible for detecting the mismatch? The specification's threat model (Section 7) describes a scenario where:
"The Shopping Agent autonomously purchases an item that violates the user's signed Intent Mandate (e.g., exceeds budget or is the wrong item)."
The expected resolution relies on comparing the IntentMandate against the cart transaction details. However, if the merchant also holds the IntentMandate, the verification surface expands unnecessarily. The merchant could argue compliance with stated intent, introducing ambiguity into dispute resolution. Merchants should not be in a position to interpret — or misinterpret — user intent.
2. Dispute Isolation
In the current model, disputes arising from intent mismatches could involve three parties: User, Shopping Agent provider, and Merchant. If the IntentMandate remains exclusively within the User ↔ Shopping Agent boundary:
Intent-level disputes (agent didn't follow instructions) are cleanly isolated between the User and the Shopping Agent service provider.
Fulfillment-level disputes (merchant didn't deliver what was agreed) remain between the User/SA and the Merchant, grounded in the CartMandate — which the merchant did sign.
This creates a clearer liability structure: the Shopping Agent is accountable for faithfully translating user intent into shopping actions, and the Merchant is accountable for fulfilling the terms of the CartMandate it signed. Neither party needs visibility into the other's contractual boundary with the user.
3. Privacy — Data Minimization Beyond Linkability
Issue #120 correctly identifies cross-merchant linkability as a risk when IntentMandate signatures act as a "super-cookie." However, even if linkability is solved (e.g., via BBS+ anonymous credentials), the content of the IntentMandate itself remains exposed. This includes:
Natural language purchase intent — reveals user preferences, urgency, and context
These are not fields the merchant needs to construct a catalog response. The Shopping Agent can translate intent into structured queries (product search, price comparison) without revealing the underlying user mandate.
Proposed Solution: Intent as a Private Contract, Queries as the Public Interface
Core Principle
The IntentMandate should function as a private contract between the User and Shopping Agent — it defines the agent's authority and constraints. The Shopping Agent then independently interacts with merchants using standard discovery mechanisms (catalog search, price queries) without forwarding the mandate.
Suggested Flow Changes
Current flow (Section 5.2, Steps 7–9):
User → SA: IntentMandate (signed)
SA → MA: IntentMandate ← merchant receives full intent
MA → SA: CartMandate (signed by merchant)
Proposed flow:
User → SA: IntentMandate (signed, retained by SA)
SA → MA: Product query / catalog search (derived from intent, minimal disclosure)
MA → SA: CartMandate (signed by merchant)
SA: Validates CartMandate against IntentMandate locally
What Changes in the Protocol
IntentMandate is no longer transmitted to Merchant Agents. It remains a credential between the User and Shopping Agent, used for:
SA's internal decision-making (what to search for, what constraints to enforce)
Post-transaction audit trail (proof that SA acted within authorized scope)
Dispute resolution between User and SA provider
Shopping Agent → Merchant communication uses derived queries. The SA translates intent into merchant-facing requests (e.g., search_catalog skill calls, structured product queries). The merchant responds based on its catalog, not on user intent metadata.
CartMandate validation becomes the SA's responsibility. The SA checks whether the merchant's CartMandate satisfies the IntentMandate constraints before presenting it to the user (HP flow) or proceeding autonomously (HNP flow). This is already implicitly the SA's role — this proposal makes it explicit.
The cryptographic evidence chain adjusts. Instead of IntentMandate → CartMandate → PaymentMandate as a single forwarded chain, the structure becomes:
User ↔ SA boundary:IntentMandate (user-signed authority grant)
The IntentMandate serves as SA-held evidence, not a merchant-facing credential.
Impact on Mandate Types in src/ap2/types/mandate.py
The IntentMandate class would gain a conceptual scope annotation (e.g., documentation or a visibility field) indicating it is not intended for merchant transmission. The CartMandate and PaymentMandate remain unchanged — they are already scoped to the SA ↔ Merchant and SA ↔ Payment boundaries respectively.
Trade-offs and Counterarguments
"Merchants need intent context to provide better offers."
The Shopping Agent can selectively convey relevant requirements (e.g., product category, price range, delivery timeline) through structured queries without exposing the full mandate. This is analogous to how a human shopper asks a store clerk for help without showing them their bank statement.
"The IntentMandate proves the agent has user authorization to shop."
This is a valid concern, especially for HNP flows where the merchant may want assurance that the agent isn't acting without authority. However, this can be addressed by a lightweight authorization proof — a derived token or zero-knowledge attestation proving that a valid mandate exists, without revealing its contents. Issue #120's BBS+ proposal could serve this exact purpose: prove authorization without exposing intent.
"This breaks the cryptographic evidence chain for dispute resolution."
The evidence chain becomes partitioned, not broken. The User can still prove what they authorized (IntentMandate), the SA can prove it acted within scope (IntentMandate + CartMandate comparison), and the Merchant can prove what it offered (CartMandate). The key insight is that the Merchant never needed the IntentMandate to fulfill its role in the chain — the CartMandate is the merchant's binding commitment.
This proposal is complementary to #120, not a replacement. #120 solves "who sent this intent?" (identity privacy). This proposal asks a more fundamental question: "should the merchant receive the intent at all?" (data minimization). Both can coexist — if partial exposure is preferred over full restriction, #120's anonymous credentials combined with #127's schema-driven selective disclosure could provide a middle ground.
The approach aligns with the protocol's own design principle stated in the specification: "responsibility is attributed to the real-world entities (users, merchants, issuers)" — not to intermediary agents. If the Shopping Agent is the user's delegate for intent execution, keeping the intent mandate within that delegation boundary is the natural consequence of this principle.
Background
The current AP2 specification (Section 5.2, Step 8) requires the Shopping Agent to forward the full
IntentMandateto Merchant Agents during the discovery and negotiation phase. The reference implementation confirms this design — the Shopping Agent system prompt explicitly states: "Note that this information will be shared with the merchant."This means merchants receive the user's
natural_language_description,intent_expiry,requires_refundability, budget-related signals, and potentially SKU/merchant filters — all before any purchase commitment is made.While this design provides merchants with context to construct a
CartMandate, it conflates two distinct concerns: what the user wants (intent) and what the merchant offers (catalog response). This proposal argues that these should be separated at the protocol level.Problem: Misaligned Responsibility Boundaries and Unnecessary Data Exposure
1. Verification Responsibility Leaks to Merchants
Under the current design, if a
CartMandatedeviates from the user's original intent, who is responsible for detecting the mismatch? The specification's threat model (Section 7) describes a scenario where:The expected resolution relies on comparing the
IntentMandateagainst the cart transaction details. However, if the merchant also holds theIntentMandate, the verification surface expands unnecessarily. The merchant could argue compliance with stated intent, introducing ambiguity into dispute resolution. Merchants should not be in a position to interpret — or misinterpret — user intent.2. Dispute Isolation
In the current model, disputes arising from intent mismatches could involve three parties: User, Shopping Agent provider, and Merchant. If the
IntentMandateremains exclusively within the User ↔ Shopping Agent boundary:CartMandate— which the merchant did sign.This creates a clearer liability structure: the Shopping Agent is accountable for faithfully translating user intent into shopping actions, and the Merchant is accountable for fulfilling the terms of the
CartMandateit signed. Neither party needs visibility into the other's contractual boundary with the user.3. Privacy — Data Minimization Beyond Linkability
Issue #120 correctly identifies cross-merchant linkability as a risk when
IntentMandatesignatures act as a "super-cookie." However, even if linkability is solved (e.g., via BBS+ anonymous credentials), the content of theIntentMandateitself remains exposed. This includes:These are not fields the merchant needs to construct a catalog response. The Shopping Agent can translate intent into structured queries (product search, price comparison) without revealing the underlying user mandate.
Proposed Solution: Intent as a Private Contract, Queries as the Public Interface
Core Principle
The
IntentMandateshould function as a private contract between the User and Shopping Agent — it defines the agent's authority and constraints. The Shopping Agent then independently interacts with merchants using standard discovery mechanisms (catalog search, price queries) without forwarding the mandate.Suggested Flow Changes
Current flow (Section 5.2, Steps 7–9):
Proposed flow:
What Changes in the Protocol
IntentMandateis no longer transmitted to Merchant Agents. It remains a credential between the User and Shopping Agent, used for:Shopping Agent → Merchant communication uses derived queries. The SA translates intent into merchant-facing requests (e.g.,
search_catalogskill calls, structured product queries). The merchant responds based on its catalog, not on user intent metadata.CartMandate validation becomes the SA's responsibility. The SA checks whether the merchant's
CartMandatesatisfies theIntentMandateconstraints before presenting it to the user (HP flow) or proceeding autonomously (HNP flow). This is already implicitly the SA's role — this proposal makes it explicit.The cryptographic evidence chain adjusts. Instead of
IntentMandate → CartMandate → PaymentMandateas a single forwarded chain, the structure becomes:IntentMandate(user-signed authority grant)CartMandate(merchant-signed offer) +PaymentMandate(user-signed payment authorization)IntentMandateserves as SA-held evidence, not a merchant-facing credential.Impact on Mandate Types in
src/ap2/types/mandate.pyThe
IntentMandateclass would gain a conceptual scope annotation (e.g., documentation or avisibilityfield) indicating it is not intended for merchant transmission. TheCartMandateandPaymentMandateremain unchanged — they are already scoped to the SA ↔ Merchant and SA ↔ Payment boundaries respectively.Trade-offs and Counterarguments
"Merchants need intent context to provide better offers."
The Shopping Agent can selectively convey relevant requirements (e.g., product category, price range, delivery timeline) through structured queries without exposing the full mandate. This is analogous to how a human shopper asks a store clerk for help without showing them their bank statement.
"The IntentMandate proves the agent has user authorization to shop."
This is a valid concern, especially for HNP flows where the merchant may want assurance that the agent isn't acting without authority. However, this can be addressed by a lightweight authorization proof — a derived token or zero-knowledge attestation proving that a valid mandate exists, without revealing its contents. Issue #120's BBS+ proposal could serve this exact purpose: prove authorization without exposing intent.
"This breaks the cryptographic evidence chain for dispute resolution."
The evidence chain becomes partitioned, not broken. The User can still prove what they authorized (IntentMandate), the SA can prove it acted within scope (IntentMandate + CartMandate comparison), and the Merchant can prove what it offered (CartMandate). The key insight is that the Merchant never needed the IntentMandate to fulfill its role in the chain — the
CartMandateis the merchant's binding commitment.Related Issues
Additional Context
This proposal is complementary to #120, not a replacement. #120 solves "who sent this intent?" (identity privacy). This proposal asks a more fundamental question: "should the merchant receive the intent at all?" (data minimization). Both can coexist — if partial exposure is preferred over full restriction, #120's anonymous credentials combined with #127's schema-driven selective disclosure could provide a middle ground.
The approach aligns with the protocol's own design principle stated in the specification: "responsibility is attributed to the real-world entities (users, merchants, issuers)" — not to intermediary agents. If the Shopping Agent is the user's delegate for intent execution, keeping the intent mandate within that delegation boundary is the natural consequence of this principle.