LeadRefinery — How the Platform Works

Lead lifecycle and cadence

Traced at commit ffe4e48 · libs/contracts/src/lib/lifecycle-machine.ts · libs/contracts/src/lib/{cadence-schedule,cadence-c1}.ts · libs/db/src/schema/leads.ts

Summary

  1. A lead has 10 states.
  2. The platform ingests, validates, scrubs and queues a lead before a campaign can use it.
  3. The pacer releases the lead. The lead then becomes CYCLE_ACTIVE.
  4. Each dispatched attempt moves the lead to HELD.
  5. A lead in HELD cannot advance, cannot be re-dialled and cannot rest.
  6. The lead leaves HELD only after the platform writes the outcome.
  7. The programme has 3 cycles: 5, 4 and 3 attempts, over 6, 5 and 4 business days.
  8. A lead in TERMINAL always has a recorded reason. The database enforces this.
A lead is ingested, validated, scrubbed against do-not-call lists, then queued. When the pacer releases it the lead becomes cycle-active and receives attempts. Each dispatched attempt puts the lead in the held state, where it cannot advance, cannot be re-dialled and cannot start its rest until the outcome is written. A completed cycle moves the lead into a gap, and after the gap it becomes active again. The programme has three cycles of five, four and three attempts, spanning six, five and four business days. A lead ends in the terminal state and the reason is always recorded.
Ten states. HELD stops a lead while a call has no outcome.

Workflow 1 — the states

Before a campaign can use the lead

  1. INGESTED — the platform has the row.
  2. VALIDATED — the row passed the shape checks.
  3. SCRUB_PENDING — the number is waiting for a do-not-call check.
  4. QUEUED — the scrub cleared the number. The pacer can release the lead.
  5. SUPPRESSED — the scrub flagged the number. The lead stops here.

Inside a cycle

  1. The pacer releases the lead. The state becomes CYCLE_ACTIVE.
  2. The platform dispatches an attempt. The state becomes HELD.
  3. The platform writes the outcome. The state returns to CYCLE_ACTIVE.
  4. A captured commitment, such as a call-back time, moves the lead to SCHEDULED.
  5. A completed cycle moves the lead to CYCLE_GAP.
  6. The gap ends. The state returns to CYCLE_ACTIVE for the next cycle.

HELD is the important state. Three events are absent from it, on purpose. The cycle cannot complete. The gap cannot start. The platform cannot dispatch a second attempt. That absence stops the attempt counter when a call merely ends. The counter advances only after the platform knows the outcome. Without HELD, a lead spends its cycle on calls that nobody resolved.

Workflow 2 — the calling calendar

The programme gives one lead twelve attempts across three cycles. Cycle one has five attempts over six business days, cycle two has four over five days, and cycle three has three over four days. A rest gap separates each cycle from the next. Attempts spread across four dayparts at half past nine, half past twelve, half past three and half past six, so a lead is not called at the same hour every time. After the last cycle the programme has no attempts left and the lead ends.
Workflow 2 of 2 — the calendar. Twelve attempts, three cycles, four dayparts.
  1. Cycle 1 — 5 attempts over 6 business days.
  2. Cycle 2 — 4 attempts over 5 business days.
  3. Cycle 3 — 3 attempts over 4 business days.
  4. A gap separates each cycle from the next.
  5. Attempts spread across four dayparts: morning, midday, afternoon and evening.
  6. After cycle 3 the programme has no attempts left. The lead becomes TERMINAL.

How a lead ends

  1. CONVERTED — the lead reached the outcome the campaign wanted.
  2. DECLINED — the person said no.
  3. CYCLES_EXHAUSTED — the programme used every attempt.
  4. NO_DIALABLE_NUMBER — the platform cannot call any number on the lead.
  5. CAMPAIGN_KILLED — an operator stopped the campaign.
  6. PROGRAMME_ENDED — the programme finished.
  7. MANUAL — a person ended the lead.
  8. The database rejects a lead in TERMINAL that has no reason.

The dial gate — what happens between CYCLE_ACTIVE and a ringing phone.