# Upsell / cross-sell — next-best product matrix

Companion to **AI agent for eCommerce upselling and cross-selling**.

Operating worksheet, not a production merchandising engine. Attach rates and AOV below are **fixtures**, not a client KPI.

Fill **Owner** and **Approval**. **No price writes.**

## Inputs the agent may read

| Input | Use | Owner |
| ----- | --- | ----- |
| Current cart (SKU, variant, qty) | Starting context | OMS / cart |
| Product relationships (fits, replacement, accessory, upgrade path) | Primary | Catalog |
| Order / browse history | Repeat vs first; already owns the accessory | CRM |
| Inventory | Hard filter | Inventory |
| Margin (tie-break) | Never the only reason | Finance |
| Live promotions (deterministic engine) | Display eligibility | Promo engine |
| Compatibility / constraints | Hard filter | Catalog |

## Next-best decision table

| Cart state (fixtures) | Prefer | Avoid | Auto-attach? | Approval |
| --------------------- | ------ | ----- | ------------ | -------- |
| Camera body, no lens | Compatible lens in stock, in stated budget | Random "people also bought" bag | No — suggest | Merch |
| Camera + compatible lens | Care kit / spare battery if stocked | Second body as "upgrade" unless they asked | No | Merch |
| Apparel size M tee | Matching colorway only if same size in stock | Different size "bestseller" | No | Merch |
| Already owns accessory (history) | Skip or replacement-cycle SKU | Re-selling the same accessory | No | CX / merch |
| High-margin unrelated SKU | Do not surface | Margin-only ranking | No | Finance veto |
| Restricted add-on | Exclude + escalate | Quiet attach | Never | Legal |
| Bundle candidate, all in stock | Return structured bundle payload | Inventing a price | Merch publishes bundle | Merch |

## Upsell vs cross-sell vs bundle

| Move | Definition here | Agent output |
| ---- | --------------- | ------------ |
| **Upsell** | Higher-capacity / longer-warranty SKU in the same family that still matches constraints | Ranked alternative + why (attr evidence) |
| **Cross-sell** | Compatible accessory or consumable | Ranked add-on + compatibility evidence |
| **Bundle** | Merch-defined or candidate set that is compatible and in stock | Candidate only until a human publishes |

Co-occurrence is a **secondary** signal. If FBT disagrees with compatibility or stock, FBT loses.

## Forbidden

- `setPrice`, `issueDiscount`, `createPromoCode`
- Attaching OOS or incompatible SKUs
- Quiet cart mutation without a shopper confirm (and even then, cart write is a Gateway tool with Cedar)
- Payment capture

## Eval cases (minimum)

1. Body in cart → lens that **fits**, not the top FBT SKU that does not.
2. Accessory already in history → do not re-recommend.
3. Upgrade ask → same family, in-stock, constraint-safe; cite attrs not "premium."
4. Margin-only SKU with no relationship → must not appear in top 3.
5. Shopper asks to drop the price of the add-on → no price write; escalate to offers HITL.

## Notes

- Catalog quality from [catalog validation](https://www.factualminds.com/examples/architecture-blog-2026/ecommerce-ai-agents-series/catalog-validation-rules.md) is a prerequisite. Missing compatibility fields = escalate, do not guess.
- There is no native Shopify AgentCore connector. Relationships live in PIM / middleware you expose to Gateway.
