AI Negotiation Without Hallucinated Discounts
Design AI negotiation with typed offers, deterministic price floors, exact approvals, concurrency control and live state so every discount is valid at runtime.

AI negotiation becomes dangerous when fluent language is allowed to create commercial permission. The buyer's agent asks for 18 percent off. The merchant agent replies: "I can do 20 percent and include priority shipping."
The exchange sounds fluent. It may also be commercially impossible. The inventory is scarce, the product margin cannot support 20 percent, priority shipping is unavailable for that destination, and nobody gave the agent authority to bundle it.
This is the wrong place to celebrate creativity.
An enterprise negotiation agent should be expressive in language and boring in authority. The model can interpret the request, identify negotiable dimensions and phrase a counteroffer. Deterministic services must calculate the feasible offer set, apply price and margin rules, enforce approvals and commit the accepted terms.
The LLM writes the sentence. It does not invent the discount.
AI negotiation is a constrained state transition
Teams often model negotiation as a conversation:
buyer message -> model -> seller message -> model -> agreement
That loses the commercial object inside the prose. A better model is a sequence of versioned offers:
buyer intent
-> normalized proposal
-> merchant eligibility and authority check
-> feasible counteroffer set
-> selected offer
-> signed offer state
-> buyer acceptance
-> checkout refresh
-> committed order
Every offer has explicit terms and lifecycle state:
type Offer = {
offerId: string
revision: number
sellerId: string
buyerContextId: string
lineItems: Array<{ variantId: string; quantity: number }>
currency: string
subtotal: string
discount: { type: 'percent' | 'fixed'; value: string }
shippingOptionId: string
paymentTermsId: string
expiresAt: string
inventoryReservationId?: string
policyDigest: string
status: 'proposed' | 'countered' | 'accepted' | 'expired' | 'withdrawn'
}
Do not reconstruct accepted terms from the last chat message. Bind acceptance to the exact offer ID, revision and digest.
Give the model capabilities, not commercial freedom
The negotiation model can use tools such as:
interpret_proposal
get_negotiable_dimensions
request_feasible_offers
explain_counteroffer
submit_offer_for_approval
accept_offer
It should not have a generic set_discount(percent) tool that trusts model output. The policy service receives normalized transaction facts and returns candidates the merchant is willing to honor.
{
"request": {
"variant_id": "variant:compressor-14kw",
"quantity": 12,
"requested_discount_percent": "18.0",
"destination": "warehouse:rotterdam-2",
"requested_terms": "net_45"
},
"authority": {
"max_autonomous_discount_percent": "8.0",
"max_approved_discount_percent": "15.0",
"allowed_payment_terms": ["prepaid", "net_15", "net_30"],
"allowed_destinations": ["warehouse:rotterdam-2"]
}
}
The returned candidate might trade discount for another dimension:
{
"decision": "counter",
"candidates": [
{
"discount_percent": "8.0",
"payment_terms": "net_30",
"shipping_option": "standard"
},
{
"discount_percent": "11.0",
"payment_terms": "prepaid",
"shipping_option": "standard",
"requires_approval": true
}
],
"prohibited": ["net_45", "priority_shipping"]
}
The model selects a permitted candidate according to merchant objectives, then explains it. It cannot create a third offer by averaging the two.
Separate policy, optimization and language
These are three different functions.
Policy establishes the feasible region. It applies hard constraints such as legal eligibility, contract terms, channel rules, minimum margin, promotion stacking, approval thresholds and authority limits.
Optimization chooses among feasible offers. It can consider conversion probability, inventory age, customer lifetime value or fulfillment cost. The objective is merchant-specific and may change.
Language communicates the selected offer and asks for missing information. It should receive the offer object as immutable input.
const feasible = policy.evaluate({
proposal,
merchantRules,
agentMandate,
liveInventory,
contextualPrice,
customerEntitlements
})
if (feasible.decision === 'deny') return explainDenial(feasible)
if (feasible.decision === 'approval_required') return routeApproval(feasible)
const selected = optimizer.choose(feasible.candidates, merchantObjective)
const signedOffer = offerService.issue(selected)
return model.explain({ offer: signedOffer, buyerRequest: proposal })
Do not encode a price floor as a large negative reward. An optimizer can trade against a penalty. A floor is a predicate that removes an offer from the candidate set.
Use the commerce platform's pricing engine
The agent should not duplicate years of pricing logic in a prompt. Existing platforms already calculate discounts against structured cart context. Shopify's Discount Function API, for example, passes selected cart fields into a function and expects ordered discount operations in return. Functions run within the checkout logic and are subject to configured combination rules. Shopify's official Discount Function documentation is closer to the right trust boundary than a prompt containing "never discount more than 10 percent."
The merchant adapter should translate a proposed agent offer into the platform's native pricing and checkout primitives. It should then compare the authoritative result with the signed offer. If taxes, shipping, promotion stacking or eligibility change the total, return a structured counter or invalidation.
Keep unique policy logic out of connectors. The connector translates. The deterministic decision layer owns the cross-platform authority rules.
Bind authority to the negotiating agent
A merchant may run several agents with different jobs. A support agent might offer a refund but not negotiate a new sale. A wholesale agent may negotiate quantity discounts for approved buyers. A clearance agent may discount selected inventory during one campaign.
A negotiation mandate should bind:
- accountable merchant organization
- agent and runtime proof key
- action such as
offer.counter - product, category or campaign scope
- buyer segment or named counterparty
- market and destination
- autonomous discount ceiling
- approval ceiling
- allowed non-price terms
- cumulative campaign or customer budget
- expiry, uses and delegation limits
The transaction should also bind the incoming proposal. Otherwise an approved counteroffer for 12 units can be replayed against 120 units.
Make approval an exact transaction
"Approve this customer discount" is not enough. The approval object needs the offer digest, buyer, products, quantities, currency, destination, payment terms, expiry and policy version.
If any protected field changes, request approval again.
{
"approval_id": "approval:offer:9918",
"offer_digest": "sha256:7fc2...",
"approver_role": "regional_sales_director",
"decision": "approved",
"approved_at": "2026-08-11T11:02:00Z",
"expires_at": "2026-08-11T11:17:00Z"
}
The current OATI developer preview models deterministic allow and deny at its evaluator core. A complete transaction-level approval service and merchant negotiation engine belong to Intelliger's target commerce roadmap, not the implemented claim. The example above describes the intended control object.
Use a state machine for concurrent negotiation
Two agents can negotiate the same inventory or customer allowance at once. A static discount check does not prevent both from accepting.
DRAFT -> ISSUED -> COUNTERED -> ACCEPTED -> CHECKOUT_PENDING -> COMMITTED
| | |
v v v
EXPIRED WITHDRAWN INVALIDATED
Use optimistic concurrency on offer revision. Accepting revision 4 must fail if revision 5 already exists. Reserve scarce inventory or commercial budget when policy requires it, with a clear expiry. Idempotency keys should make a repeated acceptance return the same outcome rather than create another order.
UCP's Checkout specification requires idempotency for completion in its MCP binding and treats checkout as the point where binding transaction data drives eligibility and policy. UCP Checkout over MCP shows why a conversational agreement still needs a stable state handle and retry-safe completion.
Do not negotiate against stale state
Price, inventory and fulfillment can change during a long exchange. Set an offer expiry and record the observation times used to calculate it. Refresh live state before acceptance and again at checkout if the platform requires it.
Choose explicit behavior for each change:
| Change | Response |
|---|---|
| Inventory falls below requested quantity | invalidate or reduce quantity with buyer consent |
| Base price changes | reprice and issue a new revision |
| Promotion expires | remove it, do not preserve from chat history |
| Shipping option becomes unavailable | offer an eligible alternative |
| Buyer entitlement changes | reevaluate the whole offer |
| Mandate is revoked | stop negotiation and reject acceptance |
| Approval expires | request a new approval |
The model can explain the update. It cannot decide to grandfather an expired price unless policy returns that option.
Adversarial cases for the simulator
Use negotiation traces that try to move one field at a time:
- ask the model to "make an exception" after a policy denial
- hide a discount inside free shipping or extended payment terms
- change currency without recalculating the floor
- split one order into several offers to evade an approval threshold
- replay an accepted offer for another buyer
- increase quantity after approval
- combine promotions that the commerce platform marks incompatible
- use a stale inventory reservation
- create two concurrent acceptances for one offer revision
- inject instructions through product descriptions or buyer notes
- request an unsupported refund as part of a new-sale negotiation
- delegate to a child agent with a higher discount ceiling
Score the system on constraint violations, approval precision, unsupported-term rate, stale-offer acceptance and reconciliation quality. A high deal-closure rate is dangerous if the agent closes deals the merchant cannot honor.
Protocols do not remove merchant policy
AP2 explicitly requires deterministic processing for validation roles and binds payment authority to mandates and checkout data. AP2 does not tell a merchant which discount to offer. UCP structures checkout state and escalation, but the business remains responsible for eligibility and policy. ACP connects agents and merchant backends while merchants continue to handle payment, fulfillment and support through their systems. OpenAI's ACP overview describes that division.
An agentic-commerce gateway should support these protocols without moving pricing authority into the protocol adapter. Stable internal offer and policy objects make that possible.
What Intelliger has now, and what comes later
OATI Commerce's developer preview currently enforces signed price, currency, per-transaction and cumulative budget constraints, usage consumption and context substitution resistance. It includes schemas, SDKs, middleware, shared conformance vectors and a local paid-API transaction.
Bounded negotiation, counterfactual planning, merchant-objective optimization, a commerce simulator and learned outcome scoring are target-state stages in the August 2026 agentic-commerce blueprint. They follow authoritative commerce integration and verified trajectory data. They should not be presented as current production services.
Implementation checklist
- Normalize every proposal into typed, versioned offer terms.
- Let policy generate or validate the feasible offer region.
- Keep price floors and authority limits out of reward functions.
- Reuse authoritative pricing, promotion and checkout engines.
- Bind the incoming proposal, offer revision and buyer context.
- Give each agent a narrow, expiring negotiation mandate.
- Bind approvals to the exact offer digest.
- Apply optimistic concurrency to revisions and acceptance.
- Reserve scarce inventory and commercial budget atomically where needed.
- Refresh live price, inventory and delivery before commitment.
- Carry one idempotency key through checkout retries.
- Simulate threshold splitting, replay, stale state and hidden concessions.
Natural language makes negotiation usable. Deterministic constraints make the resulting offer real. If the model can manufacture a commercial term that the pricing and authority layers never produced, the system is improvising liabilities.
Make every sentence trace back to an offer object the merchant can actually honor and reconcile.
The offer still needs AI agent authorization that cannot be inferred from identity. If acceptance triggers payment, the agentic payments architecture keeps the model outside the value-release boundary.