Paitho
← Product / Stage 04 · Qualification
Pipeline · Stage 04

Scoring is
opinionated.

A five-component model. Per-ICP weights. Hard disqualifiers. The fit score is the gate that decides whether a lead is worth real research.

What goes in, what comes out.

Inputs
Lead + Audit
  • lead.webAudit — channels, traffic, ecommerce maturity, content recency
  • lead.socialResearch — follower counts, posting cadence
  • lead.companySize — employees, revenue tier where known
  • icp.weights — per-component weights (sums to 1.0)
  • icp.disqualifiers[] — hard rules (e.g. is_agency)
Outputs
Score
  • lead.fitScore — 0–100 weighted composite
  • lead.scoreBreakdown — per-component subscores
  • lead.disqualifiers[] — names of fired hard-rules
  • lead.qualificationTier — A/B/C tier for sorting
  • lead.qualifiedAt — timestamp + prompt_id back-link
Default cutoff: fitScore ≥ 65 & disqualifiers.length === 0

Five components.
Per-ICP weights.

digitalMaturity
0.30
channelDependency
0.25
productFit
0.20
companySize
0.15
accessibility
0.10
— example weights for devtools · editable per pack

Each lead receives a subscore on five components. Digital maturity measures whether the lead has the website, channel presence, and content cadence to recognize the product. Channel dependency measures whether their distribution is concentrated enough that the pitch lands. Product fit measures alignment between observed pains and your solution templates. Company size measures whether the deal is worth the touch. Accessibility measures whether you can actually reach a decision maker.

Weights are per-pack, not per-product. The devtools pack weights infrastructure complexity heavily because the pitch only works if they're already running multi-cluster Kubernetes. The clinical pack weights accessibility higher because the buyer is often a clinic admin who answers their own email. You edit the weights once when you install or fork a pack, and the score model recomputes on every qualification run.

Hard disqualifiers run before scoring and override it. If a lead matches is_agency or below_min_traffic or on_global_blocklist, the score is calculated for diagnostics but the lead is tagged disqualified and never enters the Pitch Brief stage. That's the gate that keeps your enrichment bill, your LLM bill, and your reviewer time pointed at leads that can convert.

Score from facts. Never from vibes.

prompt · qualify_v22 · devtools +
--- system ---
You are a B2B fit-scoring assistant. Score the lead on five components,
each 0..100. NEVER guess a subscore if the required input is missing —
return null and add the field name to missing_required.

--- inputs ---
lead:
  domain:        {{lead.domain}}
  webAudit:      {{lead.webAudit | json}}
  socialResearch:{{lead.socialResearch | json}}
  companySize:   {{lead.companySize | json}}

icp:
  id:            {{icp.id}}            # devtools
  weights:       {{icp.weights | json}}
  disqualifiers: {{icp.disqualifiers | json}}

--- output schema ---
{
  "subscores": {
    "digitalMaturity":   number | null,
    "channelDependency": number | null,
    "productFit":        number | null,
    "companySize":       number | null,
    "accessibility":     number | null
  },
  "disqualifiers_fired": string[]   # names from icp.disqualifiers only,
  "missing_required":    string[],
  "rationale":           string
}

--- guards ---
- composite = sum(subscore * weight) only if all subscores present.
  Otherwise composite = null and lead.qualificationTier = "pending".
- If any disqualifier fires, lead.qualificationTier = "rejected"
  regardless of composite.

# <!-- PLACEHOLDER — full prompt registry available in app -->

What can break.
And what catches it.

Risk
Scoring drift across vertical

A model trained on one ICP overscores leads in a different one.

Mitigation

Per-ICP weight vault. Each ICP carries its own weights, disqualifiers, and threshold; nothing is shared by accident.

Risk
Missing input, false high score

Web audit hasn't completed yet, so the model fills the gap with optimism.

Mitigation

Composite is null if any subscore is null. The lead stays in pending until the audit finishes.

Risk
Disqualifier evasion

Composite is high enough that an obviously-bad lead slips into outreach.

Mitigation

Hard disqualifiers always override composite. is_agency + score 95 = rejected, full stop.

Score your list before you
send anything.

Drop a CSV. Watch the five components compute live in the sandbox.