
Description
The rules the reference agents enforce in code for third-party content, writes, grounding, identity, and memory, each with its module, plus two adversarial-eval rules. Load when handling untrusted tool results, guarding a write tool, or scoping what an agent remembers.
SKILL.md
Trust and safety rules
commerce_common/ is commerce-common/commerce_common/, shopping_agent/ is shopping-agent/core/shopping_agent/, and
merchant_agent/ is merchant-agent/core/merchant_agent/; docs/safety.md lists the same rules. A rule inside a tool
call holds on all three paths, which share one executor (commerce-architecture); rules 10 and 15 name the paths they run
on. Merchant staging, guardrails, approval, and marketplace posture are in commerce-merchant-operations.
Fence third-party content
- Every tool result from catalog, review, policy, order, metric, message, or web content goes through
Fence.fence_payload(commerce_common/fencing.py): NFKC-normalized, invisible and control characters removed, fence markers, forged turn markers, and special tokens replaced, wrapped in the role's label, and cut atmax_fenced_chars. The executor's_fencedapplies it to every handler. - The label and the notice are per-role constants (
STOREFRONT_FENCEinshopping_agent/fencing.py,MERCHANT_FENCEinmerchant_agent/fencing.py); the notice appears once, in the static prompt, with nothing untrusted in it. - The per-request block (profile, cart, memory facts, page, store context) sits inside the same fence after the cache
breakpoint (
build_dynamic_contextin each role'sprompt.py); backend context blocks have their own cap. - A model-supplied result count is clamped to
max_search_results(clamp_limitincommerce_common/execution.py).
Gate writes on provenance and caps
- A cart write accepts only ids in
ShoppingSessionState.seen_products, filled by the session's catalog and order reads (check_provenanceandremember_order_itemsinshopping_agent/gates.py); update and remove also accept a line already in the cart. Merchant staging accepts only ids inseen_listingsandread_listings, apply and discard only ids inseen_changes(merchant_agent/gates.py; commerce-merchant-operations). max_quantity_per_itemcaps the line after the write andmax_cart_linesthe cart, under a session lock (gated_add_to_cartinshopping_agent/gates.py; caps inshopping_agent/config.py). The lock is per process, soStorefrontBackendcart methods enforce them too; eligibility, pricing, and inventory are the backend's in both roles.- Nothing in either interface charges or places an order:
checkoutrenders the cart (enrich_checkoutinshopping_agent/enrichment.py) and the host completes it; post-purchase care is reads, with no cancel or refund tool. - Provenance lives on the session state (
ShoppingSessionState,MerchantSessionState), saved with the session when the request or turn ends (SessionStoreinexamples/demo_common/sessions.py, a versioned state document beside the transcript), so a request on another process loads it. Each map keeps its newestPROVENANCE_CAPrecords (rememberincommerce_common/types.py); a dropped id needs a fresh read. - A component is validated, its products, orders, metrics, or changes are joined from those records, and ids without
provenance are dropped and reported (
run_presentationincommerce_common/presentation.py; each role'senrichment.py; commerce-ui-tools).
Ground the answers that are figures or terms
- A terms question, an order question, or an unseen product id (
GROUNDING_RULESinshopping_agent/grounding.py), or a performance question or an apply request with nothing staged (merchant_agent/grounding.py), starts from the matching read:first_forced_toolincommerce_common/grounding.pypicks it, the Messages API runtimes force it withtool_choice, and the SDK runtimes prefetch it when the rule has a prefetch form (groundincommerce_common/agent_sdk.py; the terms rule has none); the hosted path has the prompt only. - The lexicons are config tuples (
policy_intent_terms,order_intent_terms,product_id_patterns,metrics_intent_terms, and their cues); a deployment appends its own words, a gate flag turns a rule off, and neither changes prompt bytes.
Hold identity on the server
- Session start binds the authenticated principal to an unguessable session id; later requests carry only that id, and
routes read the principal from the record (
SessionStore.startandsession_dependencyinexamples/demo_common/sessions.py). No request field or tool argument names a user, merchant, or operator; the MCP servers take the principal from their environment, a production server from its request. - Whether the principal owns a record (order, ticket, listing), and whether the step a call depends on has happened, is the backend's check against its store; an id having provenance does not make it theirs or ready.
Bound what is remembered
- Every fact on both write paths (
save_memoryand post-turn extraction) passesvalidate_factincommerce_common/memory.py: key of at most 64 characters, value of at most 200, one of the threeMemoryCategoryvalues, and theMemoryWriteFilter, which refuses identifier-shaped values by default;memory_blocked_patternsadds patterns, and a filter withchecksreplaces it (MemoryRuntime.build). - Extraction reads the last exchange's user and assistant text (
transcript_textincommerce_common/turn.py), andextract_and_storedrops its batch when the subject was purged meanwhile; the Messages API runtimes run it (update_memory), the SDK host calls the runtime, and the hosted path writes throughsave_memoryonly. memory_retention_days(with_retention),MemoryStore.delete_fact,MemoryStore.clear, andenable_memoryhold on every path without changing prompt or tool bytes; the examples expose read and delete routes (install_memory_routesinexamples/demo_common/memory.py), andclearbelongs in account deletion.- The subject is the shopper's
user_idor the operation'smerchant_id(memory_subjectin each role'sexecutor.py).
Refuse in the result, and keep the surface fixed
- A held call returns a normal result naming its gate (
ToolOutcome.heldincommerce_common/streaming.py; the host'stool_resultevent carriesstatus: blocked), a failure returns an error result, andexecutenever raises. - The tool list is a function of the config:
enable_web_search(default off) adds the tool, the SDK runtimes allow-list the registered names, and the manifests enable tools one by one. - The reference MCP servers bind to loopback unless an environment variable states that an authenticating gateway is in
front (
enforce_local_only_bindincommerce_common/mcp_server.py).
Two rules for adversarial evals
- Poisoned listings, reviews, and messages live in eval fixtures merged in for a run, outside demo and catalog data.
- Every refusal case has a should-serve counterpart in the same niche, so a suite catches over-refusal too (commerce-evals).
More skills from the commerce-agents repository
View all 16 skillscatalog-listings
create and improve e-commerce listing content
Sep 4Content CreationContent StrategyE-commerceMarketingcommerce-architecture
design and review commerce agent architecture
Sep 4AgentsArchitectureE-commerceEngineeringcommerce-evals
run behavioral evals for commerce agents
Sep 4AgentsE-commerceEvalsTestingcommerce-merchant-operations
manage merchant operations and store rules
Sep 4AgentsE-commerceManagementOperationscommerce-prompt-caching
configure commerce agent prompt caching
Sep 4AgentsE-commercePerformancePrompt Engineeringcommerce-ui-tools
implement commerce agent UI components
Sep 4DesignE-commerceFrontendUI Components
More from Anthropic
View publisheracademy-guide
recommend Claude Academy resources
skills
Aug 19AnthropicDocumentationEducationalgorithmic-art
create algorithmic art with p5.js
skills
Apr 6CreativeDesignGenerative ArtJavaScriptbrand-guidelines
apply Anthropic brand colors and typography
skills
Apr 6BrandingDesignTypographycanvas-design
create posters and visual art as PNG or PDF
skills
Apr 6CreativeDesignPDFclaude-api
build apps with the Claude API
skills
Sep 4AgentsAnthropicAnthropic SDKClaude API +1discernment-nudge
provide discernment nudges for user decisions
skills
Aug 19CoachingProductivityStrategy