understand · icp and the trigger window
Fit lines and tests
Fits-if and not-if lines, list, count and vouch tests.
In ICP and the trigger window
wiki · stage 3 · icp and trigger detection · component 1 of 2
An ICP is a filter: a short list of fits-if and not-if lines, each one checkable on a stranger from outside, each one traced to the brief fields it came from. The finished filter passes three tests: you can list them, count them, and they would vouch for each other.
Observable or cut.
Every line must be checkable from outside: a team page, a public price, a launch date. 'Values speed' isn't a line.
Traced or cut.
Each line names its brief fields; its confidence is the highest evidence tier among them.
Kill or narrow, never widen.
When a line fails a test, make the segment narrower or drop it. Widening is decided in advance, not in a panic.
what it is
An ideal customer profile as a runnable filter
Industry names: ideal customer profile (ICP), fit criteria, firmographic and technographic filters, disqualifiers. Clearbit's distinction: TAM is a number for investors; an ICP is a filter you can run against a database. Dave Kellogg's three dimensions: the ideal person, at the ideal company, with the problem you solve.
In VibeDraft the fit layer is concrete: the public-pain rule decides whether a lead's product is Hot or Warm, or only Watch; lead rules hold who is never a customer and who are competitors. The lines on this page are the design those rules come from.
Fits-if line — inclusion criterion · an observable attribute the buyer has.
Not-if line — disqualifier · an observable attribute that rules them out, whatever else is true.
List test — enumerable · you can name forty candidates in an hour without guessing.
Count test — denominator · you know how many exist, so you know your share.
Vouch test — referenceable · members can reach each other, so word of mouth can work (Geoffrey Moore's market test).
Stated vs evidenced — two versions · the founder's description, kept apart from what evidence shows.
how it works
From brief fields to a tested filter
Lines are drafted from the brief, then tested by trying to use them: list real candidates, count the pool, check that they know each other. A line that can't be checked on a stranger is rewritten or cut.
- Start from behaviour — who bought quickly and stayed (Dunford)
- Draft lines — fits-if and not-if from brief fields
- Make it observable — can you query for it? 'runs Next.js' yes
- Trace each line — fields it came from; confidence = top tier
- List test — name 40 candidates in an hour
- Count test — estimate the pool and its source
- Vouch test — do they read the same places, know each other?
- Narrow or cut — never widen on failure; widening ladder set ahead
- Start from behaviour — who bought quickly and stayed (Dunford)
- Draft lines — fits-if and not-if from brief fields
- Make it observable — can you query for it? 'runs Next.js' yes
- Trace each line — fields it came from; confidence = top tier
- List test — name 40 candidates in an hour
- Count test — estimate the pool and its source
- Vouch test — do they read the same places, know each other?
- Narrow or cut — never widen on failure; widening ladder set ahead
how narrow
Narrower than feels comfortable. April Dunford: target as narrowly as you can to meet near-term sales objectives. Narrow is a targeting unit, not a ceiling: the people at the centre are reached first, and the message still lands on the people around them.
the object
A fit line
Lines are versioned with the ICP. When a lead is scored, the lines it matched are frozen on the lead so a later change to the ICP can't rewrite history.
icp_line
| field | type | what it holds |
|---|---|---|
icp_version | text | which version of the filter |
kind | enum | fits, not, hard (must-have requirement) |
text | text | the line, in plain words |
check | text | how to test it on a stranger from outside |
traced_to | list | brief fields it came from |
confidence | enum | product rule, code rule, high (A), medium (B/C), guess (D) |
tests | object | list, count and vouch results, with dates |
lift | number or null | later: how much the line raises the chance of payment |
sample
{
"icp_version": "2026-10-09",
"kind": "fits",
"text": "Launched in the last 90 days, or about to",
"check": "launch-site date, first commit, domain age",
"traced_to": [
"watering_holes",
"voice_of_customer"
],
"confidence": "medium",
"tests": {
"list": "pass",
"count": "unchecked",
"vouch": "pass"
},
"lift": null
}line catalog
VibeDraft's lines, traced
fits if
Built alone or with a team you can count on one hand
- from
- Who it's for · paying customers
- confidence
- MEDIUM
- why
- founder belief, backed by a small number of payers
- check
- team page, open roles, LinkedIn headcount
fits if
Has a public price
- from
- What they must already have · how buying happens
- confidence
- PRODUCT RULE
- why
- there has to be something to buy
- check
- /pricing loads logged out
fits if
Launched in the last 90 days, or about to
- from
- Watering holes · voice of customer
- confidence
- MEDIUM
- why
- market evidence: the day 3 to 45 window
- check
- launch-site date, first commit, domain age
fits if
Between $0 and a few hundred in MRR, and knows the number
- from
- Who it's for
- confidence
- GUESS
- why
- founder belief only; test against payers
- check
- TrustMRR row, public revenue posts
fits if
Nobody owns distribution
- from
- Who it's for · why they bought
- confidence
- GUESS
- why
- becomes medium once payers' reasons confirm it
- check
- no marketing hire, founder posts 'builder not a marketer'
not if
Sells to a buying committee
- from
- How buying happens
- confidence
- PRODUCT RULE
- why
- self-serve product, one decider
- check
- 'book a demo' only, no checkout
not if
Wants strangers messaged automatically
- from
- What you can deliver now
- confidence
- PRODUCT RULE
- why
- it never sends the first message
- check
- interview, stated expectations
not if
No product yet
- from
- What they must already have
- confidence
- PRODUCT RULE
- why
- needs a URL with something to buy
- check
- URL resolves to content
code rule
Buyers describe the problem in public text
- from
- public-pain rule 1
- confidence
- CODE RULE
- why
- conversations to join exist
- check
- Reddit, X, Threads, forums, reviews
code rule
A customer is worth about $50 or more lifetime
- from
- public-pain rule 2
- confidence
- CODE RULE
- why
- a few customers pay for VibeDraft
- check
- read from the price; unreadable never demotes
code rule
Founder-led by a small team
- from
- public-pain rule 3
- confidence
- CODE RULE
- why
- the founder can act on a message
- check
- team signals, founder identities
not if
Gifts, ecommerce, local businesses, impulse buys
- from
- public-pain rule 1
- confidence
- CODE RULE
- why
- fail rule 1: Watch, not chased
- check
- category from the brief
The three tests, in practice
List — Unusual Ventures: "DevOps Engineer" returns over a million people; real filters cut it to about 2,000. If you can't name forty without guessing, a line is too vague.
Count — Kyle Poyar: most SaaS companies say they focus on their ICP, few can show how many accounts are in it, aware, interested, considering, chosen. Write the number and where it came from.
Vouch — Geoffrey Moore: a market is customers "who have the ability to reference one another". If two prospects couldn't plausibly know each other, you have a list, not a market.
failure modes
How it goes wrong, and how to catch it
Unobservable lines — 'Cares about quality' can't be checked on a stranger. · Catch it: every line needs a check field; a line without one is rejected.
Demographic sketch — 'Carol has two cats': invented detail crowds out what predicts fit. · Catch it: attributes must trace to brief fields.
Qualification mistaken for fit — Budget, authority and timeline are questions about one prospect, not properties of a segment. · Catch it: keep BANT-style questions out of the ICP; they belong in the conversation.
Widening on failure — Ten quiet days, so the filter is loosened. · Catch it: decide the widening ladder in advance; on failure, narrow or kill.
History rewritten — A changed line silently re-scores old leads. · Catch it: version the ICP; freeze matched lines on each lead.
data to capture
Record it so a model can learn from it later
Every decision on this page is training data if it is recorded in the guide's shape from day one.
1 · log the decision · 2 · version whatever decided · 3 · freeze the inputs · 4 · keep the negatives · 5 · log the odds · 6 · every human touch is a label · 7 · one chain of ids · 8 · keep the raw
record
- the ICP version with every line, its check and traced fields
- per lead: which lines matched, frozen at score time
- per test (list, count, vouch): result, date, evidence
- the same line vector for every payer and every cancellation
label
founder accept or never on each lead; later, paid and churned
trains
an ICP fit classifier, and per-line lift: which lines actually predict payment, so weak lines get cut and strong ones get narrower
test
- knob: which fit and not-if lines are in
- mode: offline: rescore past leads under the new line set, compare against accept and paid labels
- win rule: higher agreement with founder accepts and payers, with the pool still above the yield floor