Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Market sizing and market structure work — TAM/SAM/SOM built top-down and bottom-up then reconciled, segmentation, demand triangulation, and survey design. Use when sizing a market, writing a sizing memo, or fielding a survey.
.claude/skills/borghei-market-research/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 141% | 0% |
Applied market research for people who have to defend a number in a room. This skill is about the operational craft: constructing a market size two independent ways, reconciling the gap, cutting the market into segments that behave differently, and fielding survey instruments that do not manufacture the answer you hoped for.
the number will be challenged line by line
bottom-up build says $700M, and you need to explain the gap
data, competitor headcount) into one directional read
category awareness, switching intent — without leading the respondent
Before generating, confirm these inputs. If any is unknown or vague, ASK — do not assume:
Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the artifact.
each cut it (geography, segment, buyer qualification), each with a retention fraction and a stated justification.
qualified share, annual value per unit, reachable share, expected win rate.
flags implausible ratios and divergence.
fail before the number leaves your machine. A warn needs asentence in the memo, not a fix.
bashpython3 research-ops/market-research/scripts/tam_sam_som_builder.py \ --input research-ops/market-research/assets/sample_market_model.json \ --format text
lead velocity, win rate by segment, analyst growth rates, competitor hiring, category conference attendance.
the list of signals that contradict each other.
is usually a segmentation boundary you have not drawn yet.
bashpython3 research-ops/market-research/scripts/demand_signal_triangulator.py \ --input research-ops/market-research/assets/sample_demand_signals.json \ --format text
phrasing, absolutes, unbalanced or over-long scales, and missing escape options.
target margin of error, and confidence level.
fail, then re-run. Field only on a clean run.bashpython3 research-ops/market-research/scripts/survey_instrument_auditor.py \ --input research-ops/market-research/assets/sample_survey.json \ --format text
| Situation | Method | Why | |-----------|--------|-----| | Established category, published reports exist | PROVEN] Top-down anchored, bottom-up as a check | The anchor is defensible; bottom-up catches definition drift | | New category, no analyst coverage | PROVEN] Bottom-up only, stated as such | A top-down number for a category that does not exist yet is fiction | | Adjacent expansion from an existing product | RECOMMENDED] Bottom-up from your own funnel conversion | Your observed win rates beat any external estimate | | Regulated market with registries | PROVEN] Bottom-up from the registry count | Counting licensed entities is the strongest unit base available | | Consumer market, behaviour-driven | RECOMMENDED] Top-down plus survey-derived incidence | Unit counts exist but qualification requires stated behaviour |
These are the ratios the builder enforces. They are heuristics, not laws — but crossing one without an explanation in the memo is how sizing loses credibility.
| Ratio | Healthy range | Flag when | |-------|---------------|-----------| | SAM / TAM | 5% – 40% | Above 60% — you are claiming almost the whole market is addressable | | SOM / SAM (3-year) | 1% – 10% | Above 20% — implies category leadership inside the horizon | | SOM / TAM | 0.1% – 5% | Above 5% for a pre-scale company | | Bottom-up vs top-down TAM | Within 3x | Above 3x warn, above 10x fail — the two builds are answering different questions |
Required n for a proportion estimate, finite population corrected. Use these as a sanity check on the auditor's output.
| Population | ±10% MoE | ±5% MoE | ±3% MoE | |-----------|----------|---------|---------| | 500 | 81 | 218 | 341 | | 5,000 | 95 | 357 | 880 | | 100,000 | 96 | 383 | 1,056 | | 1,000,000+ | 97 | 385 | 1,066 |
The jump from ±10% to ±5% quadruples cost for a band most market decisions do not need. RECOMMENDED] Field at ±10% for directional category questions and reserve ±5% for pricing and packaging decisions where the band drives the choice.
Mistake: Copying a market size from an analyst report or a competitor's deck into your own memo, adjusting the geography, and presenting it as your build. Why it happens: The number is already large and already sourced, and building bottom-up takes two days you do not think you have. Instead: Use the published figure as the top-down anchor only, and always build the bottom-up chain alongside it. The reconciliation gap is the most informative artifact of the whole exercise — it tells you exactly which definition the report used and yours does not.
Mistake: SOM computed as "if we capture 1% of the TAM" with no mechanism behind the 1%. Why it happens: It sounds modest, so nobody challenges it, and it produces a convenient number without requiring a channel model. Instead: Build SOM from reachable units times expected win rate, where both come from something observed — your funnel, a pilot, or a comparable. If you cannot name the channel that reaches those units, you do not have a SOM.
Mistake: A four-year-old market report used at face value in a current memo. Why it happens: It was the best available source when someone first built the model, and nobody re-checks a number that has been in the deck for a year. Instead: Record the vintage of every anchor. If it is more than 18 months old, apply an explicit growth bridge with a stated CAGR and show both the raw and bridged figures. An unbridged stale anchor invites the reviewer to discount everything downstream of it.
Mistake: Asking "How valuable would an automated reporting feature be to your team?" and reporting the enthusiasm as demand evidence. Why it happens: The team already believes in the feature, and the question is written by the person who wants it built. Instead: Ask about the current behaviour and its cost — "How many hours last month did your team spend building reports manually?" — and let the demand fall out of the numbers. Run every instrument through the auditor before fielding; leading items are cheap to fix pre-field and impossible to fix post-field.
Mistake: Cutting the market by company size or geography because that data is available, then finding every segment has the same conversion and the same ACV. Why it happens: Firmographic fields are in the CRM; behavioural ones are not. Instead: Segment on the variable that changes the buying decision — trigger event, existing tooling, regulatory obligation, or team structure. A segmentation is only useful if the segments have measurably different win rates or values.
| File | Purpose | |------|---------| | scripts/tam_sam_som_builder.py | Builds top-down and bottom-up TAM/SAM/SOM, reconciles them, flags implausible ratios | | scripts/survey_instrument_auditor.py | Checks survey items for leading language, scale problems, and computes required sample size | | scripts/demand_signal_triangulator.py | Weights and triangulates demand signals; surfaces contradictions and source concentration | | references/market-sizing-methods.md | Method selection, filter design, growth bridges, worked reconciliation examples | | references/survey-design-methodology.md | Question construction, scale design, sampling frames, mode effects, field QA | | assets/market-sizing-memo-template.md | The memo structure a sizing number ships in | | assets/sample_market_model.json | Runnable input for the TAM/SAM/SOM builder | | assets/sample_survey.json | Runnable input for the survey auditor | | assets/sample_demand_signals.json | Runnable input for the demand triangulator |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 30,871 | 33,176 | +7% | 1 | 1 | 0% | 6,285 | 8,907 | +42% | 0 | 0 | — |
case-02 | pass→pass | 14,835 | 19,127 | +29% | 1 | 1 | 0% | 2,796 | 5,864 | +110% | 0 | 0 | — |
case-03 | fail→fail | 19,122 | 26,243 | +37% | 1 | 1 | 0% | 2,994 | 6,932 | +132% | 0 | 0 | — |
case-04 | fail→fail | 26,012 | 24,664 | -5% | 1 | 1 | 0% | 4,965 | 7,229 | +46% | 0 | 0 | — |
case-05 | fail→fail | 12,809 | 7,929 | -38% | 1 | 1 | 0% | 1,988 | 3,961 | +99% | 0 | 0 | — |
case-06 | fail→fail | 11,500 | 17,734 | +54% | 1 | 1 | 0% | 1,787 | 5,071 | +184% | 0 | 0 | — |
case-07 | fail→pass | 18,553 | 18,027 | -3% | 1 | 1 | 0% | 2,850 | 5,496 | +93% | 0 | 0 | — |
case-08 | pass→pass | 17,410 | 15,494 | -11% | 1 | 1 | 0% | 2,677 | 4,932 | +84% | 0 | 0 | — |
case-09 | pass→pass | 20,555 | 12,333 | -40% | 1 | 1 | 0% | 3,198 | 4,572 | +43% | 0 | 0 | — |
case-10 | pass→pass | 14,463 | 12,566 | -13% | 1 | 1 | 0% | 2,333 | 4,761 | +104% | 0 | 0 | — |
case-11 | fail→pass | 14,825 | 9,087 | -39% | 1 | 1 | 0% | 2,389 | 4,009 | +68% | 0 | 0 | — |
case-12 | fail→pass | 14,698 | 10,830 | -26% | 1 | 1 | 0% | 2,282 | 4,289 | +88% | 0 | 0 | — |
case-13 | fail→pass | 16,204 | 19,681 | +21% | 1 | 1 | 0% | 2,443 | 5,895 | +141% | 0 | 0 | — |
case-14 | fail→pass | 13,316 | 14,976 | +12% | 1 | 1 | 0% | 2,173 | 4,799 | +121% | 0 | 0 | — |
case-15 | pass→pass | 12,245 | 10,789 | -12% | 1 | 1 | 0% | 1,925 | 4,133 | +115% | 0 | 0 | — |
case-16 | fail→fail | 14,034 | 13,664 | -3% | 1 | 1 | 0% | 2,184 | 4,679 | +114% | 0 | 0 | — |
case-17 | fail→pass | 15,241 | 14,949 | -2% | 1 | 1 | 0% | 2,669 | 5,169 | +94% | 0 | 0 | — |
case-18 | pass→pass | 15,454 | 23,895 | +55% | 1 | 1 | 0% | 2,651 | 6,781 | +156% | 0 | 0 | — |
case-19 | fail→pass | 10,280 | 8,206 | -20% | 1 | 1 | 0% | 1,797 | 3,877 | +116% | 0 | 0 | — |
case-20 | fail→pass | 14,766 | 13,226 | -10% | 1 | 1 | 0% | 2,132 | 4,451 | +109% | 0 | 0 | — |
case-21 | pass→pass | 9,497 | 6,024 | -37% | 1 | 1 | 0% | 1,416 | 3,535 | +150% | 0 | 0 | — |
case-22 | pass→pass | 14,594 | 7,843 | -46% | 1 | 1 | 0% | 2,426 | 3,831 | +58% | 0 | 0 | — |
case-23 | fail→pass | 15,263 | 11,186 | -27% | 1 | 1 | 0% | 2,667 | 4,457 | +67% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +43 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.