F02IN PROGRESSSales·tier 1

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.

Trigger
Daily 09:00 + crm.lead score change
KPI / result
Same-day touch on score>=80
Audit log pattern
n/a
Queued for build  ·  Week 3

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.

Health  ·  30-day
accept-rate
waiting for audit JSONL data
NO DATA YET
0 events / 30d
~/ivan-ops/audit/flow-02-*.jsonl
§ 01 · Decision tree

Flowchart in plain English

§ 02 · Trigger

What fires this flow

Primary
base.automation ID 25 fires on every crm.lead write to x_lead_score (real-time)
Secondary
ir.cron ID 81 'Yazan Daily Hot-Lead Digest' runs 09:00 GST Mon-Fri
Two trigger surfaces. Real-time on threshold crossing (score crosses 80 from below) appends Hot Lead tag, creates Call Hot Lead activity, POSTs to Telegram webhook. Daily cron renders inline-keyboard digest. Third silent trigger (cron 80) handles nightly score decay; untouched, part of existing 60%.
§ 03 · Tier

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.

§ 04 · ICP filter

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.

§ 05 · Output

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.

§ 06 · Odoo objects touched

18 records · the system-of-record surface

ObjectActionIDNotes
crm.leadReadn/aSource records
crm.lead.x_lead_scoreRead/Write27614Existing; formula fires backend
crm.lead.x_score_bandRead/Write27616Existing; hot/warm/cold selection
crm.lead.x_score_breakdownRead/Write27618Existing; text rationale per pillar
crm.lead.x_last_score_updateRead/Write27620Existing
crm.lead.x_last_activity_dateRead/Write27622Existing; decay input
crm.lead.x_last_action_dateNEW writeTBDPropose to Ivan; datetime; updated by Mark Touched callback
crm.lead.x_digest_snoozed_untilNEW writeTBDPropose to Ivan; datetime; set by Snooze 24h button
crm.lead.x_manual_score_overrideRead27624Existing; honored in queries
crm.tag 'Hot Lead'Write22Existing
crm.tag 'Ivan Alert'Write23Existing
mail.activity.type 'Call Hot Lead'Write18Existing
mail.activity.type 'Hot Lead Aging Alert'Write20Existing
ir.cron 'Daily Lead Score Decay'Existing80Untouched
ir.cron 'Yazan Daily Hot-Lead Digest'Existing81Dormant; activate in step 12
base.automation 'Score Threshold Routing'Existing25Extend to fire Telegram on threshold cross
ir.actions.server (decay/digest/routing)Existing1281/1282/1284Server-action code
Odoo Studio Kanban viewNEW confign/aColor banding rules; configured via Studio, not XML-RPC
§ 07 · Build steps

16 sequenced steps · 13.5h total

