Hot Lead Visibility & Routing
Kanban color + 9am Telegram digest of score>=80 leads. The signal layer that drives prioritization for every other Phase 1.5 outbound and revival flow.
Runbook wires in priority order. Estimated 6h to ship.
Brain spec exists. This page becomes a full runbook (decision tree, trigger, ICP filter, Odoo objects, build steps, success metrics) when this flow comes up in the queue.
Flowchart in plain English
What fires this flow
Tier C · Info-only / no human gate
Info-only digest, no human approval needed to display. The digest surfaces existing Odoo state; no outbound message sends from F02 directly. Actions Yazan takes (calling a lead, sending WA, opening Odoo activity) are gated by their own flows (F01, F07, F11). Inline-keyboard callbacks (Mark Touched, Snooze 24h) are Odoo field mutations, not human-reaching. Stays Tier C by design.
Who this flow targets
The 0-100 score IS the ICP filter. Four pillars, 0-25 each: Signal (intent: web visit, lead-magnet download, GA4 event, Cal.com no-show), Fit (matches ICP segments per ~/ivan/equipt/brain/core/identity.md: owner-operated SME boutique, hotel pre-opening 12mo out, residential developer with handover, healthcare wellness, hospitality groups), Access (decision-maker contact: direct email + WA + LinkedIn + named role), Ask (audit booked / quote requested / scope shared / objection raised). Franchise-locked brands (F45, Barry's, OTF, CrossFit affiliate) auto-deduct 25 in Fit. Government tender desks auto-deduct 20. KSA leads route to separate dormant queue.
What this flow produces
Two surface artifacts. Surface 1; Kanban view in Odoo CRM pipeline: red banner for score≥80 (Hot), amber for 60-79 (Warm), grey for <60 (Cool), Anton numeral 88px+ in corner displaying score per BRAND.md §A 'single big numeral' rule, brass hairline divider between bands. Surface 2; Telegram digest 09:00 GST Mon-Fri to Yazan inbox with ranked leads, score-breakdown, recommended next action, and three inline-keyboard buttons per lead (Open in Odoo / Snooze 24h / Mark Touched). Side-effects: tags added, mail.activity created on threshold crossing, JSONL audit row per send + per callback.
18 records · the system-of-record surface
| Object | Action | ID | Notes |
|---|---|---|---|
| crm.lead | Read | n/a | Source records |
| crm.lead.x_lead_score | Read/Write | 27614 | Existing; formula fires backend |
| crm.lead.x_score_band | Read/Write | 27616 | Existing; hot/warm/cold selection |
| crm.lead.x_score_breakdown | Read/Write | 27618 | Existing; text rationale per pillar |
| crm.lead.x_last_score_update | Read/Write | 27620 | Existing |
| crm.lead.x_last_activity_date | Read/Write | 27622 | Existing; decay input |
| crm.lead.x_last_action_date | NEW write | TBD | Propose to Ivan; datetime; updated by Mark Touched callback |
| crm.lead.x_digest_snoozed_until | NEW write | TBD | Propose to Ivan; datetime; set by Snooze 24h button |
| crm.lead.x_manual_score_override | Read | 27624 | Existing; honored in queries |
| crm.tag 'Hot Lead' | Write | 22 | Existing |
| crm.tag 'Ivan Alert' | Write | 23 | Existing |
| mail.activity.type 'Call Hot Lead' | Write | 18 | Existing |
| mail.activity.type 'Hot Lead Aging Alert' | Write | 20 | Existing |
| ir.cron 'Daily Lead Score Decay' | Existing | 80 | Untouched |
| ir.cron 'Yazan Daily Hot-Lead Digest' | Existing | 81 | Dormant; activate in step 12 |
| base.automation 'Score Threshold Routing' | Existing | 25 | Extend to fire Telegram on threshold cross |
| ir.actions.server (decay/digest/routing) | Existing | 1281/1282/1284 | Server-action code |
| Odoo Studio Kanban view | NEW config | n/a | Color banding rules; configured via Studio, not XML-RPC |
16 sequenced steps · 13.5h total
How we know it's working
| Metric | Baseline | Target | Window |
|---|---|---|---|
| Median time-to-first-touch on score≥80 leads | ~6-12h business-time (estimate) | <4h business-time | rolling 30 days |
| Yazan opens digest within 30 min of 09:00 GST | unknown | ≥80% of days | 30 days |
| Score≥80 leads sitting untouched >24h | ~30%+ (estimate) | 0 | 7 days |
| Kanban color visible on every CRM open | n/a | 100% | 7 days standup verify |
| Mission Control card delivered + acted-on | n/a | green 7 consecutive days | week 2 |
| F02 telemetry feeding F01 decay correctly | n/a | 0 drift incidents | rolling 30 days |
| Audit JSONL gap-free | n/a | 0 missing days | rolling 30 days |
What this flow needs and what needs it
When to halt and rethink
Diagnose: (a) Yazan not opening Telegram → training + accountability, (b) digest too noisy → raise threshold to 85, (c) scores miscalibrated → F03 eval-gate sample on 50 hot leads. Root-cause and patch; do not just lower the bar.
Threshold of 80 too low for current volume. Raise to 85 + retest.
x_last_action_date updated but chatter shows no email/call/WA in matching window = Yazan lying to the tool. Audit JSONL + chatter cross-check weekly. >3 incidents in 30 days = trust failure, surface to Ivan.
Halt scoring decisions; rebuild formula with Yazan in the room.
Score identifying wrong leads. Pull 30 days of Hot Lead history; cross-check against actual Won deals. Re-weight Signal vs Fit vs Access vs Ask pillars.
Frameworks operationalized
Hormozi Speed-to-Lead (Ch. 9 + Ch. 5); <60s response on inbound is what F02 makes possible at scale. Without a digest, Yazan can't honor speed-to-lead on more than the 1-2 leads he happens to see in real-time.
Holmes Dream 100 prioritization (Ch. 2 + USM Ch. 7); Score crossing 80 on a Dream 100 entry = the latent buyer just turned warm. F02 is the radar; F07 + F22 + F24 are the missiles.
Holmes Buyer's Pyramid (Ch. 6); The 3% in-market gets the digest treatment; the 7% open gets F32 newsletter; the 60% latent gets F18 GEO + F-LM-HIIT. F02 isolates the 3%.
Sandler Up-Front Contract Rule #5 (Ch. 5); UFC depends on Yazan being prepared. F05 Pre-Discovery Brief consumes F02's hot-lead signal to fire the brief 30 min before Cal.com call. Sandler can't be executed cold; F02 + F05 together make it possible.
Hormozi Two Closing Questions (Ch. 8); Mark Touched inline button is the operator-side action that closes the loop. Yazan can't say 'I touched it' until he actually did. Honesty enforced mechanically.
Quality checks before any commit / send
Internal voice rules; BLUF, semicolons, no em-dashes, plain operator language. Mechanical dash-audit on digest template before commit.
equipt-skill-eval-gate (F03); scoring formula is Tier B skill; F03 measures agreement with Yazan judgment on 50 samples ≥95% before any scoring change graduates to production. Ties F02 to F03 explicitly.
wrap-untrusted-input; any prospect-supplied text arriving via webform → crm.lead.description wrapped before reaching agent reasoning per _REGISTRY.md §9 hard rule #2.
Langfuse emission; digest send emits {persona=james, skill=equipt-flow-02-digest, tier=C, outcome={lead_count, ivan_alert_count}, duration_ms, token_cost}. Required even though internal because Tier B graduations of other flows depend on F02 telemetry.
equipt-outbound-preflight; does NOT fire on F02 because F02 produces no outbound surface.
Append-only history
| Date | Transition | Owner | Proof |
|---|---|---|---|
| 2026-04-15 | NOT STARTED → LIVE 30% backend | Ivan | 8 custom fields + 4 tags + 3 activity types live |
| 2026-04-22 | LIVE 30% → LIVE 60% backend | Ivan | Cron 80 (decay) live; automation 25 + server actions 1281/1282/1284 wired; cron 81 (digest) created but dormant |
| 2026-04-30 | LIVE 60% → spec at 60% thin | Ivan | thin spec filed |
| 2026-05-13 | LIVE 60% → SPEC LOCKED | Ivan + Claude | Full spec replaces 55-line thin; build steps 1-16 sequenced; Flow Studio runbook page shipped |
| TBD | LIVE 60% → LIVE 100% | Ivan | Build steps 1-16 complete; Yazan trained; 7-day Mission Control card green; <4h median first-touch verified |