feat: 判定树轮前接入+cc_reply消费+出口卫生+存量迁移

Task 3(cc-completion 计划最重集成项):
- 轮前钩子 _cc_pre_turn: effective_raw 建成后、reminder 之前跑判定树,
  建/重置/迁移 _cc(同 canon 保留状态,canon 变化即 RESET 重走);
  与一次性计数写回同事务落库(条件扩为计数或 _cc 变更任一存在)
- 轮末钩子 _cc_round_end: 四层联系方式合并后、D1 邮件前——双门控消费
  cc_reply(仅 whatsapp 等待态;落定态仅开迟到 country 升级口,no_ip
  耗除外),canon 变化 RESET,末次联系方式补建 pass
- 出口卫生三封堵: cc_reply 消费后剥离/extractor 回传 _ 前缀键防御性
  丢弃/入口 existing_info 滤 _ 复核
- 存量迁移: 旧 _cc_asked=True+裸 whatsapp 无 _cc → 一次性 fallback 态
- _contact_completion_note cc 分支删除,邮箱轻补解锁条件改
  cc_settled(_cc.whatsapp);cc 墙门控改线 cc_due(_wa_cc)
- 集成实证修两处数据流 bug: WHATSAPP_CTX_RE 间隙吞 + 号(显式国际
  前缀被捕成裸号→误追问);同轮扫描合并方向反转(存量覆盖当轮新号,
  轮前 canon 变化检测失效——与轮末最新自述优先同语义对齐)
- 新增 10 项集成测试(affirm 确认/换号重走/迟到报国升级与忽略/
  卫生三封堵/存量迁移/confirmed 态忽略/同 canon 组归并/异号 phone
  静默/纯 phone 无墙),282 项全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-08 18:06:39 +08:00
parent c13585b4a6
commit 0b5c219090
3 changed files with 549 additions and 113 deletions
+6 -1
View File
@@ -106,8 +106,13 @@ EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
INTL_PHONE_RE = re.compile(r"\+\d{6,15}")
# 邻接绑定:上下文词与数字必须在同一匹配内(仅空白衔接)——禁止"消息任意位置
# 有上下文词 + 任意位置有 7 位数字"的消息级误绑(S1:单号/订单号/先令价格)
# 间隙字符类排除 "+"(2026-10-08 cc 判定树 Task 3 集成实证): 原 \D{0,12} 会把
# 客户显式写的 "+" 吞进间隙("whatsapp is +966…" 捕成裸 "966…"),下游
# cc_completion.classify 误判 NEED_CC 对已给全号的客户追问区号——"+" 是
# classify a 分支(显式国际前缀→HAS_CC)的唯一判据,必须在捕获里存活。
WHATSAPP_CTX_RE = re.compile(
r"(?:whats\s*app|wa\.?me|(?:^|\b)wa\s*[::])\D{0,12}(\+?\d[\d\s\-().]{5,17}\d)",
r"(?:whats\s*app|wa\.?me|(?:^|\b)wa\s*[::])[^+\d]{0,12}"
r"(\+?\d[\d\s\-().]{5,17}\d)",
re.IGNORECASE,
)
PHONE_CTX_RE = re.compile(