# Method

Built by `research/drafts/yc-dot-com-to-dot-ai.build.py`. Rerun it to reproduce
every number. Built 2026-09-15.

## Funnel

| step | rows |
|---|---|
| fetched from the directory | 6190 |
| with a parseable batch | 6189 |
| dropped, no batch ("Unspecified") | 1 |
| dropped, batch still filling (Fall 2026, Winter 2027) | 20 |
| in scope, Summer 2005 - Summer 2026 | 6169 |
| of those, 2005-2010 (outside the series, counts only) | 207 |
| with a website domain | 6127 |
| without a domain, dropped from TLD shares | 42 |
| with a one-liner | 6008 |
| without a one-liner, dropped from language shares | 161 |
| with a long description | 5758 |
| with a one-liner or a long description (analogy denominator) | 6114 |

Batch order is Winter, Spring, Summer, Fall within a year. Shares are
suppressed for batches under 30 companies; counts under 5 print `<5`.

## Known limitation

The directory text is the company's **current** description, filed under the
batch it was founded in. A 2020-batch company that rewrote its pitch in 2025
contributes 2025 wording to the 2020 row. This is why a phrase like
"Cursor for ..." appears against a Summer 2020 batch. The same applies to
domains: a company that moved from .com to .ai counts as .ai in its founding
batch, which if anything understates how recent the .ai shift is.

## 1. Top-level domain

TLD is the **public suffix** of the `domain` field, via `tldextract` running
off its bundled suffix snapshot (`suffix_list_urls=()`, no network call), so
`foo.co.uk` counts as `co.uk` and `bar.com.au` as `com.au`; both land in
`other`. Buckets: `com`, `ai`, `io`, `co`, `other`. Denominator: companies in
that batch with a non-empty domain.

## 2. Analogy phrases

Regex `\b(<Brand>) for\b`, case-insensitive, over the one-liner and the long
description joined. Brands searched: Uber, Airbnb, Stripe, Shopify, Plaid,
Rippling, Cursor, Lovable, Salesforce, Slack, Github, Figma, Notion, Amazon,
Netflix, Tinder, Duolingo, Carta, Brex, Ramp, Gusto, Deel, Twilio, Zapier,
Palantir, Tesla, Waymo, OpenAI, ChatGPT, Copilot, Datadog, Snowflake,
Databricks, Vercel, Replit, Zillow, Robinhood, Coinbase, Peloton, Toast,
Square.

The headline metric is **distinct companies**, not matches: a company that
writes "Shopify for pharmacies" in both its one-liner and its long description
is one user of the phrase.

Every match was read by hand. 30 were thrown out and are listed in
`analogy_hits_removed.csv` with a reason. Two kinds:
- the brand appears as itself, not as an analogy: employment history
  ("scaled infrastructure at Uber for millions of users"), a customer list, a
  product name ("Fulfillment by Amazon for African merchants"), a verb object
  ("asks ChatGPT for a plumber"), or a common noun ("Crypto On and Off
  Ramp for Latam").
- every "Copilot for" match. In this corpus "copilot" is a product-category
  noun ("an AI copilot for radiologists"), not a GitHub Copilot analogy;
  matches start in 2019, two years before GitHub Copilot shipped. The word is
  counted instead as a word family in `families_by_batch.csv`.

## 3. Word families

One-liner only. Denominator: companies in the batch with a one-liner.

| family | regex |
|---|---|
| agent (software sense) | `\bagent(s\|ic)?\b` after the human-agent senses are cut, see below |
| AI agent | `\bA\.?I\.?[\s-]agents?\b` |
| agentic | `\bagentic\b` |
| AI-native | `\bAI[\s-]native\b` |
| copilot | `\bco[\s-]?pilots?\b` |
| open source | `\bopen[\s-]?sources?d?\b` |
| marketplace | `\bmarket[\s-]?places?\b` |
| on-demand | `\bon[\s-]demand\b` |
| crypto/web3/blockchain/NFT/DeFi | `\b(crypto\w*\|web\s?3(\.0)?\|block[\s-]?chain\|NFTs?\|DeFi\|ethereum\|bitcoin\|smart[\s-]contracts?)\b` |
| SaaS | `\bSaaS\b` |
| no-code | `\bno[\s-]?code\b\|\blow[\s-]?code\b` |

**The agent exclusion.** "Agent" also means a person. Spans matching

    \b(insurance|insurer|underwrit\w*|real[\s-]?estate|realty|realtor|
    mortgage|travel|booking|ticketing|freight|customs|forwarder|support|
    customer[\s-]?(?:service|support|success)|service|helpdesk|help[\s-]?desk|
    call[\s-]?cent(?:er|re)|contact[\s-]?cent(?:er|re)|sales|leasing|listing|
    literary|talent|recruit\w*|escrow|human|live|field|loan|title|claims?|
    licensed|independent)(?:\s+\w+){0,2}\s+agents?\b

and the reverse order

    \bagents?\b\s+(?:\w+\s+){0,2}(?:in|for|at)\s+(?:the\s+)?
    (insurance|real[\s-]?estate|realty|travel|mortgage|
    call[\s-]?cent(?:er|re)|customer\s+(?:service|support))\b

are cut before the family test. A span is **kept** anyway if a software
modifier -- `AI`, `A.I.`, `LLM`, `GPT`, `artificial intelligence`,
`machine learning`, `autonomous`, `automated`, `automation`, `agentic`,
`software`, `digital`, `virtual`, `voice`, `chat`, `bot`, `robot*`,
`synthetic`, `generative` -- appears inside the span, in the 40 characters
before it, or in the company's own name. "AI support agent for ecommerce" is
software; "App for independent agents to sell financial products" is people.
Across the whole in-scope set this rule removes 2 one-liners, both
listed in `agent_exclusions.csv`. With the software-modifier guard turned off it
would remove 19, listed in `naive_exclusions.csv`, so the difference
can be read company by company.

## 4. AI mentions

One-liner only, regex `\bAI\b|\bA\.I\.\b|artificial intelligence|machine
learning`, case-insensitive. The company's own name is removed from the string
first, so a company called "Foo AI" is not counted unless its pitch says AI
somewhere else. `ai_n_before_name_exclusion` in `ai_by_batch.csv` shows what
the count would be without that step; the gap is never more than a couple of
companies in any batch.

## 5. Sanity check

YC's Summer 2025 batch: this dataset holds 166 companies. Extruct AI's
published S25 analysis (https://www.extruct.ai/research/ycs25/, published
25 September 2025) says "Deep dive into the Y Combinator Summer 2025 batch
featuring 160 startups and 231 founders" -- a 6-company gap, or 3.6%, in the
direction you would expect from a directory that keeps adding late entries
after a batch's demo day.

Licensed CC BY 4.0
