won-deal-icp-finder
Applies when the ICP on the slide was written before the revenue arrived. Produces a proven profile, derived from deals that closed, plus the search criteria to find more of them.
Most stated ICPs are aspirational
Teams write their ICP at the start, from the market they want. Then they close deals, and the deals quietly disagree — smaller, in an adjacent vertical, in a country nobody targeted. Nobody rewrites the slide, so prospecting keeps aiming at the market that never paid. This skill re-derives the profile from the ledger instead of the plan.
Select on money, not on stage names
The first move is picking which deals count, and it is where this play usually breaks.
The obvious approach — filter on a "Closed Won" stage — assumes a stage that a surprising number of pipelines don't have, or don't use consistently, or spell in another language. When it silently matches nothing, the fallback is worse: pull the most recent deals instead, which are the newest and emptiest ones, and the analysis runs on rows with no value in them.
Select on deal value being populated, over the last twelve months. A won signal, where one genuinely exists, is a filter you add on top — not the thing you rely on. Read the CRM's own conventions before pulling anything: which field actually holds value (the standard amount field is often abandoned in favour of a custom ARR or ACV one), and whether a won status exists at all. If you can't tell, ask one specific question and stop. Guessing here doesn't produce a slightly-off answer, it produces a confident answer about empty rows. See references/deal-data-extraction.md for the field-discovery sequence, the CSV fallback, and how to keep the pull bounded.
Do the arithmetic in code
Sums, revenue shares, concentration ratios, and frequency rankings across a hundred-odd deals are exactly the work a language model gets quietly and unfixably wrong — and a wrong ranking sends a team after the wrong accounts for a quarter.
scripts/analyze.py does the counting. It parses both European and US amount formats, applies the window, excludes lost deals always, detects a won signal when present, aggregates revenue per company, and returns segments and source rankings as JSON. Run it, then reason over what it returns. It refuses rather than improvises when it can't find a value field, a company, or any deal in the window — a refusal is a question for the user, not a problem to code around. references/analysis-engine.md covers the flags, the output schema, and how to read each block.