Market Matching
How Polymarket contracts get connected to individual companies
That was the first version, and it produced bad results. A search for "NVIDIA" finds markets that happen to mention NVIDIA in passing — like "Will Microsoft or NVIDIA be the largest company?" — while missing the most relevant ones that describe NVIDIA's actual risks without naming the company at all, such as a market about GPU export controls to China.
The reverse problem was worse: every AI-sector company got the same handful of high-volume markets about OpenAI or ChatGPT because those were the most-active markets with "AI" in the title. NVDA, MSFT, CRM, and ADBE all showed the same three cards.
The fix is to separate what a market is about (its taxonomy category) from what a company's risks are (its risk profile), and let those two independent descriptions match through a shared vocabulary — not through raw text overlap.
The 33-Category Taxonomy
How every Polymarket market is classified before it touches any company
Company Risk Profiles
Why each company has a unique decomposition instead of sector keywords
Scoring & Deduplication
How the best market is selected when multiple qualify
Coverage & Limitations
What the system can and cannot do, and why
Every decision described here is reflected directly in the codebase. The two core files are:
lib/market-taxonomy.ts33 categories, classifier patterns, anti-patternslib/company-risk-profiles.ts60+ company overrides, 11 sector defaultsapp/api/dossier/[ticker]/route.tsFetch → classify → score → deduplicate