Market Intel — Research Skill
Turn a vague "study this market" into a ranked, evidence-backed, actionable
brief — and challenge it against your own last snapshot.
Ground rules (non-negotiable)
- Public data only. Everything comes from legally scraped public
sources (OSM, public directories, search). No login, no CAPTCHA bypass,
no ToS violations. If a source requires credentials, stop and say so —
don't improvise scraping.
- Evidence over vibes. Every claim in a report carries a source (which
crawl, which report, which page). No source = mark it as estimate.
- Revenue/scale are PROXIES. Private micro-business revenue is not
public. Use review counts × category benchmarks → band + confidence.
Never fake precision. Say "estimated RM X–Y", not "RM X".
- Free-first stack. Prefer $0 tools (OSM, browser automation) over paid
scrapers. Only propose paid tools when the free path is genuinely blocked.
- Respect the environment: the engine is Python; write temp scripts to
a scratch dir rather than inline shell one-liners.
The pipeline (research → plan → spar)
Stage 1 — Crawl (who exists)
osm_crawl --area <area> [--category <vertical>] # baseline POI density
gmaps_enrich --query "<vertical> <area>" --limit N # phone/rating/reviews/website
- Free, keyless baselining first; enrichment second.
- Enrichment is fragile (layout changes): early-exit on 2 no-new-result
cycles; incremental saves so timeouts don't lose data.
Stage 2 — Report (what the data says)
niche_report --area <area> # per-niche opportunity scores 0-100
pitch_list --area <area> # reachable businesses with NO website, ranked
- The grey line is the wedge: businesses that are active (reviews) but
digitally invisible (no website). That gap = the sales opportunity.
Stage 3 — Suggest (the plan)
suggest --area <area> --tier flash|pro|ultra
- LLM stage ONLY where judgment is needed. Reads the niche report + pitch
list → produces: niche ranking with willingness-to-pay, TOP N targets,
pitch angles, wedges, risks, next steps.
- Terse, decisive output: "decisions and reasons", not hedging.
Stage 4 — Spar (challenge your own plan)
spar <vertical> --against <snapshot>
- Re-run against the last locked pipeline snapshot. Output: what changed,
what's now uncontested, what's saturated, and a verdict (action/reject/
defer).
Stage 5 — Persist + query
pgvector_load --area <area> # push to vector store for semantic queries
- Idempotent (dedupe by name+coords). Keeps its own table — never mixes
into other tenants' corpora.
Output discipline
- Brief:
STUDY_<vertical>_<area>_brief.md — problem, data, ranking,
targets, wedge, next action.
- Spar:
STUDY_<vertical>_spar.md — diff against snapshot + verdict.
- Both: recommendations are ranked by a score (0-100) that is traceable to
the scoring function, and every target row has the raw evidence fields.
Known pitfalls (learned the hard way)
- Rating is not always in visible text — some locales put it in an
aria-label attribute (
5.0 / 5); parse both.
- Too-specific queries return 0 — a query phrased like
" " can return nothing while "" works.
Keep queries broad, filter locally.
- Lazy-loaded results — need explicit scroll of the results feed; pass
element handles, not locators.
- Timeout safety — a full multi-vertical sweep exceeds most shell
timeouts; run per-vertical and merge incrementally.
- Analysts bias: family-diverse models disagree on purpose — when the
plan is built by a panel, record who said what, don't average to mush.
What to do when something's off
- Crawl empty → broaden query / check source reachability (the free source
wants a User-Agent header).
- Report feels wrong → re-check scoring inputs, don't adjust the output.
- Panel disagreement → surface the disagreement as a decision, then decide
with the evidence table — the report must say which evidence won.
Skill pattern: evidence → rank → plan → spar. The value is the discipline,
not the scraping.
1---2name: market-intel-research3description: Industry RESEARCH + market intelligence. Use when the user says "research <vertical>", "study the market", "industry brief", "spar <vertical>", "what changed in the pipeline", "fresh seams", or wants a market brief and a spar report against the last locked pipeline snapshot. Runs the market-research engine to produce actionable niche intelligence from public data.4---56# Market Intel — Research Skill78Turn a vague "study this market" into a ranked, evidence-backed, actionable9brief — and challenge it against your own last snapshot.1011## Ground rules (non-negotiable)12131. **Public data only.** Everything comes from legally scraped public14 sources (OSM, public directories, search). No login, no CAPTCHA bypass,15 no ToS violations. If a source requires credentials, stop and say so —16 don't improvise scraping.172. **Evidence over vibes.** Every claim in a report carries a source (which18 crawl, which report, which page). No source = mark it as estimate.193. **Revenue/scale are PROXIES.** Private micro-business revenue is not20 public. Use review counts × category benchmarks → band + confidence.21 Never fake precision. Say "estimated RM X–Y", not "RM X".224. **Free-first stack.** Prefer $0 tools (OSM, browser automation) over paid23 scrapers. Only propose paid tools when the free path is genuinely blocked.245. **Respect the environment:** the engine is Python; write temp scripts to25 a scratch dir rather than inline shell one-liners.2627## The pipeline (research → plan → spar)2829### Stage 1 — Crawl (who exists)30```31osm_crawl --area <area> [--category <vertical>] # baseline POI density32gmaps_enrich --query "<vertical> <area>" --limit N # phone/rating/reviews/website33```34- Free, keyless baselining first; enrichment second.35- Enrichment is fragile (layout changes): early-exit on 2 no-new-result36 cycles; incremental saves so timeouts don't lose data.3738### Stage 2 — Report (what the data says)39```40niche_report --area <area> # per-niche opportunity scores 0-10041pitch_list --area <area> # reachable businesses with NO website, ranked42```43- The **grey line** is the wedge: businesses that are active (reviews) but44 digitally invisible (no website). That gap = the sales opportunity.4546### Stage 3 — Suggest (the plan)47```48suggest --area <area> --tier flash|pro|ultra49```50- LLM stage ONLY where judgment is needed. Reads the niche report + pitch51 list → produces: niche ranking with willingness-to-pay, TOP N targets,52 pitch angles, wedges, risks, next steps.53- Terse, decisive output: "decisions and reasons", not hedging.5455### Stage 4 — Spar (challenge your own plan)56```57spar <vertical> --against <snapshot>58```59- Re-run against the last locked pipeline snapshot. Output: what changed,60 what's now uncontested, what's saturated, and a verdict (action/reject/61 defer).6263### Stage 5 — Persist + query64```65pgvector_load --area <area> # push to vector store for semantic queries66```67- Idempotent (dedupe by name+coords). Keeps its own table — never mixes68 into other tenants' corpora.6970## Output discipline7172- **Brief:** `STUDY_<vertical>_<area>_brief.md` — problem, data, ranking,73 targets, wedge, next action.74- **Spar:** `STUDY_<vertical>_spar.md` — diff against snapshot + verdict.75- Both: recommendations are ranked by a score (0-100) that is traceable to76 the scoring function, and every target row has the raw evidence fields.7778## Known pitfalls (learned the hard way)7980- **Rating is not always in visible text** — some locales put it in an81 aria-label attribute (`5.0 / 5`); parse both.82- **Too-specific queries return 0** — a query phrased like83 "<vertical> <subarea>" can return nothing while "<vertical>" works.84 Keep queries broad, filter locally.85- **Lazy-loaded results** — need explicit scroll of the results feed; pass86 element handles, not locators.87- **Timeout safety** — a full multi-vertical sweep exceeds most shell88 timeouts; run per-vertical and merge incrementally.89- **Analysts bias**: family-diverse models disagree on purpose — when the90 plan is built by a panel, record who said what, don't average to mush.9192## What to do when something's off9394- Crawl empty → broaden query / check source reachability (the free source95 wants a User-Agent header).96- Report feels wrong → re-check scoring inputs, don't adjust the output.97- Panel disagreement → surface the disagreement as a decision, then decide98 with the evidence table — the report must say *which* evidence won.99100---101*Skill pattern: evidence → rank → plan → spar. The value is the discipline,102not the scraping.*