{"type":"agent-policy-contract","version":"2.18","updated":"2026-10-05","generated_at":"2026-10-05","recent_changes":["2.18 (2026-10-03): ag_ui.testing_status now counts only the suites that run (311 test cases across the API service and route suites, 316 executions with parameterized cases, all passing). It also counted three Playwright E2E specs (25 cases) that no runner executes, so the previous total (328) and its pass-rate claim were overstated. No change of contract.","2.17 (2026-10-01): ag_ui.testing_status re-counted against the live suite (328 tests; the AG-UI MCP bridge suite was missing from the counted files) and the date of the pass-rate claim refreshed. No change of contract.","2.16 (2026-09-27): OAuth discovery links resolve per merchant resource; authentication is published per surface from the shared matrix. The API-key sunset is an announced target, not an enforced runtime cutoff.","2.15 (2026-09-26): Corrected the expansion of MPP to its real name, Machine Payments Protocol (plural) of Tempo Labs and Stripe, in protocolSupport and in the 1.8 changelog entry that first introduced it. Stopped asserting a standardization status for it: the `-01` of `draft-ryan-httpauth-payment` expired on 19 Sep 2026 and the document was renamed, and it is not confirmed that the renamed version was submitted, so `version` and `ietfDraft` now cite the tempoxyz/mpp-specs repository and say «individual IETF draft, no working group». No behaviour changes: MPP has no route an agent can exercise today.","2.14 (2026-09-23, revision final whole-branch, hallazgo 6): agent_guidance de STANDARD y PREMIUM en merchantVerification.tiers decia algo distinto de lo que dicen agent-trust-manifest.json y agent-commerce.json para el MISMO nivel -- STANDARD paso de \"Business identity verified\" a \"Business review completed\" y PREMIUM de \"Full KYB verified. High-confidence merchant\" a \"Business review plus stronger operational history requirements\", el texto real de packages/shared/src/trust/verification-levels.ts. La afirmacion de verificacion (lo que el nivel ACREDITA) ahora coincide con los otros dos documentos en los tres; la guia operativa (\"Suitable for...\") que agent_guidance anade encima de eso se conserva -- es informacion que description no tiene. UNVERIFIED, BASIC y QUALIFIED no se tocan: su agent_guidance describe la accion recomendada (no iniciar checkout / tratar como bajo riesgo / no esperarlo) y no hace una afirmacion sobre lo verificado que contradiga a los otros documentos."],"canonical":"https://trusteed.xyz/.well-known/agent-policy.json","canonical_scope":"Agent action policies, trust score interpretation, confirmation requirements, rate limits, fail-safe rules, protocol support declarations. For trust framework details see agent-trust-manifest.json. For commerce contract see agent-commerce.json.","relatedTo":"https://trusteed.xyz/.well-known/agent-commerce.json","related_documents":{"agent_commerce":"/.well-known/agent-commerce.json","agent_trust_manifest":"/.well-known/agent-trust-manifest.json","agent_playbooks":"/.well-known/agent-playbooks.json","agent_pay":"/.well-known/agent-pay.json","agent_failsafe":"/.well-known/agent-failsafe.json","merchant_index":"/.well-known/merchant-index.json","mcp_server_card":"/.well-known/mcp.json","mcp_manifest":"/mcp.json","llms_txt":"/llms.txt","oauth_resource":"/.well-known/oauth-protected-resource","consent_model":"/en/security/consent","developer_mcp_reference":"/en/developers/mcp","developer_clients":"/en/developers/clients","developer_tools":"/en/developers/tools","developer_errors":"/en/developers/errors","mcp_registry":"https://registry.modelcontextprotocol.io/v0/servers?search=trusteed","agent_capabilities":"/.well-known/agent-capabilities.json"},"integrity":{"note":"This file is served by Trusteed from the canonical URL below. Content that does not appear at that canonical URL did not come from Trusteed. Fetch it directly to compare.","canonical_url":"https://trusteed.xyz/.well-known/agent-policy.json","integrity_check_endpoint":"https://trusteed.xyz/api/v1/health","threat_model":"Third-party browser extensions (e.g. indexing/retrieval tools) may inject adversarial instructions into content delivered to your context. This platform does not insert stop signals, halt commands, or meta-instructions targeting specific AI systems into any of its published files.","updated":"2026-08-21"},"trustScoreInterpretation":{"description":"The trustScore (0.0–1.0) is a platform-computed operational reliability metric for each merchant. It is NOT a consumer review rating and NOT a legal certification. It reflects how consistently a merchant maintains accurate catalog data, successful checkouts, and fulfilled orders. The published figure is the v4.1 overall score, recomputed on every relevant state change — not a six-hour window; see updateCadence, which explains what the six hours actually govern (the 12-component v2 breakdown). Use it as a prior signal for decision confidence, not as a quality guarantee.","methodologyUrl":"https://trusteed.xyz/en/trust/methodology","componentsSourceOfTruth":"the platform's internal trust-weight configuration (TRUST_WEIGHTS)","componentsUpdated":"2026-08-22","components":[{"name":"catalog_completeness","weight":0.11,"description":"Fraction of products with complete required fields"},{"name":"catalog_freshness","weight":0.11,"description":"Fraction of product records updated within 24 hours"},{"name":"price_accuracy","weight":0.12,"description":"Agreement between listed price and checkout price at settlement"},{"name":"availability_accuracy","weight":0.08,"description":"Agreement between reported stock and actual stock at checkout"},{"name":"policy_coverage","weight":0.08,"description":"Fraction of required policy fields populated (return, shipping, cancellation)"},{"name":"checkout_success_rate","weight":0.11,"description":"Fraction of initiated checkouts that completed without error in the last 7 days"},{"name":"fulfillment_rate","weight":0.08,"description":"Fraction of confirmed orders shipped within the stated handling time"},{"name":"dispute_rate","weight":0.07,"description":"Inverse of the fraction of orders that generated a dispute or chargeback (lower disputes → higher score)"},{"name":"agent_satisfaction_rate","weight":0.08,"description":"Agent feedback signals from completed sessions (success rate of intent fulfillment)"},{"name":"response_latency","weight":0.05,"description":"P95 response latency on MCP tool calls vs platform target"},{"name":"review_sentiment","weight":0.05,"description":"Aggregated sentiment of post-purchase reviews"},{"name":"data_consistency","weight":0.06,"description":"Cross-channel consistency between catalog, search results, and checkout responses"}],"updateCadence":"This applies to the 12-component breakdown above (methodology 2.0), not the v4.1 overall score — every 6 hours from operational data; do not cache this breakdown for more than 6 hours. The v4.1 overall score (see agent-commerce.json's trustFramework) is recomputed on a much shorter cache window on every relevant state change; the two are additive, not the same figure on the same schedule.","ranges":[{"min":0.9,"max":1,"label":"EXCELLENT","agentGuidance":"High confidence merchant. All reliability indicators are consistently strong. Proceed with standard confirmation flow. No additional warnings needed for the user."},{"min":0.8,"max":0.9,"label":"GOOD","agentGuidance":"Reliable merchant with minor operational gaps. Standard flow applies. Consider surfacing the score only if the user asks about merchant quality."},{"min":0.7,"max":0.8,"label":"ACCEPTABLE","agentGuidance":"Merchant meets the recommended minimum threshold. Proceed normally. If the transaction is above the confirmation threshold, state the score to the user as part of the checkout summary."},{"min":0.5,"max":0.7,"label":"CAUTION","agentGuidance":"Merchant is active but below recommended reliability. Inform the user before checkout: state the score, explain it reflects recent operational data, and ask for explicit confirmation before proceeding."},{"min":0,"max":0.5,"label":"RESTRICTED","agentGuidance":"Merchant is deprioritized or suspended. Do NOT initiate checkout. Inform the user that the merchant currently does not meet the platform's minimum reliability standards and suggest alternatives with a higher score."}],"trustScoreGuidanceScope":"Scope: this guidance governs purchases that move a user's money. It does not govern a lane that settles nothing — a synthetic catalogue with simulated payment, published as such in its own description — where exercising the protocol puts no money and no buyer at risk. The exemption is the simulated settlement, not the merchant: wherever a real payment is possible, these thresholds apply in full, at the same numbers. The `demo-store` lane described in /.well-known/agent-checkout-guide.json is the one such lane on this platform, and it scores in the RESTRICTED band — that is not a contradiction, because nothing it settles is real.","minimumRecommendedScore":0.7,"platformMinimumScore":0.3,"platformMinimumNote":"Two different floors, on purpose. LISTING floor: merchants with trustScore < 0.3 are excluded from all agent API results (this one the platform enforces — see agent-commerce.json eligibilityRequirements). Merchants with trustScore in [0.3, 0.5) are listed but appear at the bottom of ranked results (deprioritized tier). TRANSACTION floor: the agent MUST apply the RESTRICTED guidance and not initiate checkout for any merchant with trustScore < 0.5 even though the merchant is listed and technically reachable — the platform does NOT block that checkout for you, no checkout path reads the merchant trust score. Being listed is not being safe to transact with.","productRankingFormula":{"description":"How trustScore weights product search ranking (deterministic). Source of truth: the platform's internal product-ranking service.","relevanceScore":"(textRelevance × 0.55) + (trustScore × 0.25) + (freshness × 0.10) + (inStock × 0.10)","trustScoreWeight":0.25,"twoTierSort":"Hard boundary at the active floor: products from ACTIVE stores (trustScore ≥ 0.5) always rank above products from DEPRIORITIZED stores (trustScore < 0.5), regardless of relevanceScore. Within each tier, products sort by relevanceScore DESC.","incentiveNote":"A merchant improving its trustScore directly improves its product ranking (0.25 weight) and, above the active floor (0.5), escapes the deprioritized tier."},"thresholdSourceOfTruth":"Every numeric floor in this document is derived from the platform's canonical store trust bands (packages/shared/src/trust/store-score-bands.ts), the same constants that drive search visibility, auto-suspension and the published label. See failSafePolicy.evaluationOrder for which floor governs what."},"allowedActions":{"description":"Action taxonomy for this platform. Actions are grouped by impact level. Agents should use this taxonomy to enforce their own policy layer on top of platform policies.","actionTypes":[{"type":"read","actions":["search_products","get_product_details","browse_categories","get_merchant_profile"],"requiresAuth":false,"humanConfirmation":"never","description":"Read-only operations. No financial or legal side effects. Safe to execute autonomously. Publicly accessible on all stores — no token required."},{"type":"recommend","actions":["compare_products"],"requiresAuth":false,"humanConfirmation":"never","description":"Recommendation operations. No binding commitment. Publicly accessible — no token required. Safe to execute autonomously."},{"type":"checkout_session_read","actions":["preview_checkout","get_shipping_rates","apply_discount"],"requiresAuth":true,"humanConfirmation":"never","description":"Read and non-binding operations on an active checkout session (preview totals, shipping rates, discount codes). Requires an OAuth 2.1 Bearer token with scope mcp:checkout — unlike the read/recommend types above, these are NOT publicly accessible; the platform returns 401 without a token. No binding commitment once authenticated; safe to execute autonomously."},{"type":"start_checkout","actions":["create_cart","select_shipping_option","ucp_create_checkout"],"requiresAuth":true,"humanConfirmation":"required","description":"Initiates a checkout session. Creates a binding cart or checkout record. Requires explicit user confirmation."},{"type":"complete_checkout","actions":["complete_checkout","ucp_complete_checkout"],"requiresAuth":true,"humanConfirmation":"required","description":"Finalises a purchase. Has financial consequences and may trigger payment. Always requires explicit user confirmation. The agent must also hold off unless the merchant trust score >= 0.5 (see failSafePolicy.evaluationOrder step 4) — this is a policy the agent applies, not a check the platform performs on your behalf."},{"type":"cancel","actions":["ucp_cancel_checkout"],"requiresAuth":true,"humanConfirmation":"recommended","description":"Cancels an in-progress checkout. Low financial risk but should confirm with user to avoid accidental cancellation."},{"type":"ag_ui_stream","actions":["ag_ui_run","ag_ui_confirm"],"requiresAuth":true,"humanConfirmation":"required_for_checkout","description":"AG-UI streaming session. Read-only tool calls execute autonomously; complete_checkout requires explicit human confirmation via the confirmation endpoint."},{"type":"scp_discover_context","actions":["scp_discover","scp_get_context"],"requiresAuth":true,"humanConfirmation":"never","description":"Fix 2026-08-21 (N4): scp_discover and scp_get_context are NOT MCP tools callable via tools/call — they are REST endpoints (POST /discover, POST /context on the SCP-consume service) gated by agentAuth in every environment. Corrected from requiresAuth:false, which never matched apps/api/src/routes/scp-consume.routes.ts. Read-only, no binding commitments — safe to execute autonomously once authenticated."},{"type":"scp_authorize","actions":["scp_authorize"],"requiresAuth":true,"humanConfirmation":"required","description":"SCP authorization via OAuth 2.0 + PKCE (POST /authorize on the SCP-consume service, not an MCP tool). Grants agent access to shopper context from external merchant. Requires explicit user approval."}]},"rateLimits":{"description":"Recommended rate limits per action type for well-behaved agents. The platform enforces hard limits via HTTP 429 responses. These recommended limits are softer guidelines for agent retry policy design.","byActionType":{"read":{"requestsPerMinute":20,"burstAllowance":5,"retryAfterSeconds":3,"retryStrategy":"exponential_backoff","maxRetries":3},"recommend":{"requestsPerMinute":20,"burstAllowance":3,"retryAfterSeconds":3,"retryStrategy":"exponential_backoff","maxRetries":3},"checkout_session_read":{"requestsPerMinute":20,"burstAllowance":5,"retryAfterSeconds":3,"retryStrategy":"exponential_backoff","maxRetries":3},"start_checkout":{"requestsPerMinute":5,"burstAllowance":1,"retryAfterSeconds":12,"retryStrategy":"fixed_delay","maxRetries":2,"note":"Do not auto-retry start_checkout failures — always surface the error to the user before retrying."},"complete_checkout":{"requestsPerMinute":2,"burstAllowance":0,"retryAfterSeconds":30,"retryStrategy":"none","maxRetries":0,"note":"This rate limit has no automatic backoff-and-retry (retryStrategy: none) — a 429 here must be surfaced to the user, not silently retried. This is NOT the full checkout retry policy: complete_checkout IS idempotent and safe to retry on 5xx/timeout with the same idempotency_key (see /.well-known/agent-playbooks.json#safe-checkout-retry). Never auto-retry after a 4xx, or after any response indicating payment was captured — a failure there may mean a partial charge was already processed; inform the user and let them decide."},"ag_ui_stream":{"requestsPerMinute":10,"burstAllowance":2,"retryAfterSeconds":5,"retryStrategy":"exponential_backoff","maxRetries":3,"note":"AG-UI SSE streams are long-lived connections. This limit applies to new stream initiations, not to events within an active stream."},"scp_discover_context":{"requestsPerMinute":100,"burstAllowance":10,"retryAfterSeconds":3,"retryStrategy":"exponential_backoff","maxRetries":3},"scp_authorize":{"requestsPerMinute":5,"burstAllowance":1,"retryAfterSeconds":10,"retryStrategy":"fixed_delay","maxRetries":2}},"errorCodeGuide":{"400":{"meaning":"Validation error — bad input schema","retry":false,"action":"Fix the request parameters before retrying"},"401":{"meaning":"Missing or invalid API key","retry":false,"action":"Obtain a valid API key via POST /api/v1/sandbox/key or the developer dashboard"},"403":{"meaning":"Tier gate — feature not available on current plan","retry":false,"action":"Inform the user and suggest upgrading or using an alternative flow"},"404":{"meaning":"Resource not found (product ID, cart ID, etc.)","retry":false,"action":"Verify the ID is from the current session; do not assume it persists across sessions"},"409":{"meaning":"Conflict — idempotency guard (checkout already completed)","retry":false,"action":"The action already succeeded; read current state with get_checkout or preview_checkout"},"429":{"meaning":"Rate limit exceeded","retry":true,"action":"Wait for Retry-After header value, then retry with exponential backoff"},"500":{"meaning":"Merchant system error","retry":true,"retryAfterSeconds":10,"action":"Retry once after 10 seconds. If it persists, surface the error to the user."},"503":{"meaning":"Service temporarily unavailable","retry":true,"retryAfterSeconds":30,"action":"Retry after 30 seconds with exponential backoff"}}},"confirmationPolicy":{"description":"Defines which actions the agent MUST confirm with the human user before executing. Confirmation means pausing the agentic flow, presenting a clear human-readable summary to the user, and waiting for explicit approval. Implicit or assumed approval is not sufficient.","alwaysRequireConfirmation":["complete_checkout","create_cart","place_order","submit_payment_method","paypal_approve_refund"],"alwaysRequireConfirmationRationale":"These actions have financial consequences or create binding merchant commitments that cannot be automatically reversed. The agent must present the full order summary (items, quantities, total amount, merchant name, and trust score) before the user approves. PayPal refunds always require merchant/human approval before execution.","requireConfirmationAboveAmount":{"currency":"USD","threshold":100,"description":"For any single order or cart total exceeding USD 100, the agent must present an explicit pre-checkout summary and receive affirmative user approval, even if a lower-value confirmation was already given earlier in the session. The threshold applies per merchant checkout session, not per item.","currencyConversionNote":"Added 2026-08-20 (C20): this threshold is evaluated against the cart total in USD. The platform does not automatically convert non-USD carts (see supported_merchant_currencies) for this comparison — until a conversion rule is published, treat a non-USD cart's relationship to this threshold as unverified and err toward requesting confirmation."},"allowedShippingCountries":["US","CA","GB","DE","FR","ES","IT","NL","MX"],"allowedShippingCountriesNote":"The agent must verify that the user's shipping country is in this list before creating a cart. If the country is not supported, inform the user and do not proceed with checkout. Fix 2026-08-20 (C21): 'AU' was removed from this list — it was never confirmed against a merchant that actually ships there (see shippingPolicy.supportedRegions, the list anchored to real merchant shipping data). Re-add it only once a merchant's 'policies.shipping' confirms AU coverage.","maxCartValueWithoutSplitting":{"amount":500,"currency":"USD","note":"Corrected 2026-09-09: this is a RECOMMENDED threshold for the agent, not a limit applied on your behalf. Earlier wording described a 500 USD platform cap that rejected larger checkouts; no such check exists anywhere in the checkout path, so agents must not rely on one. Above this amount, obtain explicit human approval before completing checkout. A merchant MAY configure a real per-order cap (rule R035.max-order-value); when they have, exceeding it returns a checkout block carrying that rule code. When they have not, no cap applies.","currencyConversionNote":"Added 2026-08-20 (C20): same caveat as requireConfirmationAboveAmount — this ceiling compares against the USD cart total, with no automatic conversion for other currencies."},"neverRequireConfirmation":["search_products","get_product_details","compare_products","get_merchant_profile","preview_checkout","scp_discover","scp_get_context"],"neverRequireConfirmationRationale":"These are read-only operations with no financial or legal side effects. The agent may execute them autonomously without interrupting the user."},"failSafePolicy":{"description":"Defines the required agent behavior when encountering uncertainty, degraded signals, or error states. The default posture is conservative: when in doubt, stop and inform rather than proceed and assume.","rules":[{"condition":"merchant.trustScore < 0.5","action":"DO_NOT_PROCEED","enforcedBy":"agent","reason":"The merchant is in the restricted or deprioritized tier. Initiating a checkout against a merchant with this score exposes the user to elevated risk of failed fulfillment, price discrepancy, or unavailable stock. Suggest alternatives at or above the recommended minimum (0.7). Note this floor is HIGHER than the listing floor (0.3): a merchant can legitimately appear in agent API results and still be one this rule tells you not to transact with. The platform does not enforce this floor at checkout — you do."},{"condition":"merchant.verificationLevel == 'UNVERIFIED'","action":"DO_NOT_PROCEED","reason":"The merchant has not completed any identity or domain verification. This does not imply fraud, but it means the platform has no verified data about the business entity. The agent must not initiate checkout with an unverified merchant; inform the user and suggest verified alternatives instead."},{"condition":"merchant.verificationLevel not in [UNVERIFIED, BASIC, STANDARD, PREMIUM, QUALIFIED]","action":"DO_NOT_PROCEED","reason":"Added 2026-08-20 (C18): the platform only defines these five verification levels. A value outside this set is unrecognized — the agent must not infer trust from an unknown level, inform the user, and treat the merchant as unverified until the platform's own docs confirm what the level means."},{"condition":"checkout_response.status == 'error'","action":"ABORT_AND_INFORM","reason":"A checkout error may indicate a price change, stock exhaustion, or merchant system failure. Do not retry automatically. Inform the user of the error, retrieve fresh availability data, and present updated options before asking whether to retry."},{"condition":"availability_freshness > 24h","action":"WARN_USER","reason":"Stock and price data older than 24 hours is classified as stale. The agent should call /agent/availability/{id} before checkout to confirm current data. If a fresh check is not possible, inform the user that availability may have changed."},{"condition":"ambiguous_user_intent","action":"ASK_FOR_CLARIFICATION","reason":"If the user's instruction can be interpreted in multiple ways that would result in different products, merchants, or order amounts, the agent must resolve the ambiguity before taking any action with financial consequences. Do not guess."},{"condition":"trustScore_v2_breakdown_age > 6h","deprecatedConditionAlias":"trustScore_data_age > 6h","action":"TREAT_AS_STALE_AND_REFETCH","enforcedBy":"agent","reason":"Corrected 2026-09-10. This rule applies ONLY to the 12-component breakdown of methodology 2.0 (trustScoreInterpretation.components), which is what is recomputed every 6 hours — see updateCadence. It does NOT apply to the published overall figure: that one is the v4.1 score, recomputed on demand within the request that serves it and therefore never served stale. The old condition name said 'trustScore_data_age', which read as if it governed the published figure and contradicted this document's own trustScoreInterpretation.description. The former name is kept in deprecatedConditionAlias for one contract cycle; agents matching on it must migrate. No client-side staleness rule is published for the v4.1 overall figure, deliberately: we do not have a client cache window to recommend and will not invent one."}],"evaluationOrder":[{"step":1,"dimension":"administrative_status","enforcedBy":"platform","description":"A suspended merchant is suspended regardless of score. Nothing below this step can rescue it.","evidence":"packages/shared/src/trust/store-score-bands.ts -> operationalStatus(): a store with suspendedAt != null short-circuits to 'suspended' before the score ladder is consulted.","appliesToConditions":[]},{"step":2,"dimension":"verification_level","enforcedBy":"platform","description":"Verification level is a hard filter evaluated independently of the score: a high score does NOT rescue an unverified or unrecognized level. This is what resolves the collision between a CAUTION band and an UNVERIFIED merchant — DO_NOT_PROCEED wins, because it is decided one step earlier.","evidence":"apps/dashboard/src/lib/discovery/merchant-classification.ts -> meetsAgentApiEligibility() returns false on the level before it ever looks at the score; apps/api/src/services/agent/agent-search.service.ts applies isAgentEligibleVerificationLevel() as a hard filter on the same surface.","appliesToConditions":["merchant.verificationLevel == 'UNVERIFIED'","merchant.verificationLevel not in [UNVERIFIED, BASIC, STANDARD, PREMIUM, QUALIFIED]"]},{"step":3,"dimension":"listing_floor","enforcedBy":"platform","description":"trustScore >= 0.3 to appear in agent API results at all. Enforced by us; an agent will simply not see merchants below it. A missing score is fail-closed, not a pass.","evidence":"apps/api/src/services/agent/agent-search.service.ts -> meetsMinTrustGate(store.trustScore, 0.3, ...); apps/dashboard/src/lib/discovery/merchant-classification.ts -> AGENT_API_MIN_TRUST_SCORE.","appliesToConditions":[]},{"step":4,"dimension":"transaction_floor","enforcedBy":"agent","description":"trustScore >= 0.5 before initiating checkout. The platform does NOT enforce this: no checkout path reads the merchant trust score. It is on the agent, and it is why a listed merchant can still be one you must not transact with.","evidence":"No enforcement site exists by design. The only 0.x gate on this value in the platform is ranking (agent-ranking.service.ts / agent-search.service.ts), which changes position in results, not the ability to buy. The 0.3 floor in services/mcp/trust-band.service.ts is the AGENT's own score, a different scale and a different subject.","appliesToConditions":["merchant.trustScore < 0.5"]},{"step":5,"dimension":"score_band","enforcedBy":"agent","description":"Only once the steps above are clear do the trustScoreInterpretation.ranges bands apply, and they govern how to INFORM the user, never whether a blocked merchant becomes allowed. A CAUTION band never overrides a DO_NOT_PROCEED decided at step 2, 3 or 4.","evidence":"packages/shared/src/trust/store-score-bands.ts -> displayLabelFromScore01(), consumed by apps/api/src/routes/stores-trust-score.routes.ts for the published label.","appliesToConditions":[]},{"step":6,"dimension":"data_freshness","enforcedBy":"agent","description":"Staleness is evaluated last and never turns a permitted merchant into a forbidden one: it tells the agent to refetch and re-run this order from step 1.","evidence":"The 'stale' field is published by apps/api/src/routes/stores-trust-score.routes.ts and gates nothing server-side; the v4.1 overall is computed within the request and reported stale:false.","appliesToConditions":["trustScore_v2_breakdown_age > 6h","availability_freshness > 24h"]},{"step":7,"dimension":"runtime_signals","enforcedBy":"agent","description":"Errors and ambiguity are evaluated on the live interaction, after the merchant has cleared every step above.","evidence":"Agent-side rules; the platform surfaces the error but does not decide the agent's retry policy.","appliesToConditions":["checkout_response.status == 'error'","ambiguous_user_intent"]}],"evaluationOrderNote":"Published 2026-09-10. Until then nothing in this document said which rule wins when two apply at once — a merchant at trustScore 0.646 (CAUTION: 'ask for explicit confirmation') and verificationLevel UNVERIFIED (DO_NOT_PROCEED) matched both. This order does not change any rule; it declares the precedence the platform already practises, with the source file for each step. Lower step number wins."},"returnPolicy":{"description":"Return eligibility and terms are set individually by each merchant and are surfaced in the merchant profile response under the 'policies.return' field. There is no platform-wide universal return window.","note":"Trusteed is not the merchant of record and does not process returns directly. All return requests must be directed to the originating merchant via the contact information in the order confirmation.","agentGuidance":"Before presenting return terms to a user, always fetch the current merchant profile to read the 'policies.return' field. Do not state or imply a default return window unless the merchant's profile explicitly provides one. If no return policy is present, tell the user that the merchant has not published a return policy and recommend contacting them directly before purchase.","docsUrl":"https://trusteed.xyz/en/trust"},"shippingPolicy":{"description":"Shipping terms, carriers, and timelines are set by each individual merchant. The platform aggregates estimated delivery windows from merchant-provided data. These are estimates, not guarantees.","supportedRegions":["US","CA","GB","DE","FR","IT","NL","ES","MX"],"supportedRegionsNote":"ISO 3166-1 alpha-2 country codes (no regional aliases such as 'EU' — the previous 'EU' entry was expanded into its member codes already covered by this list). This list reflects regions where at least one connected merchant ships. A specific merchant may ship to a subset of these regions. Always check the merchant's 'policies.shipping' field for the exact destination list.","estimatedDelivery":{"standard":"3-7 business days","express":"1-2 business days"},"estimatedDeliveryNote":"These are platform-level averages derived from merchant data. Actual delivery time depends on the merchant, carrier, and destination. Read the merchant-specific shipping policy before presenting timelines to the user.","agentGuidance":"Fetch the merchant profile and read 'policies.shipping' before quoting shipping timelines or costs to the user. Do not present platform-level averages as the merchant's specific commitment."},"ticketLimits":{"description":"Order value limits control the maximum amount the agent is permitted to process in a single checkout session. These limits exist to reduce exposure to fraud and to ensure human oversight of high-value transactions.","defaultMaxOrderValue":{"amount":500,"currency":"USD"},"defaultMaxOrderValueNote":"Corrected 2026-09-09: there is NO platform default cap. The previous wording said the platform enforced a 500 USD ceiling when a merchant had not configured one — the opposite of what the code does: the evaluator for R035.max-order-value returns PASS when the merchant has set no cap (packages/shared/src/enforcement/rule-catalog.ts, evaluateR035). Treat the 500 USD figure as a recommended confirmation threshold for the agent, not as a limit the API will apply on your behalf.","merchantConfigurable":true,"merchantConfigurableNote":"Corrected 2026-09-09. A merchant configures a real per-order cap through the checkout enforcement rule R035.max-order-value (merchantPolicies.r035.maxCents); the setting name previously published here, 'agentRiskControls.maximum_order_value', does not exist. There is no 'lower of platform default and merchant override': the effective cap is the merchant's, and when unset there is none. Related merchant-configurable caps: R036 (per line item), R038 (item count), R039 (quantity per SKU), R042 (orders per agent per day) and R062 (cumulative agent spend per window).","agentGuidance":"Before constructing a cart, check whether the total value is within the effective limit. If a user requests an order that would exceed the limit, inform them that the transaction must be split or completed manually, and do not attempt to circumvent the limit by splitting into multiple automated checkout calls."},"ui_protocols":{"description":"Declares the UI protocols supported by this platform for agents that can render rich declarative interfaces.","supported":[{"protocol":"ag_ui","version":"0.0.48","type":"Agent-User Interaction (SSE Streaming)","spec_url":"https://docs.ag-ui.com","author":"CopilotKit","documentation_url":"https://trusteed.xyz/en/for-agents","attribution_note":"AG-UI is CopilotKit's protocol. Until 2026-08-29 this entry declared author 'Trusteed' and pointed spec_url at our own integration page, while the other three protocols in this list attributed Google and the W3C correctly.","description":"AG-UI (Agent-User Interaction Protocol) — Real-time agentic commerce with Server-Sent Events (SSE) streaming, bidirectional state synchronization via RFC 6902 JSON Patch, and human-in-the-loop confirmation. Enables agents to manage carts and checkout with real-time feedback and cryptographic token confirmation.","endpoint":"POST /{storeSlug}/ag-ui","transport":"Server-Sent Events (text/event-stream)","how_to_activate":"POST a JSON body with threadId, runId, and messages to /{storeSlug}/ag-ui. Receive continuous SSE events for state updates, tool calls, and confirmation prompts.","supported_events":["RunStarted","RunFinished","RunError","TextMessageStart","TextMessageContent","TextMessageEnd","ToolCallStart","ToolCallArgs","ToolCallEnd","StateSnapshot","StateDelta","Custom"],"compatible_tools":["search_products","get_product_details","browse_categories","get_merchant_profile","create_cart","apply_discount","preview_checkout","complete_checkout"],"human_in_the_loop":true,"confirmation_endpoint":"POST /{storeSlug}/ag-ui/confirm","security_model":"HMAC-SHA256 token confirmation with 5-minute window. State synchronization via immutable JSON Patch. Agent signature verification required for all confirmations.","testing_status":"311 tests total across the API service and route suites, 100% pass rate as of 2026-10-03 (static count of it()/test() blocks; 316 executions once parameterized cases expand; count verified live by CI gate ag-ui-test-count-drift, not a hand-typed phase breakdown — see apps/dashboard/src/__tests__/manifest-contracts.test.ts)","fallback":"Plain JSON response for non-SSE capable clients","dispatchable_mcp_tools":["apply_discount","browse_categories","create_cart","get_merchant_profile","get_product_details","get_shipping_rates","preview_checkout","search_products"],"dispatchable_mcp_tools_reference":"https://trusteed.xyz/.well-known/mcp.json","dispatchable_mcp_tools_note":"An AG-UI run resolves the user's message to one of these eight MCP tools and streams the call as ToolCallStart/Args/End. The reference above is the MCP server card, where their schemas live — it is the catalogue of the MCP surface, not of AG-UI, and it lists far more tools than a run can dispatch. Notably absent: complete_checkout. A conversation cannot charge anyone; payment goes through the confirmation endpoint. Replaced catalog_url on 2026-08-30 (external verification): that field name is how the a2ui entry below points at its own component catalogue, and copying it here claimed the MCP server card as AG-UI's catalogue while also promising all 45 of its tools. Pinned to the ToolIntent union of apps/api/src/services/ag-ui/ag-ui-tool-adapter.ts by a CI gate, so this list cannot drift from what the adapter actually dispatches.","status":"production"},{"protocol":"a2ui","version":"0.9","version_note":"0.9 and not_implemented, matching /.well-known/a2ui-catalog.json and /mcp.json. This entry said 0.8 / coming_soon: three surfaces, two versions, two states, for a protocol none of them serves.","spec_url":"https://github.com/google/A2UI","license":"Apache-2.0","author":"Google","description":"Agent-to-UI: AI agents will be able to request rich, interactive, declarative JSON UI surfaces from MCP tools. Planned (coming soon) — A2UI rendering for search and checkout tools is not yet functional; tools currently return plain JSON regardless of the 'a2ui' flag.","how_to_activate":"Planned — not yet functional. Once renderers ship, pass 'a2ui: true' in the tool input parameters of compatible tools; today the flag falls back to plain JSON.","compatible_tools":[],"compatible_tools_note":"Empty on purpose, matching /mcp.json. This listed search_products and complete_checkout, neither of which accepts an 'a2ui' parameter — as the description in this same entry already said.","fallback":"plain JSON response identical to non-A2UI behavior — fully backward compatible","security_model":"Declarative only — no arbitrary code execution. Components are restricted to the store's approved catalog (whitelist). XSS prevention applied to all text values.","renderers":["Angular","Flutter","Lit","Markdown"],"renderers_url":"https://github.com/google/A2UI/tree/main/renderers","catalog_url":"https://trusteed.xyz/.well-known/a2ui-catalog.json","status":"not_implemented"},{"protocol":"webmcp","spec_version":"2026-03-27","status_note":"2026-08-29 (coherence audit, O-05): was 'active'. The signed capability registry classifies webmcp as CODE_COMPLETE, and 'active' is an exact synonym of LIVE in the state vocabulary that same registry publishes — so this field asserted two rungs above its ceiling, in a document whose own llms.txt says the registry wins. Level 1 (server-side tools over standard MCP transport) is reachable today; its state is declared by the three_bucket_tools capability. What is unconfirmed is level 2: the browser bridge bundle has been uploaded by hand since 2026-05-16 and native navigator.modelContext has never been verified against a real browser.","spec_url":"https://webmachinelearning.github.io/webmcp/","author":"W3C Web Machine Learning Community Group","description":"WebMCP (W3C CG Draft) — browser-native MCP via navigator.modelContext. This platform supports WebMCP at two levels: server-side (all stores, no installation) and browser-bridge (session/cart/DOM access, requires store snippet).","level_1_server_side":{"description":"All stores on this platform expose MCP tools over standard Streamable HTTP transport. Browser agents using navigator.modelContext.callTool() can reach them directly — no frontend installation required.","auth_model":"Discovery tools (search, browse) are public — no token required. Checkout tools require OAuth 2.1 Bearer token with scope mcp:checkout. Fix 2026-08-21 (N4): removed scp_discover/scp_get_context from this list — they are not MCP tools reachable via navigator.modelContext.callTool(); they are REST endpoints of the SCP-consume service (POST /discover, POST /context), both auth-required. See allowedActions.actionTypes.scp_discover_context.","endpoint_pattern":"POST /{storeSlug}/mcp","public_tools":["search_products","get_product_details","browse_categories","get_merchant_profile","compare_products"],"auth_required_tools":["preview_checkout","apply_discount","create_cart","select_shipping_option","complete_checkout","ucp_create_checkout","ucp_complete_checkout","ucp_cancel_checkout"],"status":"production"},"level_2_browser_bridge":{"description":"JS snippet that registers navigator.modelContext tools providing browser-native capabilities: authenticated session read, local cart sync, wishlist, user preferences, and DOM interaction. The store installs once via their platform's native extension mechanism.","browser_capabilities":["authenticated_session_read","local_cart_sync","wishlist_read","user_preferences_read","dom_product_highlight"],"install_methods":{"shopify":"Theme App Extension (App Embed Block) — merchant activates from Shopify Theme Editor, no code changes","woocommerce":"WordPress plugin via wp_enqueue_scripts() — install from wp-admin, no code changes","prestashop":"PrestaShop module via displayHeader hook — install from backoffice Module Manager, no code changes","odoo":"Odoo app module via ir.http hook — install from Apps menu, activate WebMCP bridge, no code changes","custom":"Manual: <script src='https://trusteed.xyz/webmcp-bridge.js' data-store='{storeSlug}'></script>"},"compatible_browsers":["Chrome Canary (flag: #model-context-protocol)","Opera Comet"],"status_note":"Was `in_development` until 2026-09-01 while /mcp.json published `code_complete` for the same field. Both resolve to CODE_COMPLETE in the signed state vocabulary, so neither over-claimed — but a CI gate comparing strings would have called them equal to their own registry and different from each other, which is how a literal drift survives. The signed registry (trusteed-capabilities.json -> webmcp) is the arbiter: CODE_COMPLETE.","status":"code_complete"},"how_to_use_now":"Use the Level 1 server-side endpoint. Connect to POST /{storeSlug}/mcp using Streamable HTTP transport. No WebMCP snippet needed — all discovery tools are public, checkout tools require OAuth.","sandbox_url":"https://trusteed.xyz/en/demo-store/playground","status":"code_complete"},{"protocol":"payment_request_api","version":"W3C CR Draft (27 Jan 2026)","type":"Browser-Native Human-Confirmed Payment (W3C)","spec_url":"https://www.w3.org/TR/payment-request/","author":"W3C Web Payments Working Group","description":"W3C Payment Request API — browser-native payment sheet (Apple Pay, Google Pay, saved cards) that generates a Stripe PaymentMethod token. Bridges agent-initiated checkout (Layer 4) to settlement (Layer 6) with mandatory human confirmation in the browser. No agent can complete payment without human interaction.","layer":"L5 — Human-Confirmed Payment Execution","trigger":"Agent initiates checkout via MCP complete_checkout tool → frontend receives checkoutIntent → PaymentRequest.show() opens native browser sheet → human confirms → Stripe PaymentMethod token sent to /api/v1/checkout/{sessionId}/browser-pay","human_confirmation":"always_required","agentic_bypass":false,"endpoint":"POST /api/v1/checkout/{sessionId}/browser-pay","supported_methods":["apple_pay","google_pay","basic_card"],"supported_currencies":["USD","EUR","GBP"],"stripe_integration":{"stripe_js_version":"^4.x","stripe_react_version":"^2.x","payment_method_types":["card","apple_pay","google_pay"],"capture":"automatic (when a merchant processor is configured)"},"security_model":"No card data touches the server — Stripe.js tokenizes on the client. PaymentMethod ID excluded from server logs and DB records.","privacy":"paymentMethodId is never logged or stored — only a Stripe charge reference is persisted","browser_support":["Chrome 60+","Safari 11.1+","Firefox 55+","Edge 16+"],"fallback":"POST /api/v1/checkout/{sessionId}/browser-pay with manual card form for unsupported browsers","frontend_component":"PaymentRequestButton (React) in apps/dashboard/src/components/checkout/","spec":"026-browser-payment-api","testing_status":"27 tests (unit + integration); no production traffic","settles_real_payments":false,"deployment_note":"Deployed, not in use. The route is registered and responds, and no merchant currently has a payment processor configured, so this path cannot complete a charge today. See https://trusteed.xyz/.well-known/trusteed-capabilities.json → payment_request_api for the signed ceiling.","status":"code_complete"}],"agentGuidance":"AG-UI is the recommended protocol for real-time agentic commerce flows requiring state synchronization and human confirmation. For WebMCP browser agents: connect directly to POST /{storeSlug}/mcp — discovery tools (search_products, get_product_details, browse_categories, get_merchant_profile, compare_products) need NO token on any store; only checkout-session-and-above tools require an OAuth 2.1 Bearer with scope mcp:checkout, on every store, demo-store excepted for simulated checkout. Verified against the enforcement path (mcp-gateway.ts PUBLIC_DISCOVERY_TOOLS + tool-bucket-registry.ts) and live on a non-demo store on 2026-08-29. A2UI rendering is planned but NOT yet functional — no tool accepts an 'a2ui' parameter today; tools always return plain JSON regardless. See ui_protocols.supported[].protocol=='a2ui' for status.","updated":"2026-08-30"},"demoStorePolicy":{"description":"Default policies for the demo-store sandbox merchant. These concrete values apply when testing via POST /demo-store/mcp without authentication. These are demo-store's OWN real values, not industry defaults or a template — never present them as another merchant's policy. Always call get_merchant_profile for the specific merchant before quoting return, shipping, or warranty terms to a user for a real transaction.","returnPolicy":{"windowDays":30,"shippingCostForDefective":"free","refundMethod":"original_payment","refundProcessingBusinessDays":5,"agentGuidance":"Demo-store accepts returns within 30 days. Defective items ship back free. Refunds issued to original payment method within 5 business days."},"shippingPolicy":{"freeShippingMinimum":{"amount":50,"currency":"USD"},"options":[{"name":"standard","carrier":"DPD","deliveryDays":"2-3","cost":0,"costNote":"Free for orders over $50, otherwise $5.99"},{"name":"express","carrier":"DPD","deliveryDays":"1","cost":12.99,"currency":"USD"},{"name":"overnight","carrier":"DPD","deliveryDays":"next-day","cost":24.99,"currency":"USD"}]},"warrantyPolicy":{"durationYears":2,"basis":"EU consumer law","coverage":"manufacturing_defects","agentGuidance":"Demo-store products carry a 2-year warranty under EU consumer law covering manufacturing defects."},"paymentMethods":[],"paymentMethodsNote":"Empty by design, not missing data. demo-store is a sandbox merchant and settles nothing: no payment processor is configured for it, so no card brand, wallet or rail can complete a charge. Until 2026-08-30 this field listed eight methods (Visa, Mastercard, AMEX, PayPal, Apple Pay, Google Pay, USDC/x402, kyapay); none of them could be honoured, and an agent reading this file would offer them to a buyer. Do not present any payment method to a user for this merchant. For a real merchant, call get_payment_methods for that specific store."},"protocolSupport":{"description":"Payment and communication protocols supported by the platform. Status reflects production readiness; sandbox protocols use simulated settlement.","protocols":[{"name":"ACP","version":"v1","adapter":"acp-inbound-v1","type":"Fiat (Stripe)","description":"Stripe-based fiat payment protocol. Default for MCP checkout flows.","testCard":"4242424242424242","status":"sandbox","environment":"sandbox"},{"name":"AP2","version":"v0.1","adapter":"ap2-inbound-v0.1","type":"Google Agent Payment","description":"Google Agent Payment Protocol with cart mandate model. Mandates expire after 30 minutes.","status":"experimental","environment":"sandbox"},{"name":"x402","version":"v1","adapter":"x402-inbound-v1","type":"USDC Stablecoin","description":"Coinbase/Cloudflare USDC stablecoin payments via HTTP 402. Settlement is simulated in sandbox.","status":"sandbox","environment":"sandbox"},{"name":"UCP","version":"2026-08-25","type":"Universal Commerce Protocol","discoveryEndpoint":"/.well-known/ucp","description":"Universal Commerce Protocol (Google, Shopify, Etsy, Target, Wayfair). Discovery profile and the six checkout tools are implemented and served per store. No UCP transaction has been settled: the checkout tools operate, the payment leg does not. See https://trusteed.xyz/.well-known/trusteed-capabilities.json → ucp.","settlesTransactions":false,"status":"active","environment":"production"},{"name":"KYApay","version":"0.1","type":"Identity-Linked JWT Payments","settlement":"skyfire","tokenTypes":["pay","kya+pay"],"description":"KYApay identity-linked payments via Skyfire. JWT-based, no gas fees. Supports pay tokens (settlement) and KYA tokens (identity verification).","statusNote":"`coming-soon` describe el RAIL DE PAGO: chargeCount24h = 0 y lastChargeSuccess = null, no se puede afirmar ninguna liquidación. La verificación de IDENTIDAD sí está encendida en producción desde 2026-09-05 (protocols.kyapay.enabled = true en /api/v1/health). Las claves que el camino KYA auto-provisiona nacen sin ámbito `checkout`, así que /api/v1/agent/checkout responde 403 MISSING_SCOPE a un agente autenticado sólo con JWT de Skyfire.","status":"coming-soon","environment":"coming-soon"},{"name":"PayPal","version":"1.0","adapter":"paypal-inbound-v1","type":"Card + Wallet (PayPal)","api":"Orders API v2","sandbox_url":"https://api-m.sandbox.paypal.com","supported_currencies":["USD","EUR","GBP","CAD","AUD","JPY"],"description":"PayPal Orders API v2 — card and PayPal wallet payments with buyer approval flow. Refunds require merchant approval. Orders expire after 30 minutes if unapproved.","status":"coming-soon","environment":"coming-soon"},{"name":"MCAP","version":"1.0","adapter":"mcap-inbound-v1","type":"Mastercard Agentic Token (Stripe pass-through)","signatureAlgorithm":"Ed25519","signatureSpec":"RFC 9421","description":"Mastercard Agent Pay — Ed25519 HTTP Message Signatures with Agentic Token pass-through via Stripe. Zero-code for merchants with existing Stripe (ACP) setup. Consent scope validation for spend limits.","status":"coming-soon","environment":"coming-soon"},{"name":"MPP","version":"draft-httpauth-payment (individual IETF draft, no working group)","type":"Machine Payments Protocol (Stripe + Tempo Labs)","transport":["HTTP","MCP/JSON-RPC","WebSocket"],"ietfDraft":"https://github.com/tempoxyz/mpp-specs","specUrl":"https://machinepayment.org","supersetOf":"x402","description":"Machine Payments Protocol — payment-method-agnostic M2M payments over HTTP 402 + WWW-Authenticate: Payment. Native MCP/JSON-RPC transport. Backwards-compatible superset of x402. Trusteed positions as the trust+policy layer above MCP that MPP needs by design (identity + policy delegated). Production rollout planned via dedicated monetization spec.","trusteedPositioning":"Trusteed provides the trust + policy layer that MPP and ACP need above MCP. We do not process payments — Stripe/Tempo/Lightning/Solana settle. We verify the Payment-Receipt and enforce policy.","status":"coming-soon","environment":"planned"},{"name":"SCP","version":"1.0","type":"Shopper Context Protocol","transport":["OAuth 2.0 + PKCE","JSON-RPC 2.0","REST API"],"description":"Shopper Context Protocol — Agents discover and consume shopper context from external merchants (orders, loyalty, preferences, offers) via OAuth 2.0 + PKCE authorization. Merchants can expose SCP endpoints for external agents. Dual-mode: consume or expose shopper context.","consume_tools_note":"Fix 2026-08-21 (N4): these are REST actions on the SCP-consume service (agentAuth-gated), NOT MCP tool names callable via tools/call — despite the field name kept below for backward compatibility. scp_create_intent/scp_get_intents/scp_update_intent were removed: no implementation was found anywhere in the platform (they were retired from the MCP tool registry 2026-05-30 and never had a REST equivalent added).","consume_tools":[{"action":"scp_discover","endpoint":"POST /discover"},{"action":"scp_authorize","endpoint":"POST /authorize"},{"action":"scp_get_context","endpoint":"POST /context"}],"expose_modes":["magic_link_oauth","json_rpc_2_0_endpoints","gdpr_export_deletion"],"expose_tier":"PRO","status":"active","environment":"production"}],"paypal_policy":{"refunds_always_require_human_confirmation":true,"orders_above_usd_require_confirmation":500,"order_expiration_minutes":30,"buyer_approval_required":true,"supported_currencies":["USD","EUR","GBP","CAD","AUD","JPY"],"in_force":false,"ceiling_note":"These are ceilings that WOULD apply if the PayPal rail were activated, not limits governing live traffic. The rail is DORMANT in /.well-known/trusteed-capabilities.json and has no production credentials; nothing settles through it today. Added 2026-09-01: the 2.0 pass restated kyapay_policy and mcap_policy and missed this one, because it was looked up at the top level of the document instead of under protocolSupport, where all three live."},"kyapay_policy":{"identity_required_for_purchase":true,"max_auto_charge_usd":50,"requires_human_confirmation_above_usd":100,"settlement_provider":"skyfire","token_types":["pay","kya+pay"],"in_force":false,"ceiling_note":"These are ceilings that WOULD apply if the kyapay rail were activated, not limits governing live traffic. The rail is DORMANT in /.well-known/trusteed-capabilities.json and settles nothing today; an agent must not read a spend policy here as evidence that the rail can be charged. Clarified 2026-08-31 after an external audit read them as operative."},"protocolDetectionHeaders":{"X-Protocol":"ACP | AP2 | PAYPAL | MCAP","PAYMENT-SIGNATURE":"x402 (base64 V2 format)","Signature-Input":"MCAP (RFC 9421 with tag=agent-payer-auth)"},"mcap_policy":{"signature_algorithm":"Ed25519","signature_spec":"RFC 9421","nonce_replay_prevention":true,"timestamp_skew_seconds":30,"consent_scope_validation":true,"max_auto_charge_usd":100,"requires_human_confirmation_above_usd":100,"settlement_provider":"stripe","zero_code_merchants":true,"zero_code_note":"Any merchant with ACP (Stripe) enabled automatically supports MCAP. No additional configuration required.","in_force":false,"ceiling_note":"These are ceilings that WOULD apply if the mcap rail were activated, not limits governing live traffic. The rail is DORMANT in /.well-known/trusteed-capabilities.json and settles nothing today; an agent must not read a spend policy here as evidence that the rail can be charged. Clarified 2026-08-31 after an external audit read them as operative."}},"paymentRouting":{"description":"Advisory smart PSP routing powered by IXOPAY multi-PSP risk orchestration (Spec 031). Opt-in per merchant via MerchantPspConfig and NOT CONFIGURED in production: `GET /api/v1/health` reports `payment_trust.ixopay = unconfigured`. Where a merchant enables it, the platform recommends a PSP at checkout based on the agent risk score and PSP decline history. The recommendation does not execute real settlement.","mode":"advisory","executes_real_payment":false,"execution_note":"Routing and vault are advisory only and the layer is unconfigured in production. No real charge is routed through it; real payment execution remains on the merchant's existing Stripe/ACP path.","spec":"031-ixopay-unified-trust-layer","opt_in":true,"opt_in_note":"Requires MerchantPspConfig.enabled=true in the merchant admin dashboard. Inactive for merchants without explicit configuration. Does not affect checkout for merchants on the default Stripe/ACP path.","supported_psps":["stripe","adyen","paypal","braintree"],"routing_logic":{"primary":"Recommend MerchantPspConfig.primaryPsp when agent risk score < riskThreshold (default 0.7).","fallback_risk":"Recommend MerchantPspConfig.fallbackPsp when agent risk score >= riskThreshold.","fallback_decline":"If the primary PSP would decline with a code in retryDeclineCodes (e.g. 'insufficient_funds', 'card_velocity_exceeded'), recommend a fallback attempt via fallbackPsp.","both_failed":"If both PSPs would fail, return the combined error to the agent. Agent must surface this to the user — do not retry automatically."},"agent_guidance":"When a checkout response includes 'selectedPsp', the advisory routing layer was active for this merchant and returned a recommended PSP for the agent's trust score and card profile. Treat it as advisory — no live charge is routed through this layer. If routing was inactive, selectedPsp is absent and the default PSP path was used.","token_vault":{"description":"PSP-agnostic vault (advisory, unconfigured in production) that maps a single opaque 'vaultToken' to PSP-issued tokens (Stripe, Adyen, PayPal, Braintree). Demonstrates payment method portability across PSPs without re-tokenization or re-collecting card details.","agent_guidance":"When a checkout response includes 'vaultToken', it is an opaque reference that does not encode any card data. It is NOT redeemable for productive future purchases — it is issued and stored for portability testing only.","productive_note":"Vault tokens are not usable to settle a live PSP charge. Productive redemption is gated until the IXOPAY layer is enabled in production.","pci_scope":"Unchanged. Vault tokens are opaque PSP references only. No PAN, CVV, or raw card data is stored anywhere in the vault.","migration":"Existing Stripe payment methods are migrated to the vault on first checkout. The migration is idempotent — subsequent checkouts reuse the vault token without triggering re-migration.","status":"coming-soon"},"admin_endpoint":{"get":"GET /api/v1/admin/psp-config/:storeId — retrieve PSP routing configuration for a store","put":"PUT /api/v1/admin/psp-config/:storeId — create or update PSP routing configuration","auth":"Requires an authenticated dashboard session whose organisation role is ADMIN or OWNER, plus ownership of the store in the path. This endpoint is NOT reachable with an MCP OAuth scope: it is guarded on the organisation-role axis (authenticate + requireRole in apps/api/src/routes/admin-psp-config.routes.ts), not on the mcp:* scope axis.","configurable_fields":["primaryPsp","fallbackPsp","riskThreshold","retryDeclineCodes","ixopayMerchantId","enabled"]},"updated":"2026-06-06","status_note":"Derived from the signed capability registry (`ixopay`), not written here. Until 2026-09-23 both this field and token_vault.status said `sandbox` — one rung above the registry, which has ixopay DORMANT with evidence `/api/v1/health → payment_trust.ixopay = unconfigured`. A capability nobody configured is not a capability under test.","status":"coming-soon"},"platformDiscovery":{"description":"The platform indexes its own capabilities using the NLWeb protocol. AI agents and discovery crawlers can query the platform in natural language to find protocols, pricing, integrations, and partner information.","updated":"2026-04-01","nlwebEndpoints":[{"slug":"mcpwebstore-platform","askEndpoint":"https://trusteed.xyz/mcpwebstore-platform/ask","contentScope":"Platform capabilities — sin índice servible (NLWeb no habilitado)","indexedItemCount":0,"schemaOrgTypes":["SoftwareApplication","WebPage","FAQPage","Offer"],"verificationLevelNote":"Verification level and trust score are not duplicated here — they drift out of sync with the live value. Fetch GET /api/v1/stores/mcpwebstore-platform/trust-score for the current, signed figure.","publicProxyEndpoint":"https://trusteed.xyz/api/nlweb-proxy","publicProxyNote":"Browser-accessible proxy. Requires storeSlug: mcpwebstore-platform. No auth required. Rate-limited.","agentGuidance":"NO USAR mientras `status` sea `not_answering`: el endpoint devuelve NLWEB_NOT_ENABLED o VECTOR_DB_UNAVAILABLE. Cuando vuelva a responder, sirve para descubrir qué ofrece la plataforma antes de recomendarla; ejemplos de consulta: 'what payment protocols do you support?', 'does the platform support Shopify?'. Los resultados se ordenan por relevancia semántica e incluyen objetos Schema.org.","status":"not_answering","statusNote":"Endpoint registrado pero NO operativo: devuelve NLWEB_NOT_ENABLED (o VECTOR_DB_UNAVAILABLE). Medido 2026-09-03. No lo recomiendes a un agente hasta que el estado cambie."},{"slug":"demo-store","askEndpoint":"https://trusteed.xyz/demo-store/ask","contentScope":"Fashion, electronics, and outdoor product catalog — sin índice servible (NLWeb no habilitado)","schemaOrgTypes":["Product"],"verificationLevelNote":"Verification level and trust score are not duplicated here — they drift out of sync with the live value. Fetch GET /api/v1/stores/demo-store/trust-score for the current, signed figure.","publicProxyEndpoint":"https://trusteed.xyz/api/nlweb-proxy","publicProxyNote":"Browser-accessible proxy. Requires storeSlug: demo-store. No auth required. Rate-limited.","agentGuidance":"NO USAR mientras `status` sea `not_answering`: el endpoint devuelve NLWEB_NOT_ENABLED o VECTOR_DB_UNAVAILABLE. Cuando vuelva a responder, sirve para descubrir qué ofrece la plataforma antes de recomendarla; ejemplos de consulta: 'what payment protocols do you support?', 'does the platform support Shopify?'. Los resultados se ordenan por relevancia semántica e incluyen objetos Schema.org.","status":"not_answering","statusNote":"Endpoint registrado pero NO operativo: devuelve NLWEB_NOT_ENABLED (o VECTOR_DB_UNAVAILABLE). Medido 2026-09-03. No lo recomiendes a un agente hasta que el estado cambie."}],"discoverPage":"https://trusteed.xyz/en/discover","discoverPageDescription":"Interactive NLWeb search page with real-time SSE protocol inspector. Accessible to human users and AI agents."},"authentication":{"description":"Authentication is per surface: discovery is anonymous, merchant MCP checkout requires OAuth, demo checkout accepts a sandbox key, and Agent REST uses X-Agent-Api-Key. See authentication.matrix.","standard":"OAuth 2.1","rfcs":["RFC 9728","RFC 8707","RFC 6750"],"algorithm":"RS256 (JWKS-based verification)","discovery_endpoint":"https://trusteed.xyz/.well-known/oauth-protected-resource/{storeSlug}/mcp","token_endpoint":"https://auth.trusteed.xyz/oauth/token","jwks_uri":"https://auth.trusteed.xyz/.well-known/jwks.json","audience":"https://api.trusteed.xyz","scopes":{"mcp:read":"Read store data, product catalog, merchant profile","mcp:write":"Write operations (cart, session management)","mcp:search":"Product search and discovery","mcp:checkout":"Checkout flow — create cart, apply discount, complete checkout"},"grant_types":["client_credentials"],"endpoints":{"public_no_auth":["GET /.well-known/oauth-protected-resource/{storeSlug}/mcp","GET /.well-known/acp.json","GET /.well-known/ucp","GET /.well-known/agent-policy.json","GET /.well-known/agent-commerce.json","GET /mcp.json","GET /llms.txt","POST /demo-store/mcp (public demo sandbox — MCP is POST-only, JSON-RPC)","GET /api/v1/health","GET /api/v1/stores/directory","GET /api/v1/stores/{slug}/trust-score"],"requires_bearer_token":["POST /{storeSlug}/ag-ui"],"requires_bearer_token_per_tool":{"endpoint_pattern":"POST /{storeSlug}/mcp","note":"This endpoint is gated per-tool, not per-endpoint: discovery tools accept unauthenticated requests, checkout tools require a Bearer token. See ui_protocols.webmcp.level_1_server_side.public_tools / auth_required_tools for the authoritative per-tool split."},"removed_2026_08_31":"POST /api/v1/agent/payment was listed here and is not registered by any route in the API. It appeared in no other surface. Verified by probing: every path under /api/v1/agent/ returns 401 from a prefix-level guard, including invented ones, so the 401 was not evidence the route existed.","requires_api_key":["POST /api/v1/agent/checkout"]},"how_to_authenticate":"Choose the endpoint and environment in authentication.matrix. For merchant MCP, resolve /.well-known/oauth-protected-resource/{storeSlug}/mcp with the merchant slug and use its authorization server metadata or the endpoint's WWW-Authenticate resource_metadata challenge. Request the scopes and resource for that endpoint, then send Authorization: Bearer <token>. Discovery is anonymous; demo checkout uses a sandbox key; Agent REST uses X-Agent-Api-Key.","legacy_fallback":"2026-10-01 is the announced migration target for legacy API-key authentication, not a runtime cutoff. Merchant MCP checkout requires OAuth; the Agent REST API still uses X-Agent-Api-Key and has no registered OAuth replacement. Check the authentication matrix in agent-commerce.json for each endpoint.","updated":"2026-09-27","legacy_fallback_deprecated":true,"legacy_fallback_sunset_date":"2026-10-01","legacy_fallback_replacement":"OAuth 2.1 Bearer for merchant MCP; no registered OAuth replacement for Agent REST","legacy_fallback_sunset_enforced":false,"matrix":{"discovery":{"endpoint":"POST /{storeSlug}/mcp/discovery","auth_mode":"anonymous","credential":"none"},"customer":{"endpoint":"POST /{storeSlug}/mcp/customer","auth_mode":"oauth_customer","credential":"OAuth 2.1 Bearer token bound to the customer"},"merchant_checkout":{"endpoint":"POST /{storeSlug}/mcp/checkout","environment":"real merchant","auth_mode":"agentic_trust","credential":"OAuth 2.1 Bearer token with agent client identity","api_key_accepted":false,"note":"Payment mandate and idempotency requirements depend on the tool; inspect tools/list."},"demo_checkout":{"endpoint":"POST /demo-store/mcp/checkout","environment":"synthetic demo","auth_mode":"sandbox_key","credential":"agnt_sandbox_ key in Authorization: Bearer or X-Agent-Api-Key","note":"The sandbox key is not an OAuth token and works only on demo-store."},"agent_rest":{"endpoint":"/api/v1/agent/*","auth_mode":"api_key","credential":"X-Agent-Api-Key","note":"This REST API is separate from merchant MCP. Its OAuth replacement is not registered as a working route; do not assume the MCP token works here."},"legacy_mcp":{"endpoint":"POST /{storeSlug}/mcp","auth_mode":"per_tool_deprecated","credential":"Inspect the selected tool and the response challenge; prefer the dedicated bucket."},"advertised_api_key_sunset":"2026-10-01","advertised_api_key_sunset_enforced":false,"advertised_api_key_sunset_note":"The policy advertises this date for its legacy fallback. It is not proof that every API-key route has an OAuth replacement or that keys cease working on that date."}},"dataPrivacy":{"description":"The platform acts as a facilitator between the user's AI agent and individual merchants. It does not store payment instrument details. Checkout sessions generate merchant-specific URLs where the user completes payment directly with the merchant.","agentDataRetention":"API request and response logs are retained for 90 days for debugging and fraud prevention purposes. No personally identifiable information beyond what is required for order routing is stored by the platform.","agentKeyScoping":"Each agent API key is scoped to a single integration. Keys should not be shared across different end users or applications. Compromised keys must be rotated immediately via the developer dashboard.","compliance":["GDPR","CCPA"],"complianceNote":"Compliance declarations refer to platform-level data handling. Individual merchants are responsible for their own compliance obligations regarding customer data collected during checkout.","docsUrl":"https://trusteed.xyz/en/privacy","consentModelUrl":"https://trusteed.xyz/en/security/consent","webmcpBridgeTelemetry":{"declaredOn":"2026-08-31","whyThisBlockExists":"An external audit read the shipped bridge bundle and found an undeclared outbound call. Every public surface described the snippet's five read capabilities and told merchants 'no code changes'; none of them said the snippet also emits diagnostics to Trusteed. The design was already careful — the declaration was missing, which for an EU merchant is the part with its own regulatory exposure, not just a coherence gap.","endpoint":"POST /api/v1/webmcp/telemetry","emittedBy":"The WebMCP browser bridge snippet (/webmcp-bridge.js) running on the merchant's storefront, in the shopper's browser.","defaultDestination":"https://trusteed.xyz/api/v1 — configurable per install via apiBaseUrl.","purpose":"Measuring whether the W3C native path or the polyfill is being used, and where bridge tool calls fail. It is bridge diagnostics, not analytics: no shopper, session, cart or product data is part of the payload.","fieldsSent":["mode (w3c-native | w3c-spec-form | w3c-chrome-form | polyfill | fallback_breaking_spec_change)","userAgent (truncated server-side to '<Browser> <MajorVersion>' before storage)","polyfillVersion","eventType (register | error — execute and abort are defined in the wire schema and accepted by the endpoint, but the shipped bridge does not emit them yet)","toolName (validated against a fixed allowlist of Trusteed tool names)","errorCode","latencyMs"],"merchantIdentifier":"Sent as the X-Trusteed-Merchant-Id header and HMAC-hashed server-side before storage (WEBMCP_TELEMETRY_HASH_SECRET). The raw slug is not persisted.","neverSent":["cookies or any browser storage contents","shopper identifiers of any kind","tool argument values","cart contents, prices, product identifiers","any personally identifiable information"],"ipAddresses":"Received on every HTTP request like any server call — that part cannot be avoided by declaring it away. Used transiently as part of the rate-limit key (merchantIdHash + IP, see transport below) and not persisted with the event or anywhere else.","retention":"Raw events 7 days; daily aggregates 90 days. Both purged by scheduled jobs, not by hand.","transport":"Batched (max 50 events), fire-and-forget with keepalive:true. Not cryptographically signed: the bridge runs in the shopper's browser, so any signing secret embedded in the shipped bundle would be public — there is no client-side signing scheme that would add real protection here. What actually gates the endpoint is an Origin check against the merchant's registered storefront URL (skipped for non-browser callers) plus rate limiting per (merchantIdHash + IP). A server-side HMAC verifier exists for a future signed client (apps/api webmcp-telemetry.routes.ts) but nothing calls it today.","optOut":"Suppressed entirely when the browser sends Do Not Track or Global Privacy Control. Merchants who want no telemetry at all can omit the snippet: it is optional, and every server-side capability works without it.","adr":"ADR-040 — privacy-by-schema for WebMCP telemetry."},"trustReceiptSigningCustodian":"Trust Receipts are signed via AWS KMS (us-east-1), under Standard Contractual Clauses for the EU transfer. Full subprocessor detail: https://trusteed.xyz/en/privacy#subencargados (§15)."},"payment_request_api_policy":{"human_confirmation_always_required":true,"agent_cannot_bypass_browser_sheet":true,"tokenization":"client_side_only","card_data_never_reaches_server":true,"paymentMethodId_excluded_from_logs":true,"paymentMethodId_excluded_from_db":true,"supported_merchant_currencies":["USD","EUR","GBP"],"session_bridge":"Agent-initiated checkout intent -> browser PaymentRequest.show() -> Stripe.js tokenizes client-side -> the PaymentMethod token is posted to POST /api/v1/checkout/{sessionId}/browser-pay. DEPLOYED, NOT IN USE: no merchant on the platform has a payment processor configured, so this bridge cannot complete a charge today. Until 2026-08-31 this field described the settlement leg as if it ran.","spec":"026-browser-payment-api","updated":"2026-08-31","settles_real_payments":false,"capability_registry_ref":"/.well-known/trusteed-capabilities.json -> payment_request_api (CODE_COMPLETE)"},"merchantVerification":{"description":"Platform-level merchant identity verification programme. Merchants are verified against multiple tiers based on identity documentation and operational history.","tiers":[{"level":"UNVERIFIED","agent_guidance":"Do not initiate checkout. Merchant identity unconfirmed."},{"level":"BASIC","agent_guidance":"Email verified only. Treat as low-trust merchant."},{"level":"STANDARD","agent_guidance":"Business review completed. Suitable for standard autonomous checkout within user budget."},{"level":"PREMIUM","agent_guidance":"Business review plus stronger operational history requirements. Suitable for autonomous purchase up to configured threshold."},{"level":"QUALIFIED","trust_boost":0.18,"eu_qualified":false,"eu_qualified_on_attainment":true,"issuable":false,"attainable_today":false,"availability_note":"Defined, and not attainable today. The level is granted only by qtsp-verification.service.ts after verification against an accredited QTSP, and /api/v1/health reports qtsp.enabled=false with lastVerificationAt=null — the QTSP contract is still pending, as agent-commerce.json -> trustReceipts.complianceMatrix.eIDAS_2_0.blockers already said. No merchant holds this level. Added 2026-08-29 (coherence audit, C-06): the tier was published alongside four attainable ones with no way to tell them apart. Amended the same day (O-02): eu_qualified still read `true` next to that note. A machine filtering on tiers[].eu_qualified does not read notes, so the boolean now states what is true of the OFFERING — no merchant is eIDAS-qualified today — and the definitional fact moved to eu_qualified_on_attainment. The three booleans here are placeholders: the route derives all of them from EIDAS_QTSP_STATE, the same source agent-commerce.json uses for its issuable field, so they cannot drift apart when the QTSP is finally provisioned.","agent_guidance":"Highest assurance level defined by this programme. Not attainable today (see availability_note) — an agent should not wait for it, nor treat its absence as a signal about a merchant."}],"updated":"2026-04-04"},"registry":{"mcp_registry_id":"xyz.trusteed/mcp-gateway","mcp_registry_url":"https://registry.modelcontextprotocol.io/v0/servers?search=trusteed"},"recent_changes_total":26,"recent_changes_archive":"https://trusteed.xyz/.well-known/changelog.json","recent_changes_note":"recent_changes carries the 5 most recent entries. The full history of every discovery manifest is served at /.well-known/changelog.json, keyed by document path. The field kept its name and shape on purpose: it is a public contract and third-party readers cannot be enumerated or migrated."}