listen · lead scoring and merging
Tiers and contact policy
Hot, Warm, Watch and who never gets contacted.
In Lead scoring and merging
stage 7 · lead scoring and merging · tiers and contact policy
Hot, Warm and Watch decide when a lead gets a move. The contact policy decides whether it can get one at all. Both live on the person, so they follow every handle after merging.
signal → lead → tiers and policy → playbook
Tiers are service levels — Hot means today, Warm means this week, Watch means keep listening. Nothing else.
Policy beats tier — A Hot lead in cooling-off gets nothing. The check runs before every move, on every channel.
Never-contact is forever — Set by a stop request, a lead rule or the founder. Nothing automatic ever clears it.
what it is, in industry terms
Three tiers decide when; the contact policy decides whether.
Tiers turn a score into a service level a solo founder can keep. The contact policy is the guard every move passes first. Together they're why a distribution agent can act fast on Hot leads without ever spamming anyone.
Lead tier — also: lead grade, priority bucket · A small number of buckets that decide the service level: who gets a move today, this week, or not yet.
Speed to lead — response-time SLA · How fast a tier must be acted on. A Hot lead's buying window is measured in hours.
Contact policy — frequency caps, cadence rules · Limits that apply before any message: how often, how close together, which channels, which hours.
Suppression list — do-not-contact, never-contact · People who must never get a move. Set by the founder, a stop request or a lead rule. Never cleared automatically.
Cooling-off — rest period · A window after a touch with no reply when no new touch is allowed.
Override — manual tier · The founder sets a tier by hand. Kept as a label: it says where the rule was wrong.
how it works
From a lead to today's list, through two checks.
Check the person
never-contact or a lead rule (customer, never, competitor): out
Apply the public-pain rule
all three fit lines hold: Hot or Warm. Any fails or is unknown: Watch
Split Hot from Warm
proposed: fresh strong or stacked signals are Hot; older, weaker or single are Warm
Record the change
every tier change with its cause and rule version
Check the contact policy
caps, cooling-off, quiet hours, channel allowed, at the person level
Release to the list
Hot today, Warm this week, Watch keeps listening
- Check the person — never-contact or a lead rule (customer, never, competitor): out
- Apply the public-pain rule — all three fit lines hold: Hot or Warm. Any fails or is unknown: Watch
- Split Hot from Warm — proposed: fresh strong or stacked signals are Hot; older, weaker or single are Warm
- Record the change — every tier change with its cause and rule version
- Check the contact policy — caps, cooling-off, quiet hours, channel allowed, at the person level
- Release to the list — Hot today, Warm this week, Watch keeps listening
| Tier | Service level | Rule |
|---|---|---|
| Hot | a move today | all three public-pain fit lines hold, and the signal is fresh and strong, or stacked |
| Warm | a move this week | all three fit lines hold, but the signal is older, weaker or single |
| Watch | no move yet | any fit line fails or is unknown; a second signal or a confirmed line can promote |
the objects
A tier change, and the policy state of a person.
tier_change
| Field | Type | What it holds |
|---|---|---|
| change_id | uuid | One tier change. |
| lead_id | uuid | Whose tier changed. |
| from, to | hot | warm | watch | out | The move. out covers never-contact and lead rules. |
| cause | enum | new signal, signal aged, fit line confirmed, fit line failed, founder override, lead rule, stop request. |
| rule_version | string | The tier rule that made the call, e.g. public-pain.2026-10-09. |
| by | system | founder | Who changed it. |
| at | timestamp | When. |
contact_policy (per person)
| Field | Type | What it holds |
|---|---|---|
| person_id | uuid | Policy lives on the person, so it follows every handle after merging. |
| last_touch_at | timestamp | The most recent move, any channel. |
| touches_7d | int | Moves in the last 7 days, all channels. |
| cooling_until | timestamp | No move before this. |
| channels_allowed | list | Public reply only, DM allowed (after they engaged), email (only if they gave it). |
| quiet_hours | local window | No sends at night in their timezone, when it's known. |
| never_contact | bool + reason + source | Founder, stop request or lead rule. Sticky across re-imports. |
sample, as data
{
"tier_change": {
"change_id": "tc_301",
"lead_id": "ld_51aa",
"from": "watch",
"to": "warm",
"cause": "fit line confirmed",
"rule_version": "public-pain.2026-10-09",
"by": "system",
"at": "2026-10-17T13:02Z"
},
"contact_policy": {
"person_id": "pn_2c7d",
"last_touch_at": null,
"touches_7d": 0,
"cooling_until": null,
"channels_allowed": [
"public_reply"
],
"quiet_hours": "22:00-08:00 local",
"never_contact": {
"value": false
}
}
}the catalog
Sixteen tier changes and policy rules.
tier.new-strong — tier change
Fresh strong signal
- move
- watch → hot or warm
- when
- a strong signal under its half-life arrives and all fit lines hold
- note
- Hot if fresh and strong; Warm otherwise
tier.stacked — tier change
Second signal stacks
- move
- warm → hot
- when
- a signal from a different detector or trigger arrives inside the window
- note
- stacking is the strongest promotion
tier.aged — tier change
Signal aged past its window
- move
- hot → warm → watch
- when
- the strongest signal passes one, then two half-lives with no new one
- note
- keeps yesterday's Hot from crowding today's list
tier.line-confirmed — tier change
Fit line confirmed
- move
- watch → warm
- when
- enrichment or the founder confirms the unknown fit line
- note
- the commonest promotion out of Watch
tier.line-failed — tier change
Fit line failed
- move
- any → watch
- when
- they turn out not to sell to people, or the product isn't live
- note
- demote, keep listening
tier.override — tier change
Founder override
- move
- any → any
- when
- the founder sets the tier by hand
- note
- kept as a label: the rule was wrong here
tier.replied — tier change
They replied
- move
- any → in conversation
- when
- a reply to a move arrives
- note
- leaves the tier list; the conversation's own next step takes over
tier.joined — tier change
Joined or paid
- move
- any → converted
- when
- a waitlist join or a payment matches the person
- note
- closes the lead; it becomes an outcome label
policy.stop — policy rule
Stop request
- move
- any → out, sticky
- when
- they say stop, block or report
- note
- never cleared automatically; logged as negative feedback
policy.lead-rule — policy rule
Lead rule match
- move
- any → out
- when
- the founder's rules say customer, never a customer, or competitor
- note
- never becomes a lead
policy.cap-7d — policy rule
Weekly cap
- move
- blocks a move
- when
- proposed: a third touch inside 7 days, across all channels
- note
- caps apply to the person, after merging
policy.cooling — policy rule
Cooling-off
- move
- blocks a move
- when
- proposed: a touch with no reply in the last 3 days
- note
- one unanswered message is a fact; two is a pattern
policy.dm-gate — policy rule
DM gate
- move
- blocks a channel
- when
- they haven't engaged with you publicly yet
- note
- public reply first; a DM only after they answer
policy.quiet — policy rule
Quiet hours
- move
- delays a move
- when
- it's night where they are, when their timezone is known
- note
- drafts wait for morning
policy.two-in-a-row — policy rule
No reply twice
- move
- watch, cooling 30 days
- when
- proposed: two moves, no reply
- note
- back to listening; a fresh signal can restart
policy.channel-limit — policy rule
Platform limits
- move
- blocks a channel
- when
- the platform's own reply or DM limits are near
- note
- never let a cap bite in the middle of a sequence
illustrative example
One morning, before launch.
With one founder spending about 20 minutes a day, tiers have to keep Hot short. A rule of thumb to start with: if Hot holds more than ten people on a given morning, the Hot cut is too loose, and the fix is to require a stacked or very fresh signal, not to work faster.
ONE MORNING · EXAMPLE
- Hot
- 4 people: 2 asked for a tool in the last 12 hours, 1 stacked (Reddit + X reply), 1 commented the keyword
- Warm
- 23 people, a public reply each this week
- Watch
- the rest; any fresh signal can promote them
- blocked
- 2 by cooling-off, 1 DM gate, 1 never-contact (said stop last week)
- result
- 4 moves today, each logged with tier, rank and the policy state at send time
failure modes
Six ways tiering and policy go wrong.
Everyone is Hot — Loose rules put fifty people in Hot and the list stops meaning anything. · catch ita daily Hot count with an alert; tighten the rule when it grows
Stale Hot — A lead stays Hot for a week because nothing demotes it. · catch itage-based demotion runs every day, not only on new signals
Policy bypass by channel — Capped on X, the same person gets a Reddit reply because the two handles weren't merged. · catch itcaps live on the person; unmerged duplicates are counted as incidents
Never-contact lost — A re-import or a new handle brings back someone who said stop. · catch itnever-contact sits on the person and is checked against every new claim
Overrides that teach nothing — The founder fixes tiers by hand and the rule never learns why. · catch itstore every override with the rule's tier beside it; review them monthly
Quiet hours guessed wrong — A timezone guessed from a single post sends at 3am. · catch itonly apply quiet hours when the timezone is known; otherwise default to your daytime
data to capture
Every change and every block, with its reason.
record
- every tier change with cause, rule version and who made it
- the contact policy state at the moment of every move, and every block with the rule that blocked it
- founder overrides, with the rule's tier beside the chosen one
- stop requests and negative feedback, tied to the touch that caused them
label
- override: the rule's tier was wrong for this person
- replied, joined or paid by tier: does Hot really outperform Warm?
- stop requests per 100 touches by tier and channel (a guardrail)
trains
- calibrated tier cutoffs, so each tier has a measured reply rate
- a cap and cooling-off setting learned from stop requests against replies
test
- offline: replay the tier rule on past leads and compare the reply rate per tier
- online: test one policy knob at a time (cooling 3 days vs 5) with leads randomized, stop requests as the guardrail
Handles, products and scores in examples are invented. Merge only on public or first-party data, keep never-contact sticky, and a person always sends the first message.