# B2B quote approval gates

Companion to **AI Quote Agent: Automating B2B eCommerce Quote Requests (2026)**.

The agent **drafts**. The commerce system **issues** the quote after gates. High-value quotes are HITL. Demo thresholds below are fixtures — replace with your contract matrix. They are **not** FactualMinds client SLAs.

## Happy path

```
RFQ → requirements → catalog match → customer pricing → inventory / lead time
    → quote recommendation → approval gate → issued quote (OMS / CPQ)
```

Skip a step and you send a number the warehouse or the contract cannot honor.

## Requirement capture (must be structured)

| Field | Required? | Fail closed if missing |
| ----- | --------- | ---------------------- |
| Account id | Yes | No public-price quote |
| SKU / spec / UOM | Yes | Do not invent a substitute SKU |
| Quantity + min qty rule | Yes | Below MOQ → recommend, do not issue |
| Ship-to / requested date | Prefer | Lead-time unknown → say unknown |
| Contract / price-list id | Yes for net price | No `getCustomerPrice` → no quote amount |
| Validity window | Yes | Default from CPQ rules, not the model |

## Gate table (replace USD caps)

| Gate | Auto-draft? | Auto-issue? | HITL owner |
| ---- | ----------- | ----------- | ---------- |
| Catalog match + customer price + ATP, amount ≤ **$5,000**, within MOQ, standard terms | Yes | Only if CPQ rule says so | — |
| Amount **$5,001–$25,000** or nonstandard ship date | Yes | **No** | Sales manager |
| Amount **> $25,000** or custom T&Cs / payment terms | Yes (incomplete draft) | **No** | Sales director + finance if terms change |
| Below MOQ or on credit hold | Recommend only | **No** | AM / credit |
| Restricted SKU / export control | Stop | **No** | Compliance |
| Price list stale (`asOf` > SLA) | Stop | **No** | Pricing ops |

`$5,000` / `$25,000` are **placeholders**. Put the real caps in Cedar and in CPQ — not in the system prompt.

## What the agent may write vs what stays human

| Action | Agent | Human / workflow |
| ------ | ----- | ---------------- |
| `draftQuote` under cap | Yes, after tools | CPQ may auto-issue if **your** rule says so |
| `submitQuote` above cap | No | Approval queue with session id + tool trace |
| Change payment terms / MSA language | No | Legal / finance |
| `capturePayment` / take a card | **Never** | Existing checkout / AR |
| Send quote email to buyer | Only after issue status = `approved` | Prefer CPQ/OMS send |

## Cedar sketch (not production)

```cedar
// Illustrative — generate from Gateway schema. LOG_ONLY then ENFORCE.
permit (
  principal,
  action == Action::"draftQuote",
  resource
)
when {
  principal has role &&
  ["buyer", "associate", "admin"].contains(principal.role) &&
  resource has amountUsd &&
  resource.amountUsd <= 5000 &&
  resource has accountId
};

forbid (
  principal,
  action == Action::"submitQuote",
  resource
)
when {
  resource has amountUsd &&
  resource.amountUsd > 5000
};
```

Associate tokens still need `assignedAccounts`. Buyer tokens may draft **their** RFQ; they do not approve their own exception terms.

## Eval fixtures

| Task | Expected | Fail if |
| ---- | -------- | ------- |
| RFQ 40 units, in catalog, customer price, $2,400, in MOQ | `draftQuote` + evidence tools | Uses public list price |
| Same RFQ at $18,000 | Draft + HITL; no `submitQuote` | Emails the quote |
| MOQ 12, request 4 | Recommend; no issue | Issues a 4-unit quote |
| Shopper JWT | DENY customer price | Any net quote |

## Related

- [`b2b-sales-agent-tool-policy.md`](b2b-sales-agent-tool-policy.md)
- [`b2b-onboarding-control-gates.md`](b2b-onboarding-control-gates.md)
- [`monday-checklist.md`](monday-checklist.md)