01
Verify scoring math fires on every lead update
Pick 5 random crm.lead records, manually edit a signal pillar via XML-RPC write(), confirm x_lead_score recalculates within 60s. If drift, debug ir.actions.server ID 1284 before continuing.
OWNER: Ivan
Time
30m
02
Document the formula at brain/domains/lead-scoring.md
1-page spec of Signal+Fit+Access+Ask breakdown, franchise-locked deduction, KSA queue routing, decay rule. Source of truth for F03 eval-gate samples.
OWNER: Ivan
Time
1h
03
Propose x_last_action_date + x_digest_snoozed_until to Ivan
Explicit go before adding to crm.lead via Odoo Studio. STOP HERE until confirmed.
OWNER: Ivan
Time
5m
04
Add the 2 new custom fields
Odoo Studio → crm.lead model → add fields. Record IDs in _REGISTRY.md §3.1.
OWNER: Ivan
Time
20m
05
Configure Kanban view color rules
Odoo Studio → CRM Pipeline Kanban view → 3 conditional formatting rules (red ≥80, amber 60-79, grey <60). Apply Anton 88px+ display widget per BRAND.md §A.
OWNER: Ivan
Time
1h
06
Build the digest Python skill
~/.claude/skills/equipt-flow-02-digest/SKILL.md. Query crm.lead WHERE score≥80 AND active AND not snoozed AND not touched-in-last-2d. Enrich with name + ICP tags + last touch summary + LLM-drafted recommended action. Thin-space decimals per BRAND.md §1.12.
OWNER: Ivan
Time
2h
07
Format Telegram message + inline keyboard
Per-lead bullet with [Open in Odoo](deep link)[Snooze 24h](callback)[Mark Touched](callback). Use Telegram Bot API inline_keyboard with callback_data carrying lead_id + action.
OWNER: Ivan
Time
1h
08
Wire inline-keyboard callback handler
Extend ~/ivan-ops/scripts/telegram-bot.py (James bridge) to handle three callbacks: mark_touched_<lead_id>, snooze_<lead_id>, open_<lead_id>.
OWNER: Ivan
Time
2h
09
Wire score-threshold real-time Telegram
Direct Python from base.automation 25 webhook; sends Telegram to Yazan (and Ivan if ≥90 OR revenue ≥AED 800K). No n8n per global rule (custom code only).
OWNER: Ivan
Time
1.5h
10
Schedule launchd com.equipt.flow-02-digest
plist runs digest skill 09:00 GST Mon-Fri (not Sat/Sun; Yazan day off + Friday prayer respected).
OWNER: Ivan
Time
30m
11
Activate Odoo cron ID 81 as fallback
Set Odoo cron 81 to next-run 09:05 GST Mon-Fri as redundant fallback if launchd fails.
OWNER: Ivan
Time
30m
12
Test with current pipeline state
Trigger digest manually; verify count matches manual Odoo count of leads ≥80; verify Yazan Telegram format; verify all three inline buttons work.
OWNER: Ivan + Yazan
Time
1h
13
Train Yazan in 30-min session
Walk through digest semantics, <4h time-to-first-touch target, expectation that Mark Touched is honest (not a 'I'll get to it' lie). Digest is action not awareness.
OWNER: Yazan + Ivan
Time
30m
14
Wire JSONL audit
Every digest send + every inline callback writes {ts, action, lead_id, score, ivan_alert, snooze_until} to ~/ivan-ops/audit/lead-routing-YYYY-MM-DD.jsonl.
OWNER: Ivan
Time
30m
15
Wire Mission Control card
Read JSONL + compute daily digest count, Yazan response latency, Ivan-alert count, snooze rate.
OWNER: Ivan
Time
1h
16
Flip status in _REGISTRY.md §1A
LIVE 60% backend → LIVE 100%. Append to §13 status flip log with verification proof.
OWNER: Ivan
Time
5m
§ 08 · Success metrics

How we know it's working

MetricBaselineTargetWindow
Median time-to-first-touch on score≥80 leads~6-12h business-time (estimate)<4h business-timerolling 30 days
Yazan opens digest within 30 min of 09:00 GSTunknown≥80% of days30 days
Score≥80 leads sitting untouched >24h~30%+ (estimate)07 days
Kanban color visible on every CRM openn/a100%7 days standup verify
Mission Control card delivered + acted-onn/agreen 7 consecutive daysweek 2
F02 telemetry feeding F01 decay correctlyn/a0 drift incidentsrolling 30 days
Audit JSONL gap-freen/a0 missing daysrolling 30 days
§ 09 · Dependencies

What this flow needs and what needs it

Infrastructure
Odoo Enterprise live
Source of truth for all lead state
Telegram bot @Ivan_james_bot
Primary push channel per feedback_telegram_primary_channel.md
Custom Python orchestration
Per global rule; no n8n / Make / Zapier
F03 Skill Quality Eval Gate
Recommended for scoring formula evals; not blocking initial ship
GA4 → Odoo Website integration
Blocks Phase 2 GA4 Behavior Scoring add-on; does NOT block Phase 1.5
Consumed by
F01 Quote Follow-Up
Consumes Hot Lead tag as fast-track signal
F05 Pre-Discovery Brief
Consumes hot-lead webhook to trigger 30-min-before-Cal.com brief
F07 LinkedIn Outbound
Reads x_score_band to prioritize daily 16-connect quota
F11 + F20 + F22
All consume score band for ranking
F19 Won-Deal Onboarding
Reads historical score curve for case-study cohort selection
§ 10 · Reversal triggers

When to halt and rethink

01<4h first-touch target missed in ≥30% of hot leads (30-day window)

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.

02Yazan complaint 'digest too noisy' >2 in 30 days

Threshold of 80 too low for current volume. Raise to 85 + retest.

03Mark Touched dishonesty signal

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.

04Score formula drift; F03 sample shows formula-Yazan agreement <80%

Halt scoring decisions; rebuild formula with Yazan in the room.

05Hot-lead-to-Won conversion <20%

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.

§ 11 · Playbook alignment

Frameworks operationalized

§01

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.

§02

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.

§03

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%.

§04

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.

§05

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.

§ 12 · Voice + audit gates

Quality checks before any commit / send

01

Internal voice rules; BLUF, semicolons, no em-dashes, plain operator language. Mechanical dash-audit on digest template before commit.

02

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.

03

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.

04

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.

05

equipt-outbound-preflight; does NOT fire on F02 because F02 produces no outbound surface.

§ 13 · Status flip log

Append-only history

DateTransitionOwnerProof
2026-04-15NOT STARTED → LIVE 30% backendIvan8 custom fields + 4 tags + 3 activity types live
2026-04-22LIVE 30% → LIVE 60% backendIvanCron 80 (decay) live; automation 25 + server actions 1281/1282/1284 wired; cron 81 (digest) created but dormant
2026-04-30LIVE 60% → spec at 60% thinIvanthin spec filed
2026-05-13LIVE 60% → SPEC LOCKEDIvan + ClaudeFull spec replaces 55-line thin; build steps 1-16 sequenced; Flow Studio runbook page shipped
TBDLIVE 60% → LIVE 100%IvanBuild steps 1-16 complete; Yazan trained; 7-day Mission Control card green; <4h median first-touch verified
§ Spec

Source of truth

Canonical brain spec
~/ivan/equipt/brain/domains/flows/flow-02-hot-lead-visibility-routing.md
Read-only · do not freelance edits
§ 03 · Email templates

Live from Odoo mail.template

No templates wired for this flow yet.
§ 04 · WhatsApp templates

From Odoo WhatsApp module; Meta-pending

No WhatsApp templates wired for this flow yet.
§ 05 · Drive assets

Photo library; segment-matched

No Drive assets wired for this flow yet.
§ 06 · Audit log

Last 30 days of sends + skips

Audit feed connector wires in v0.1. Reads ~/ivan-ops/audit/flow-NN-*.jsonl.