Eligibility & Visibility Semantics
com.os.retailagent.shopping.eligibility
Layer: RetailAgentOS extension on top of UCP (Universal Commerce Protocol) · Reference implementation in Playground
Abstract
This spec defines a machine-readable way for a merchant to declare who may see a product and who may buy it, and why — evaluated against a buyer's context at catalog time, before a cart is ever built. It produces two computed outputs an AI agent (or any UI) can act on: Visibility (surface it or not) and Eligibility (can this buyer purchase, and if not, what would fix it).
The defining feature is reasons. Eligibility is not a boolean. Every decision carries a structured reason code, a human message, and — where a path exists — the requirement that would resolve it. An agent can therefore explain a block and guide a buyer toward qualifying, instead of failing silently at checkout.
The problem this solves
Right now, a merchant's rules about who can buy what live deep in the checkout flow — invisible to any AI agent doing discovery. The result:
- A wholesale-only SKU is surfaced to a guest, who hits a wall at checkout.
- An agent builds a cart for a buyer who was never eligible — dead end.
- A buyer who could qualify (link an account, upload a resale certificate) is simply blocked, with no path shown.
The core idea: move merchant reasoning from checkout-time to catalog-time, with machine-readable reasons attached.
What goes in
Merchant declares on the product
Visibility gates, account requirements, tier restrictions — attached to each variant at catalog time.
Agent supplies buyer context
Customer type, membership tier, region, fulfillment mode — the agent knows who it's shopping for.
What comes out
ComputedVisibility
VISIBLE — surface and recommend freely.
HIDDEN — do not surface at all. Never quote or add to a cart.
ComputedEligibility
ELIGIBLE — proceed freely.
CONDITIONAL — blocked now, but a resolvable path exists.
BLOCKED — no path. Explain and stop.
Reason code registry
The registry is the heart of interoperability — two systems agree on codes, not on prose. Messages are localizable; codes are stable.
| Code | Meaning | Severity | blocking | Resolvable? |
|---|---|---|---|---|
HIDDEN_PRODUCT | Item is not visible in this context (guest visibility gate) | BLOCK | true | No |
REGION_RESTRICTED | Not available in the buyer's market region | BLOCK | true | No |
WHOLESALE_ONLY | Requires a wholesale or B2B account | BLOCK | true | Become a wholesale account |
RESALE_CERTIFICATE_REQUIRED | Resale certificate must be on file | BLOCK | true | Upload a resale certificate |
TIER_RESTRICTION | Requires a higher membership tier (BLOCK + requirements[] → status: CONDITIONAL) | BLOCK | true | Upgrade membership tier |
FULFILLMENT_UNAVAILABLE | Not available for the requested fulfillment mode | BLOCK | true | No |
How the decision is made
Visibility is checked first. If an item is hidden (guest gate or region restriction), eligibility stops immediately with a clear reason code. For visible items, each merchant rule is evaluated in turn, accumulating reason codes. The final status is BLOCKED if any unresolvable block exists, CONDITIONAL if a buyer could qualify with action, or ELIGIBLE if nothing blocks.
Real merchant scenarios
B&T Wholesale — gated, qualification-first
Guest buyer
Agent never surfaces it.
Wholesale buyer, no resale cert
"I can show this, but you'll need a resale certificate on file. Want to upload one?"
Wholesale buyer, resale cert on file
Agent proceeds.
Fresh Corner Market — region & fulfillment sensitive
Buyer in HI
Item not available in this market. Agent explains — doesn't silently drop.
Buyer requesting shipping
Agent doesn't promise shipping it can't deliver.
Sara's Boutique — open DTC, discovery-led
Any buyer
Clean payload, no gates — an agent recommends freely. This archetype's gap is discoverability, addressed by a future spec.
Open questions
These are genuine forks. Tell me I'm wrong.
#1`blocking` vs. status coherenceRESOLVED 2026-06-10
The reference implementation emitted `TIER_RESTRICTION` with `blocking: true` while resolving status to `CONDITIONAL`. Incoherent: if a reason is resolvable (upgrade tier), is it really "blocking"?
RESOLVED: `blocking` is now a derived boolean (`severity !== 'INFO'`), not an authored field. Status is derived from severity + requirements[]: BLOCK + requirements[] → CONDITIONAL; BLOCK + no requirements[] → BLOCKED. The `blocking` field is deprecated (supersededBy: severity, RAOS-0000 §7.4).
#2Is `CONDITIONAL` worth keeping as a distinct status?RESOLVED 2026-06-10
Or should agents just read `BLOCKED` + the presence of `requirements[]`? Three states is more expressive; two is simpler to implement.
RESOLVED: Three states are kept (ELIGIBLE | CONDITIONAL | BLOCKED). CONDITIONAL signals an actionable resolution path the agent can surface; BLOCKED means stop with no path. Collapsing to two states would push the distinction into the agent's requirements[] inspection — three states is more expressive and the derivation is deterministic.
#3`REGION_RESTRICTED` placement
Region restriction surfaces as a visibility `HIDDEN` result (the item disappears) and as the eligibility reason code `REGION_RESTRICTED` (so agents can explain it). Is a region-restricted item correctly `HIDDEN`, or should it be `VISIBLE` with `BLOCKED` eligibility?
Hidden means the agent never surfaces it; blocked means the agent sees it but can't transact. Which is more useful for agent behavior? Open for comment.
#4Unknown-context defaulting for transaction-gating stagesRESOLVED 2026-06-10
Spec says "default to most restrictive." Is that right for discovery (you'd under-surface), or should visibility default open and eligibility default strict?
RESOLVED for transaction-gating stages (Eligibility, Price, Quote): default to most-restrictive per RAOS-0000 §7.2. Asserted privilege claims are downgraded. The discovery-side default (visibility) remains open — comment welcome.
#5Tier hierarchy
Currently an ordered list (`none < gold < reseller_plus < distributor`). Should tiers be a partial order / capability set instead of a strict ladder?
Have a view on any of these?
This is being built in the open precisely so the answers come from people who run real catalogs. Email me or reply on the build-log post.
rikbanerjee007@gmail.comWhy start here
Of all the merchant-reasoning gaps, eligibility-with-reasons is the most reusable — it applies to wholesale gating, age restriction, region rules, membership, regulated goods, and more. Prove it cleanly here, on real archetypes, and it becomes a candidate to propose upstream into UCP itself.
The mission: a small retailer can't build this. But if the spec exists and is open, the platform they already use can implement it once — and every merchant on that platform inherits agent-readiness for free. The spec is the leverage.