OrderPin 的 ISO 白牌获客外联系统——从找线索到 CRM 商务跟进共十一个环节,目标是把它跑成一条闭环。
外联由两套系统协作:系统 A(Hermes Tracker)负责工作日 20:00 的发送,系统 B(数据库账本)记录线索、邮件与会议。当前 Gmail 未登录,发送已经阻断;账本 queued 与实际待发分别统计。冷发域已于 2026-09-15 永久停产。
本看板的数字若无特别说明均属系统 B;两套系统按邮箱去重后的 A ∪ B 合并口径在 §01 第一组指标里(两边不能直接相加);每次更新看板全部数字实查,不沿用上一版。
current_date − N,本版边界 2026-09-09 00:00 UTC2026-10-09 快照。箭头表示业务路径;红色表示当前阻断,黄色表示仍需人工处理。详细历史评估保留在页尾。
盖章 2026-10-09 12:50 HKT:生产库、Tracker、发送与获客日志、批次记录、配额接口及会议纪要审计重新读取。所有当前统计以本节为准;页尾保留的 9 月评估是历史快照。
10/9 09:00 检查确认 Gmail 未登录,10/5–10/8 四个工作日均为零发送;最新实际发送停在 10/2。Tracker 真正待发仅 1 人,已经低于 150 人补货红线。
获客任务 10/2–10/8 被出口网络检查跳过。16:30 批次任务仍在运行:10/8 生成 184 名候选,其中 178 名待验证;验证、定稿、导入和释放仍需人工完成。
系统 A ∪ B 共标记 62 人回复;剔除 8 项误报(我方发件、营销邮件、自动客服、外出回复),并把自动预约信号单列。53 项中 52 项可从正文或明确日历动作复核,1 项正文被 HTML/CSS 截断、语义待补。含自动预约的有效互动共 54 项;A 独有且无可判证据的待复核项 0。数据库原标签不等于当前商业意向;筛选已结合客户 CRM 记录与后续邮件。
Tracker 1,111 人全部属于库中 2,655 个有邮箱联系人,Tracker 独有邮箱 0。两套系统按邮箱去重,人数与投递人次分别计算;发送状态仍未完整回写账本。
下面保留数据库原标签,供 A/B 对账使用,合计 62;它包含上方已剔除或单列的记录,不能作为销售跟进名单。内容审计后的业务分类为:有意向 17、拒绝 17、有效预约信号 10、回复者中的 meeting_held 技术子集 1、退订 3、其他 5,共 53。
| 数据库原分类 | 本轮(7/1 起) | 全部时期 | 说明 |
|---|---|---|---|
| 有意向 | 14 | 18 | 原标签;内容审计剔除 1 项我方发件 |
| 已拒绝 | 14 | 17 | 部分标签与后续正文或 CRM 不一致,筛选时重新判断 |
| 已约会(仅约,未开) | 5 | 13 | 2 项我方发件剔除,1 项自动预约另列;有效 10 |
| 回复者中 meeting_held(技术子集) | 1 | 1 | 只用于回复分类对账,不是实际开会总数 |
| 日历已结束(未验证出席) | 15 | 30 | 仅证明事件时间已过;30 位联系人对应 24 个审计后公司实体 |
| 纪要确认实际开会(历史) | 11 | 19 | 至少一次非空纪要确认到场并有实质沟通;对应 14 家公司 |
| 退订(分类) | 3 | 3 | 3 人通过业务回复退订;退订标志共 4 人 |
| 其他 / 未分类 | 2 | 9 | 内容审计剔除 4 项营销、系统确认或我方发件;有效 5 |
| 仅 A 侧回信,B 无正文可分类 | 1 | 1 | Mail 扫描可识别为外出自动回复,业务口径已剔除 |
| 合计(系统回复标记) | 40 | 62 | 技术口径按 reply_detected / Tracker replied 及已持久化自动回复标志计算 |
预约、日历结束和实际开会是三件不同的事。交接与跟进以纪要确认层为准;日历结束层只用于发现待核实记录。
meeting_completed=true;只看时间已过,不验证到场或会议内容30 位日历已结束联系人按对应事件核验:17 人/13 家在该场有实质会议;7 人虽有非空纪要但内容不足;2 人最近一场明确未到场;4 人没有纪要。Carolina PayPoint 两位联系人最近一场未到,但更早一次已有实质纪要,因此历史确认口径为 19 人/14 家。
meeting_completed;原始公司名直接去重为 27,实体审计合并后 24;未验证出席| 环节 | 当前状态 | 核实结果 | 下一步 |
|---|---|---|---|
| 供给 / 加工任务 | 出口检查阻断 | 10/2–10/8 每日 14:00、15:00 两次跳过;raw 最新入库 9/22 22:10Z,new 0 | 恢复美国固定出口后再检查任务产出 |
| 批次 → Tracker | 仍需人工 | 10/8 16:30–16:30:34 出批次;全集 1,234 → 候选 184,终态验证 6、未验证 178,账本已导入 603 | 按既有准入与抑制规则完成验证、定稿、导入、释放 |
| 发送 | Gmail 未登录 | 10/5–10/8 四个工作日零发送;10/9 09:00 未登录,距上次认证 17.7 天;最新实发 10/2 20:56 HKT | 重新认证 Gmail,再检查队列与发送前抑制 |
| 回信识别 | 技术标记需内容审计 | 10/9 09:00 本地扫描完成;标记 62、业务有效 53。入库未标 0;未来年份的 last_reply_at 0 | 对业务跟进使用内容审计和当前 CRM 状态 |
三张上游表现值:raw_leads 10,601 → company_leads 10,877 → lead_contacts 3,961。来源凭据 354;无网站 442、有站无摘要 34(非 high 档 33)。原始线索状态:promoted 9,784 / duplicate 647 / junk 88 / rejected 82。存量回流 5,757;五桶:不合格 5,083 / 测试 0 / 销售流程 25 / opt-out 12 / 可回流 5,757。邮箱验证:ok 1,347 / catch_all 869 / invalid 124 / unknown 104 / error 14。抑制表 87。
以下内容保留原有评估、设计决策与历史数字;“当前”“今天”“距今”等表述均指原记录日期。它们不是 2026-10-09 的运行状态,最新统计与阻断见上方 §00 / §01。
三个子块:当下运行状态(谁真的在发)→ 目标闭环(该长成什么样)→ 当前断点(差在哪)。
这一轮查出的每件事都是同一个形状:台账说的和实测的不是一回事。所以这张表并置两列。
| 渠道 | 台账怎么说 | 实测 | 状态 |
|---|---|---|---|
run.pyHermes ISO 邮件 |
jobs.json 工作日 20:00 |
最早发送 2026-07-01,累计 1,831 次投递(9/9 tracker 逐条) | 在跑 |
engine.jsLinkedIn 好友邀请 |
jobs.json:enabled=falsepaused_at 2026-07-14 |
launchd 那一路从未关闭。日志 452 条发送记录,100% 发生在标记暂停之后;跨 49 天、27 个发送日、451 人 | 台账说停了 |
linkedin_outreach_v3LinkedIn 私信跟进 |
代码默认 REAL_SEND=false |
.env:55 覆盖为 true,launchd 已调度。9/9 实测队列 59 人,其中 46 人已到期(runner_node 全部 = hermes-graham,与 .env:33 一致),current_step 分布 1→4。日志实证 9/2 sent=8/20、9/4 9/20、9/8 3/20(mode=REAL) |
在跑 · 46 已到期 |
linkedin_reply_send_worker审批过的回复自动发 |
代码默认 false |
脚本 :91 硬编码 true,每 15 分钟一轮;累计已发 20 条(完成: sent=N 行求和,最后一次 8/16),队列中 1 条且 9/9 09:52 发送失败(no_editor,回 approved 重试) |
在跑 · 发不出 |
cold_email_engine |
2026-06-25 恢复 | daily_leadgen.sh:260 整行注释;注释写明「活库 contacted 行 = 0 = 事实空转」 |
已停 |
send_emails_direct.py |
— | 无调度,但零护栏:给个 JSON 名单就全发,不查抑制名单、不限量 | 误跑成本最高 |
9/2 新增一个同族陷阱:daily_linkedin.out.log 里有两个任务名——linkedin_followups 每次都打「今日无需跟进的 LinkedIn 联系人」,而真正发 DM 的是 linkedin_outreach(sent=2/20 (mode=REAL))。按任务名判断「followups 在不在发」会得出完全相反的结论。
上个会话查到过 linkedin-iso,判断「它跑的是 engine.js,根本不碰 tracker」就排除了——「不碰 tracker」≠「不发信」。按「它写不写我关心的那张表」筛发送器,会整条渠道地漏掉。查一个 job 停没停,判据是看它的产出(state.json 的 added_today、日志末行),不是看配置里的开关。
| 口径 | 值 | 说明 |
|---|---|---|
| DB「可发」四层收紧 | 1,017 → 900 → 895 → 671 | ①有邮箱∧outreach_status='queued' ②排已发 t1 ③排 unsub/bounce/reply ④排 status∈(disqualified,dead,paused) |
| DB queued 三桶闭合(2026-09-10 21:4x HKT) | 1,036 = 189 + 417 + 430 | tracker 也 queued 189 · DB 标 queued 但 tracker 已发/已回 417 · tracker 没有 430(9/10 11:00 为 189 / 417 / 411,15:34 桥首轮 +19 全落在第三桶;9/9 10:35 为 175 / 417 / 425:9/10 10:55 唯一队列 B 步把 25 个候选里准入的 14 人写进 tracker,其余 11 = 每家 2 人超额 3 + catch_all 6 + invalid 2 留档未入队;导入不改 DB 的 status)。430 里 status='new' 140(= §0d 批 4 现值,recount_plan_headcounts.py 复算;11:00 为 124 = 旧默认值 108 + 桥推 16,之后桥 +19、黑名单改判 −3);全集 327(§0d 合计),构成以下一次 --recheck 为准 —— 9/4 批次快照已失效,下次 A 步先 --out-dir 出新批次。复算:scripts/ab_union.py 的 queued(both / B_only)+ tracker 里该邮箱的 status |
| 真·上膛 | 175 | (tracker 2026-09-08 22:04 HKT 快照;9/4 22:24 为 205、9/2 22:33 为 295)tracker 里 queued 且三个 tN_sent_at 全 NULL,本版逐条验 175/175 同形(9/2 那次验的是 295/295) |
| DB 比 tracker 多 | 425 | 这些人没有任何路径会被发出 |
| DB 陈旧 | 417 | (2026-09-09 10:35 HKT;9/4 为 357、9/2 为 297)DB 标 queued,tracker 里其实已发过 ⇒ 只能回填,不能相加 |
| t1/t2/t3 已发 | tracker 691 / 609 / 531;DB 276 / 211 / 187(9/2 起一行没动) | 发送器只读 tracker ⇒ tracker 是发送真相源,DB 仅为其 40% / 35% / 35% |
| 发送总量三口径 | run.log 2,041(含自测)· tracker meta 1,834 · tracker 逐条 1,831(纯外发) | 三个都复算成立(9/9),run.log 比逐条多 210;引用时必须点名口径 |
左侧三段分区(9/2 新增):供给段(来源 → raw_leads)近 30 天产出 43 条真线索(全部落在 9/3–9/9,0 个带邮箱;9/9 起 Tavily 配额硬停,见 §01 块 ②),Graham 已定换主线为 Apollo + LinkedIn Sales Navigator;加工段(规则闸 → 邮箱验证)是本轮唯一还有价值的一段,下一步是把新供给接到它的入口上;待发队列是边界(「到待发队列前」指的就是它以上);发送段在本轮范围之外。
一条主路径 + 一条存量回流边,纵向读。分配同事是终点——交给销售后线索就离开外联系统。让它成环的是 company_leads 存量回流到闸前那条边(5,758 家可回流,见 §01 枚举明细),不是从销售末端往回流。当前之所以看着像两条,是因为 Apollo 的 --ingest 从最后一格直插待发队列,而回流边根本不存在。颜色是每个环节的真实状态,不是计划状态。9/2 重画——旧图有三处与实查矛盾:把 Reveal 标成「手动」(实际没有代码)、把邮箱验证标成已打通(实际未调度)、把 LLM 判 ISO 标成未接线(实际 icp_v2_reclass 每天在跑,没接的是 Apollo 那条 --review)。
📐 系统实时状态图已移到页首(§00) —— 那张图反映的是此刻的模块状态,已关闭的通道不再画出。本节往下是它的明细与口径:多源入口逐桶枚举、各表计数的复算方式、以及被推翻过的旧结论。
与 SEND_PATHS_ENUM 同一套纪律:入口没枚举全,闸就会被整条地绕过,而且是静默的。上图十个格是这张表的摘要。下表实查自生产库,「绕过 raw_leads」列精确闭合到 953(= from_raw_lead_id IS NULL 的行数,2026-09-14 11:3x 实查,与 9/9 23:25 同值 —— 本版新增的 2 行 iso_disclosure 全部经 raw)。
| 来源桶 | 源数 | raw_leads | company_leads | 绕过 raw | 闸能不能看见 / 备注 |
|---|---|---|---|---|---|
| 自动抓取 · Google google_places / google_maps | 2 | 5,405 | 5,585 | 696 | 大部分经 raw_leads,696 条直写——这批闸看不见 |
| 一次性表格导入 import_batch=wechat_20260620 · 5 个 sheet | 5 | 3,409 | 3,409 | 0 | 全经 raw 但 0/3,409 有邮箱;source 名写 20260620 而实际导入是 2026-04-22;online_ordering sheet 里 99 家名字像餐厅(终端商户,不是 ISO) |
| 展会名单 tradeshow_linga/neaa/eta/discovery | 4 | 749 | 740 | 0 | 全经 raw |
| 其它单点源 cra_ncr / linkedin / clover_fiserv / pax | 5 | 578 | 453 | 0 | 全经 raw |
| POS 厂商合作方 *_partner / *_reseller | 12 | 45 | 45 | 0 | 全经 raw |
| 自动抓取 · Tavily tavily_discovery | 1 | 0 | 261 | 248 | 🔴 每天在跑却几乎全部直写 company_leads(仅 13 条经 raw) |
| 🔴 测试 / 审计垃圾 rls_audit 0(601 行 9/2 已删)/ qa_perf 0(62 行 9/9 23:22 已删) | 0 | 0 | 0 | 0 | 已清 migration 086 删 62 行(级联事件 868,审计入 qa_cleanup_audit),085 约束已 VALIDATE ⇒ 以后写入即拒;回流时仍显式排除(单元测试锁住) |
| Apollo source='apollo' | 0 | 0 | 37 | 46 | ✅ 已修:--ingest 改为只写 raw_leads、--promote 已退役 ⇒ 直插旁路关闭;闸 9/15 补建 37 家 ⇒ 现 46 条(2026-09-16 00:35 实查) |
| ISO 披露名单(新) iso_disclosure | 1 | 4 | 2 | 0 | 全经 raw 本版新桶:9/12 首次产出 raw 4 → company 2(1 家入库即判 non_pos,1 家进可回流桶 ⇒ 存量回流 +1)。名单 9/14 从 9 家扩到 25 家、轮换周期 3 天 → 7 天;9/13 那轮产出 0,真判据是库内当天 source='iso_disclosure' 行数,不是日志(task_runner 会把结算块截掉) |
| (source 为 null) | 0 | 0 | 0 | 0 | 已清 9/2 时有 9 条来源未知,9/9 实查 0 |
合计绕过 raw_leads | 953 | 精确等于 from_raw_lead_id IS NULL 的行数 ⇒ 枚举闭合 | |||
⚠️ 还有两条不在这张表里的入口,因为它们根本不落 company_leads:
① Apollo 直插待发队列 418 条(该旁路已关:最后一条直插停在 2026-09-14,现在只写 raw_leads,所以页首的图上不再画它)——三张上游表一张没进;且它不是一次性验证:分 5 次入库(7/22 158、7/26 4、7/27 13、8/10 83、8/18 160),81 行 t1_sent_at 非空(已真发信),其中 44 行 status='disqualified' 仍 outreach_status='queued'、2 行判否后照样发了出去。
🔴 比图上画的更隐蔽:这 418 行的 lead_source 全写成 linkedin,lead_source ilike '%apollo%' 实查 0 行,只能靠 discovery_meta 认出来 ⇒ 队列里 lead_source='linkedin' 的 546 行中 418 是 Apollo,真 LinkedIn 只有 128(0 有邮箱,9/9)。任何按 lead_source 做的枚举/闸/统计都会漏掉它。
② cold call 存量 1,203 家——它们在 company_leads 里(已计入上表各桶),但 caller_stage 携带的人工信号(尤其 ask_to_send_email 61 家)目前没有任何自动通路回到闸前。
枚举漏一个,闸就漏一条渠道。LinkedIn engine.js 就是这么漏了 50 天。
icp_v2_reclass 2026-09-21 06:02Z(3.5 小时)、leadgen_summary 2026-09-20 19:10Z(14.4 小时),promote_raw 停在 2026-09-16 16:55Z(112.6 小时)2026-09-21 17:3x 实查 · 都在跑,停的是供给不是步骤结论:加工段在转,promote_raw 也在转 —— 它「112 小时没产出」不是故障。今天 14:00:09 实跑、3 秒跑完(daily_leadgen.out.log 有 开始任务: promote_raw 与 ✅ promote_raw 成功 (attempt 1, 3s)),把近 5 天唯一那行待处理 raw_leads 判成 junk no_name: 1 ⇒ 它没有 promoted 事件可写,视图里自然一直停在 9/16。
⚠️ 我中午把这条归错了桶:当时只看到「有 1 行 new + 上次产出在 4.5 天前」就判它是步骤级故障。这两件事推不出「那一步没被调起」 —— 必须去当轮日志里确认那一步有没有被调起。现已改判为「无事可做」,与 website_backfill 同类,和「有事做不了」(配额停供的 tavily / cra_ncr)相反。
建议:判据落在产出上,不是「进程起没起」—— 但反过来也成立:产出为 0 也不等于步骤没起,要两边都看。09:30 的 pipeline_stale_alert 今天实报三条红(cra_ncr_scrape 12.8 天 / tavily_discovery 11.8 天 / promote_raw 4.4 天),三条都不是步骤故障:前两条是配额停供到 10/1,第三条是没有合格输入。
建议:判据落在产出上,不是「进程起没起」。已建 v_cron_last_success(不限窗口取 MAX)+ 独立 launchd 告警。
| 步骤 | 上次真正产出 | 距今 |
|---|---|---|
icp_v2_reclass(近 24 小时 4 / 近 7 天 55) | 2026-09-21 06:02Z | 3.5 小时 ✅ |
leadgen_summary(近 7 天 399 个事件) | 2026-09-20 19:10Z | 14.4 小时 ✅ |
promote_raw(近 7 天 373) | 2026-09-16 16:55Z | 112.6 小时 ✅ 不是故障:今天 14:00:09 实跑 3 秒成功,但近 5 天唯一输入被判 junk no_name ⇒ 无 promoted 事件可写。归「无事可做」,与 website_backfill 同类 |
phone_backfill(近 7 天 12) | 2026-09-14 07:28Z | 6.9 天 |
kp_finder(近 7 天 0) | 2026-09-09 06:15Z | 11.9 天 |
tavily_discovery(Tavily 配额 95% 停用至 10/1) | 2026-09-09 06:01Z | 11.9 天 🔴 |
cra_ncr_scrape(与 tavily 共用同一把 key,同因停用) | 2026-09-08 06:58Z | 12.9 天 🔴 |
kp_supplement(US SOS,不在本机) | 2026-09-01 08:09Z | 19.8 天 |
email_enrich | 2026-06-25 05:43Z | 87.9 天 |
gmaps_scrape(2026-05-25 停用) | 2026-05-22 06:02Z | 121.9 天 |
website_backfill | 2026-05-08 02:04Z | 136.1 天 候选池 0 ⇒ 告警侧按「无事可做」豁免、不计超期(promote_raw 本版实查同属此类;真正「有事做不了」的是配额停供的 tavily_discovery / cra_ncr_scrape)。规则见 pipeline_stale_alert.py:池 SQL 与脚本候选谓词同口径,池非空 / 查不到照红 |
customer_match / pos_reseller_verify | 2026-04-20 / 04-16 | 153.8 / 157.6 天 |
leadgen_alert / linkedin_verify | 从未 | — 两个埋点一次都没产出过,last_success_at 为 NULL ⇒ 它们不会「变红」,因为从来没绿过 |
原因:「跑了」≠「产出了」 —— 8/31 那次跑完了每一步,但 cra_ncr +0、pos_reseller empty directory、phone_backfill 三次 serpapi 超时 ⇒ 净产出 0。
🔴 告警装在被跳过的那段里面:daily_leadgen.sh:47 governor 不过就 exit 0,而 leadgen_alert 在第 320 行 —— 流水线越是没跑,告警越不会响。且 check 的输出被 >/dev/null 2>&1 丢掉,连是哪一项资源都不知道。
⚠️ 9/9 10:40 实测(df -g / sysctl vm.swapusage / vm_stat free+inactive):disk 剩 43 G / swap 已用 369 M / mem 30% ⇒ 卡的是白天那两个时刻的内存,而一天只有两次机会。已改成 03/04/05 三次候选,9/3 起每天都有一次过闸。
结论:9/2 时 v_cron_health 有 3 个信号指错了表、2 个没有发射方;migration 084 + 补埋点后,v_cron_last_success 里 tavily_discovery(近 7 天 17 事件)、kp_supplement(9/1)、kp_found(近 7 天 5 事件)、phone_validated(近 7 天 95 事件)都已变绿;icp_v2_reclass 上午还红(最后一个 icp_passed 7/30),14:43 HKT 那轮判出 1 家后也变绿了。
建议:5 项按「下次成功跑完应变绿」的判据曾全部兑现;9/10 删掉 qa_perf 测试行后 website_backfill 回到真实值(最后一次 2026-05-08,125 天),stale-alert 09:30 重新变红 —— 判据对,数据此前是假绿;9/10 21:2x 起对「候选池为 0」的步骤不计超期(永远红 = 不携带信息),池一有活它就得产出、否则照红。icp_v2_reclass 的问题不是通过率:近 30 天 1,767 个 disqualified 事件绝大多数是同 7 家 unknown 公司被每天 8 遍反复判(9/9 深夜已改成判完不变不写、同轮不重判,见 §01 块 ②);新供给不经此步,加工段主线是入库定类的质量(§05 难点 05 的 40% 误判)与桥 RPC 无人调度(视图里现成 92 人)。
| 步骤 | 视图查的 | 实际写的 |
|---|---|---|
tavily_discovery | raw_leads → 0 | company_leads 256(9/9) |
kp_supplement | raw_leads source LIKE 'sos%' → 0 | lead_contacts 331 |
icp_v2_reclass | meta.reclass_source → 0 | stage_name='icp_passed' 3,137(探针级联删除后;7/30 之后的第 1 个是 9/9 06:43Z) |
kp_found | ✅ 已有发射方:9/2 补埋点,9/8 06:14Z 写出 3 个事件(9/2 前只有一次性回填脚本在 2026-04-24 写过一次) | |
phone_validated | ✅ 同上:近 7 天 83 个事件(最近 2026-09-08 07:58Z) | |
原因:一个永远红的监控和一个永远绿的一样不携带信息 —— 这就是它建好之后没人读的原因。唯一的消费方 cron_health_check.py 在本机没有任何调度。
结论:company_leads 近 30 天(≥ 8/10)新增 105 行,其中 62 行曾是测试数据(9/1 写入的 qa_perf,9/9 23:22 已删;rls_audit 探针 601 行已于 9/2 删除,30 天内 0 新增),真线索 43 条。存量测试垃圾现为 0 行;此前 website_backfill 近 7 天 801 个事件全落在那 62 行上,已随行级联删除。
建议:qa_perf 存量已清、085 约束已 VALIDATE(对全表生效)。rls_audit 待 Graham 定。
原因:🔴 不能用约束挡 rls_audit —— 那 108 行来自 RLS 审计的 INSERT 探针(故意插一行验 RLS 拦不拦得住)。挡了它,探针会因「约束」失败,而那个失败长得和「RLS 生效了」一模一样 —— 等于用数据卫生把一个安全控制变成假绿。它的正确修法是修它自己的 cleanup。
⚠️ NOT VALID 期间「约束存在 ⇒ 数据干净」是错的推论:存量 62 行曾在,9/9 23:22 清完后已 VALIDATE(migration 086)。
🚪 闸该落在哪:company_leads 的写入口,不是绿线 promote_raw 上(9/2 实查定的)。
实查(9/9 17:16):promote_raw 近 30 天 promoted 26 条(最后一次 2026-09-08 12:00Z),同期 disqualified 事件 1,767(事件数;绝大多数是同 7 家 unknown 公司被反复判,见 §01 块 ②)——它在跑,放行率仍低;而 company_leads 近 30 天新增 105 家里 79 家(75%)from_raw_lead_id IS NULL(近 90 天 227 里 146)。
⇒ 把闸挂在绿线上只管得住近 30 天入口的 25%,另外 75% 照样从旁边走过去——正是本页反复说的那个形状。
排序:重要 > 高产出 > 紧急。原来的 P0 / P1 / P2 三档已合并成这一张表 —— 分档曾经掩盖了一件事:三档里真正「不需要任何人做错事就会持续出错」的只有一条。
本表 2026-09-21 逐条复核:原 17 条里 7 条已解或判据本身就错(不再列出,只在 §02 架构图里标状态),2 条改判为「不要做」,仍成立的 8 条列在下面。2026-09-22 增补:新增 3 条(T1 供给余粮红线 / 批次 → 待发四段人工 / A4 四轮外审未合),A6 行按 v3 外审结果更新,4 条 ✅ 行补上今天的验证结果;顺序按 Graham 9/22 拍板重排:供给连续性 > 批次→待发自动化 + Apollo 拉新 > A4 收尾 > A6 记账。2026-09-23 增补:新增第 2 条 CRM 客户排除红线(应恒 0);原第 5 条约会冻结改 ✅(日历同步上线);其余顺延。
⚠️ 复核方式是查「触发条件现在成不成立」,不只是「问题还在不在」—— 上一版整整挂了 5 天没复核,期间有一条是自己好的。
| # | 阻碍项 | 为什么排在这 | 最小动作 · 实测依据 |
|---|---|---|---|
| ✅ | 原第 1 条「swap 5.93G > 4G,14:00 会被拦」已修 openclaw 0eeb51af / 66e4b7a1 · 2026-09-22 03:16 实测放行 · 外审 2 家出票(Codex 撞限至 9/26) |
拦的不是资源,是判据:macOS 的 vm.swapusage used 是高水位不是活压力(换出的页不主动换回),16G 机 swap 6.0G 而 memory_pressure 空闲 52%。governor 改为 swap 超阈须有「内存空闲 < 30%」佐证才拦(读不到 / 非法值按无法佐证拦,fail-closed 保留;GOV_SWAP_CORROBORATE_MEM_PCT=101 恢复旧行为)。14:00 流水线直接跑工作树 ⇒ 改动即生效,无需部署。 |
plist 环境下实跑 runtime_governor check:02:52 PAUSE → 03:28 OK(同一台机、swap 5.84G、内存空闲 50%,预警行「判为历史高水位,不拦」)。selftest +10 向量;变异(去掉佐证条件 / 去掉百分比校验)分别红 2 / 3 条。swap 本身不会降: top -o cmprs 大户是 com.apple.Virtualization 1.6G、Mail 0.9G、WeChat 0.8G、Chrome / Notion / Claude 各 0.4–0.6G —— 全是常驻 app(B 组,Graham 定)。掉速(9/21 19:23 → 9/22 02:43 掉 15G)仍待查,与闸无关。✅ 9/22 已验证: daily_leadgen 14:00:09 开始任务(未被 governor 拦)、14:23:22 结束 9 passed / 0 failed;scripts/verify_checkpoints_20260922.py 21:04 判 14:00 PASS。 |
| ✅ | 原第 2 条「util.cold_sender 每轮 4 次 ModuleNotFoundError」已修并部署openclaw 66e4b7a1 · 03:29 deploy.sh VERIFIED · DEPLOYED_VERSION 同步 |
本版更正口径:它不是「持续造成功能损失的活 bug」。模块是 7e8052ae「删零消费者模块」时删的(漏了这处延迟 import),import 失败后的 fallback 与模块存在时结果相同 —— 10 个冷发箱本就没有任何凭据来源。64 人回信检不到是冷发域 9/15 停产的既定代价,由 09:00 Mac Mail 本地索引扫描覆盖,与本条无关。 |
改动 = 删掉那个 import、avail = {},逐箱「无 appPassword」行与 LAST_SCAN_HEALTH 对账照旧;发送器 255 个用例绿。顺带落了 A7:隔离清单来源进日志(quarantine: source=primary (N 个邮箱),故意不带 quarantine[ 前缀,观测清单从「无 quarantine[ 行」反证改为正证)。✅ 9/22 已验证(20:14 重跑轮,跑的是 66e4b7a1):run.log 全轮 0 行 cold_sender(A2);quarantine: source=primary (3 个邮箱) 自 20:17:19 起每次读清单都有(全轮 25 次,quarantine[ 0 行,A7 正证)。⚠️ 今晚跑的不再是 21:53 的 ef3039a2 —— 对崩溃修复的验证仍成立(两次改动都没碰发送循环),归因时要记住这一点。 |
| ✅ | 原第 1 条「发送那一刻不重判状态」已落地 原 P0-7 · 2026-09-21 21:53 部署 |
已从本表移除。但尚未经过一次完整验证 —— 部署发生在 9/21 那轮崩溃之后,第一个真验证点是 9/22 20:00。 | 逐封循环里的判断已扩到 replied/bounced/已约会,并在循环中途定期重读名单。部署副本 ~/.hermes/state/iso_outreach/run.py 已核 VERIFIED。🔴 验收判据:9/22 20:00 那轮要跑完(有日报产出)。9/21 那轮发到 21:46:05 后抛 ERR_CONNECTION_RESET、计划 82 实发 49;修的就是那处裸 send_compose。9/22 实况:20:00:30 那次启动崩在浏览器可执行文件(与发送循环无关,0 封;栈在 cron.out ⇒ 「cron.out 无 Traceback」这一条今晚对重跑轮不携带信息);20:14:37 重跑;20:46–20:53 网络抖动,FOLLOWUP-WEB-FAIL 四次(ERR_CONNECTION_RESET)后都继续发了下一封 —— 这处修复第一次被真网络验证。✅ 跑完:22:50:27 日报行,实发 66(T1 29 / T2 12 / T3 25),失败 5 = 网络 4 + T1 未发 1;重跑段自己的 Traceback = 0(verify 脚本 22:53 判 PASS)。 |
| ✅ | 原第 2 条「补货没有排程」已落地 原 P1-1 + 接缝 · 2026-09-21 夜 |
已从本表移除。挡在前面的性能问题与排程本身,两件都做完了。 | 性能:上一版记「适配器逐行 ≈8 分钟」。S5b 分块 36.4×(197s → 5.0s)、S5 抑制分块 32×(749 ms/行 × 210 → 4.8s)⇒ 端到端 dry-run ~8 分钟 → 26.1 秒。正确性与独立地面真值逐键比对 3 轮 210 键 0 不符。 排程: com.openclaw.supply-stage 周一至五 16:30,launchctl print 已确认进内核。✅ 9/22 已验证:16:30:05 首次真触发(磁盘 28G 闸过)、16:30:34 出批次 2026-09-22T16-30HKT-90bef4d7(29s),全集 1,234 → 候选 193。但排程只到批次为止,批次 → 待发仍是四段人工,见下方第 3 条。 |
| 1 | 🔴 T1 供给余粮红线(新增,可证伪) Graham 2026-09-22 17:5x 拍板:「要保证系统的供给不能断,持续有邮件外发 / 跟进出去」 |
供给一断,发送段整段空转 —— 9/17–9/20 已发生过一次(余粮只剩 1 人、空转两天)。后果最直接、且每个工作日都在消耗,所以排第 1。 | 判据:tracker status='queued' 且三个 tN.sent_at 全 NULL ÷ 每轮 T1 上限 30,发送器只跑工作日 ⇒ < 5 个发送日(< 150 人)即红。现值 203(2026-09-23 16:10 实查;16:08–16:09 已导入并放行 9/22 批次准入的 9 人,之前 194)= 6.8 个;此后每个工作日 −30(9/23 → 173),不补货则 9/24 那轮之后(≈143)跌破。杠杆:这批候选 193 人里 159 人是 catch_all(82%),一批只出 9 个 T1 ⇒ T1 主杠杆是 Apollo —— 本周期 2,500 credit 未动(21:07 实读)、2026-10-16 23:04 HKT 到期,Graham 定:由 Claude 看着花、到期前用掉、只拉合格质量(搜索期 has_email ⇒ reveal 命中 99/100)。catch_all 储备 532 行 / 370 个邮箱( email_verifications,2026-08-20 起,21:04 连真库)单独保存、现在不放,供给不够时再从里面筛。 |
| 2 | 🔴 CRM 付款 / 近期拒绝客户能被发出去的人数 = 0(新增红线,应恒 0) Graham 2026-09-23 拍板:付款客户永久排除 · 明确拒绝 6 个月不碰 · 其它可发 |
发错一封给付款客户或刚拒绝的人,损失的是关系不是配额;而它今天真的发生了 —— 明确拒绝(4/16)的客户排在 T1、另一家已到 T2,付款客户的同事在库队列。 | 判据:抑制表里 campaign 为 crm 的邮箱 ∩(tracker 待发 / 在途 ∪ 库侧 queued)里未被抑制表覆盖的人数 = 0。本版实查(9/23 11:31):53 个 crm 邮箱(付款 49 + 付款域 1 + 拒绝至 2026-10-13 3)∩ tracker = 待发 1 + 在途 1(另 1 人已回信),∩ 库队列 = 4 —— 交集 6 人全部已被 email_suppression(33 → 86 行)压住,今晚 20:00 起生效;现值 0 是靠抑制表,不是靠源头。根因:客户匹配只按 website;S5b 只看 company_leads.caller_stage,不读客户表。最小动作:S5b 直接读客户表(付款 / 拒绝日期),并把每晚发送前的这个交集做成闸。 |
| 3 | 🟠 批次 → 待发仍是四段人工(+ Apollo 拉新接同一入口) 原「补货没有排程」的后半段 · 2026-09-22 首次真触发后显形 |
排程只自动化了前半段(库 → 批次);后半段每次都要人。第 1 条那条红线要靠它才守得住 —— 本表产出最高的一条。 | 今天的四段:16:30:34 出批次 → 人看数字(--recheck)→ 17:45 MillionVerifier 验 187 条(ok 17 / catch_all 153 / invalid 10 / unknown 7;扣 27 credit,9,595 → 9,568,21:05 实读 9,567)→ 17:52:40 finalize 准入 9(拒 catch_all 159 / invalid 10 / unknown 7 / 每家 2 人超额 8)→ 导入 tracker(held)再释放,排到明天 10:00–18:00(批次包 apply_state = prepared,22:53 tracker held 仍 66)。最小动作:把四段串成一条,验证扣费加上限与余额闸;Apollo 拉新接到同一入口(搜索免费,reveal 只对 has_email 的人)。 顺带(A5):「阻断名单为空时 fail-open」的探针方案 v1 三家否决(探针方向反了);事实清查有用 —— 从公司表拉阻断名单的只有 S5b 一处;两张线索表对匿名键仍有表级授权(无策略、返回零行)⇒ 收紧属 B 组(Graham)。 |
| 4 | 🟡 回信落库 seen / persist 次序(A4)—— 四轮外审未合 分支 fix/a4-sink-seen-order · 本地 HEAD a457cc8f;远端 a457cc8f(r2–r4 已推,与本地同) |
每轮「有条件合并」且每轮抓到新的真缺口(r1 DeepSeek + 千问 / r2 Codex + 千问 / r3 Codex + 千问 / r4 三家),三家都点名复杂度 ⇒ 今晚不合。不合不丢数据(09:00 链现状不变),所以排在供给之后。 | r4 已做:唯一副本永不删 / 路径类型与别名校验 / 死信读上限 / 隔离件 0600 / 持锁阶段异常也 spool / drain 认隔离件。 最小动作:按 r5 清单(接续文档 §1.0)收口,合并前 r5 外审 ≥ 2 家放行。 |
| 5 | 🟡 发送侧不回流(A6)—— v2、v3 各一轮外审,三家都不放行 原 P2-1 · 停在 v3,v4 必改清单见接续文档 §2 |
两份发信证据互不包含,导致库侧「从没联系过」是假的。不修,任何基于库侧状态的放行都可能重复打扰。排在 A4 之后:它是记账,不是丢数据。 | 已触达:队列侧 842 ∪ 库侧 702 = 864,仅队列侧 162 / 仅库侧 22(22:53 现算;今晚 T1 29 人全落在「仅队列侧」—— 库侧对他们仍是 queued)。根因未动:发送器对账本表 grep 0 命中,队列 JSON 仍是唯一名单。 v4 必改(r3 三家 P0):回滚证据链要在库里;dry-run 不许写发送账本; run_id 竞态;回滚不能把真发过的人置回待发(置 NULL 会让他们重新进队列)。 |
| ✅ | 原第 5 条「约会/开会数据冻结 28 天」已解冻 原 P0-6 + P2-2 合并 · 2026-09-23 日历 → CRM 同步上线 |
已从阻碍项移除:max(appointment_at) 2026-08-25 13:30Z → 2026-09-22 02:00Z(11:28 实查);写入方从「一个都没有」变成 launchd com.orderpin.gcal-sync 每天 10:00(只读 OAuth)。 |
口径:日历为准,同步脚本 --apply 改 1 行;日历有会、CRM 无行的外部与会者补 28 人(lead_source='calendar',contacted / done,不进队列;meeting_held 16 / appointment_scheduled 12)⇒ 「已开会」卡 5 → 21、「已触达(B)」388 → 416。⚠️ 仍未做:会议纪要判读第二轮写 lead_status 0 行生效(优先级函数判 calendar 的 meeting_held 高于 llm 的 interested,全部落在 status_conflict),优先级待 Graham 拍板。 |
| 6 | ✅ 已解 · 加工段取数不是一个划分 原 P1-5 · 开关 9/21 接上,9/22 首次真跑 |
缺口在缩小,不是变大:9/21 基线 76 → 9/22 那轮后 65 → 9/23 那轮后 54(本条口径「有官网 ∧ 无摘要 ∧ 非高档」= 53,9/23 16:05 连真库复算)。上一版写的「在变大 · 39 → 73」是 9/21 的数,已作废。 | 三家取数仍各取一段(没官网 / 高档 / 已有摘要),但缺的那一段已经有人取了:14:00 流水线里 website_backfill 那行现在带产摘要开关,不再是裸调用;「必须同时指定 id 清单」的约束由脚本内两道闸取代 —— 只取有官网的行、每轮上限 15 行(9/23 14:11 那轮:扫 15 行、写入 11 条、抓空 4)。剩余动作:无 —— 按每轮约 11 条,53 行约 5 个工作日自动清零;届时该口径应到 0,到不了才需要再看。 |
| 7 | 🟠 19 个写方只有 3 个走统一去重 原 P1-3 |
人数没变但成分变了:停用的那个退出、Apollo 那条新腿接进来了。它是第 8 条的前置 —— 不先做,接任何新线索源都会加重它。 | 线索总表 19 个写方,真调统一去重模块的 3 个。有个陷阱:外部源的入库层只在注释里声明「这里用不了去重模块」,那是明确不接入、不是漏接。 最小动作:只改两个在生产真跑的写方( cra_ncr_scrape / iso_disclosure_finder);其余 14 个是停用 / 迁移 / PATCH 路径,可后置。 |
| 8 | 🟡 一列承载两个状态机 原 P2-3 |
没有新增伤害,但每次读这一列都要记得「按来源二次判别」—— 靠人记得的约束迟早出事。reflow 从 10 涨到 29。 |
四个取值 100% 只出现在 LinkedIn 来源,非 LinkedIn 一行都没有:dead 84 · qualification 73 · reflow 29 · paused 10(23:00 实查;dead +2 是今晚 LinkedIn 状态机自己的动作)。 最小动作(零代码):给这四个取值加一条库层约束,或建一个只读视图,把「必须按来源二次判别」从人的记忆变成库的保证。 |
| 9 | 🟡 孤儿子系统未清 原 P2-5 |
纯技术债,不产生错误行为。列在这里只为不让它悄悄长大。 | ✅ 已解一组:根目录那 8 个 JS/sh 连同死 cron 目录已删干净。 仍在:公司级配额闸 5 个文件零 runtime caller(唯一引用是另一处的一句注释)—— 「零 runtime caller」≠「可直接 git rm」:本页只登记事实,删不删属 Graham(B 组);去重审计表仍有写方、全仓零读方。 🔴 「审计战役 15 个脚本」这条判据不可复核:原文没给清单,今天「15」对不上任何一个自然分组。最小动作是先补清单 —— 没有清单就没有可证伪的完成判据。 |
| 原条目 | 为什么不做 |
|---|---|
| 接回 8 个外部线索源 原 P2-4,曾被列为「上游唯一的现成解」 |
现在接会先加重第 5 条。这 8 个源写的是线索总表(不是绕过入口,这点是好消息),但它们都不走统一去重。 另:原文的分类也不对 —— 不是「协会 3 + 展会 3 + 招聘 1 + 新闻 1 = 8 个没 runner」,实际是 7 个连 runner 都没有 + 4 个有 runner 但没人调,招聘和新闻属于后者。 正确顺序:先做第 5 条,把这 4 个 runner 的入库改走去重,两件事合并成一次改动。 |
| 抢修那个绕过入口的发现脚本 原 P0-2 |
结构问题仍在(它确实直写公司表、不经统一晋升),但触发条件不成立:挡它的第一层是 14:00 脚本里硬编码的默认跳过,不随月份变,三处配置都没人把它打开;关它的理由是「净产出 0」,不是配额。 ⚠️ 上一版写的「10/1 配额恢复是这个洞重开的必要条件」是错的,已作废 —— 配额只是第二层闸。 |