The operational model for 2A product search
The shared map of products, dealers, shoppers, and demand that Betsy and humans both use — so search, alerts, and Brand Intelligence stay grounded in the same reality.
SYS.01
Objects
The nouns of 2A commerce — products, dealers, journeys, alerts.
SYS.02
Links
How inventory, identity, and intent relate — not orphaned tables.
SYS.03
Actions
What Betsy, shoppers, and Brand Intelligence can do — search, watch, export demand.
Object graph
A simple map of how the system fits together. Hover a circle to see its neighbors. Click for a plain-language explanation — Product is in the center because everything else hangs off live inventory.
Hover a circle to see what connects to it. Click for a short explanation.
These are the building blocks of GunSearch — inventory, visits, and demand — shared by Betsy, dealers, and Brand Intelligence.
Object inventory
Each object is a real operational entity — backed by schema and APIs, not a slide-deck noun.
Product
Live listing / SKU from a dealer feed
products
Brand
Manufacturer / house brand
brands
Seller
FFL / retailer with feed + optional embed
sellers
Session
Chat / embed shopping journey (legacy table: leads)
leads
Shopper
Verified identity for alerts (magic link) — never in Brand Intelligence API
shoppers
Watch
Saved search / restock alert
shopper_watches
SearchIntent
Rolling multi-turn demand signal on a session
search_intent_summary + events
ModelTerm
Catalog-mined firearm platform / SKU family in titles
catalog_model_terms
EnterpriseClient
OEM / Platform Brand Intelligence tenant (not GSA dealers)
enterprise_clients + users + api_keys
DemandSignal
Anonymized aggregate — full/OEM for Brand Intelligence API; store-scoped or market teaser for GSA; public Insights teaser
derived from sessions + demand_daily_rollups (no PII)
Links
Relationships the platform enforces — embed catalog scope, identity, demand rollups.
| From | Link | To |
|---|---|---|
| Product | manufactured_by | Brand |
| Product | listed_by | Seller |
| Session | scoped_to | Seller |
| Session | identified_as | Shopper |
| Session | accumulates | SearchIntent |
| Shopper | subscribes | Watch |
| Watch | matches | Product |
| Session | clicked | Product |
| SearchIntent | aggregates_to | DemandSignal |
| ModelTerm | matches_title | Product |
| Session | rolls_up_to | DemandSignal |
| DemandSignal | consumed_by | EnterpriseClient |
Actions
Kinetic layer: governed operations that change or query the model. Shoppers feel CTAs; agents call tools; cron keeps the twin fresh.
search_productsRetrieve live Product cards from catalog SQL
Betsy (agent loop) · agent-tools → searchProducts
get_productLoad one Product by id (seller-scoped in embed)
Betsy · agent-tools
compare_productsSide-by-side cards from last product ids / ids
Betsy · agent-tools + compare-intent
capture_lead / email_resultsBind email continuity; re-run search up to 200
Shopper + Betsy CTA · /api/email-results, embed mirror
create_alert / watchUpsert Watch on normalized SearchParams
Shopper · /api/watch, shopper_watches
record_host_intentFirst-touch referrer, path trail, funnel, soft seed
Embed page-intent beacon · /api/embed/page-intent
ingest_feedUpsert Products; soft-delete missing; refresh brands
Cron / admin Sync · feed-ingest + cron
fire_watch_alertsEmail on restock / price change fingerprint
Cron · /api/cron/watch-alerts
enterprise_api_v1Demand intel, sanitized sessions, export, unmet, UPC, rising, referrers — OEM-scoped
Brand Intelligence client (portal or ek_live_) · /api/enterprise/v1/{intel,sessions,export,unmet,upc,rising,referrers,health,me,settings}
mint_api_keyCreate ek_live_ key (secret shown once)
Portal client_admin or GSE admin · /api/enterprise/v1/keys
send_weekly_insightsWeekly Brand Intelligence email summary
Cron (opt-in per EnterpriseClient) · enterprise-weekly-insights + cron
gsa_store_intelSeller-scoped DemandVisualization aggregates (no session export)
GunSearchAgent (ONBOARDING_SECRET) · /api/onboarding/sellers/:id/intel
gsa_market_teaserLimited anonymized platform teaser — no export/API keys
GSA Pro (ONBOARDING_SECRET + market_teaser_enabled) · /api/onboarding/sellers/:id/market-teaser
Lexicon layer
Semantic enrichment maps shooter language onto objects — the narrow “ammo ontology” is one file inside a larger identity stack.
LEX.01
Ammo load ontology
Slang → structured load/casing (subs, green tip, Critical Defense…)
src/lib/ammo-ontology.ts
LEX.02
Caliber aliases
300 BLK ↔ .300 AAC Blackout; longest-match parse
src/lib/caliber-aliases.ts
LEX.03
Brand normalize + roles
name_key, aliases, gun_primary / ammo_primary / dual
src/lib/brand-normalize.ts + brand-roles-catalog
LEX.04
Catalog model terms
Mine firearm platforms from titles (no products.model column)
src/lib/model-extract-catalog.ts
LEX.05
Intent taxonomy
load_type, use_case, quantity_intent, budget tags
src/lib/intent-taxonomy.ts
LEX.06
Policy matrix
When Betsy may search vs clarify (agent readiness)
docs/betsy-policy-matrix.md + conversation-policy
Harness
Three layers keep the model trustworthy: eval quality gates, the agent runtime that only mutates the world through tools, and the Enterprise API that partners call with keys.
Eval harness
livenpm run test:ci / test:eval-extract
- ▹Shared applySearchTurnMerge with runtime
- ▹scripts/eval-betsy.ts (extract + optional retrieval)
- ▹eval/golden/betsy-queries*.json + baselines
- ▹CI: search-policy + extract --strict
- ▹npm run smoke:prod (post-deploy)
Agent runtime
liverunSearchTurn + applySearchTurnMerge + agent-tools
- ▹Extract → shared merge/policy → tools → ProductCards
- ▹Rate limits + session minting + embed scope
- ▹Not a multi-agent orchestration platform (by design)
Enterprise API v1
liveBearer ek_live_… → /api/enterprise/v1/*
- ▹Public API docs: /docs/enterprise-api
- ▹intel · sessions · export · unmet · upc · rising · referrers
- ▹health · me · settings · keys
- ▹OEM fail-closed scope · multi-day rollups
Why it matters
Why an ontology for 2A AI
- Grounded inventory — Betsy answers from Product objects, not hallucinated stock.
- Shared demand signal — Session + SearchIntent feed Insights, dealers, and Brand Intelligence without dumping PII.
- Governed actions — Email, watches, and ingest are explicit tools — the agent does not invent side effects.
- Shooter language — the lexicon layer turns slang into structure so the model stays searchable.
FAQ
- What is the GunSearch Ontology?
- It is the shared operational model for 2A product search: objects (Product, Brand, Seller, Session, Watch…), links between them, and actions Betsy and humans can take (search, email, watch, ingest, export demand). Agents and apps use the same nouns so inventory and demand stay one system of record.
- Is this page automated from the API or database?
- No. The inventory is curated in src/lib/ontology-v0.ts and rendered here. When we ship product changes (for example Enterprise API v1), we update that registry. OpenAPI docs will describe HTTP contracts separately — they are not the same as this narrative map.
- Is this the same as Palantir’s Ontology?
- Same idea, different scope. Palantir’s Ontology is a full enterprise digital twin with object security and AIP tooling. Ours is the decision model for firearms and ammo commerce — catalog, shopper journeys, demand signals, and agent actions — implemented in production code today.
- How does Brand Intelligence fit in?
- DemandSignal is the anonymized aggregate object. EnterpriseClient tenants read it through the portal and the Enterprise API (ek_live_ keys): intel, sessions, export, unmet, UPC intensity, and more — OEM-scoped or full platform. Shopper emails never leave the shopper side of the model.
- How do you keep the agent honest?
- Product cards are never LLM-authored — only catalog tools return inventory. A policy matrix gates when search may run, and an eval harness regresses extract, policy, and retrieval quality.
Curated inventory (not auto-generated from OpenAPI or the DB): src/lib/ontology-v0.ts · docs/ontology-v0.md · HTTP contracts: docs/enterprise-api.md