From a36fcbccc7d5b6835db487a7f9a1cdeb84800b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Thu, 8 Oct 2026 16:36:35 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=AE=A1=E5=88=92=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E2=80=94=E2=80=94no=5Fip=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=BD=92=E5=B1=9E/grep=E5=85=A8=E9=87=8F=E6=94=B9=E5=86=99?= =?UTF-8?q?=E5=90=AB:7:56=E9=94=9A/canon=E5=8F=A3=E5=BE=84=E9=92=89?= =?UTF-8?q?=E6=AD=BB/=E9=97=A8=E6=8E=A7=E6=94=B9=E7=BA=BF=E7=82=B9?= =?UTF-8?q?=E5=90=8D/cc=5Fsettled=E8=AF=AD=E4=B9=89/=E9=9B=86=E6=88=90?= =?UTF-8?q?=E8=A1=A5=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Code --- .../plans/2026-10-08-cc-completion.md | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/plans/2026-10-08-cc-completion.md b/docs/superpowers/plans/2026-10-08-cc-completion.md index acf1dfb..e22310c 100644 --- a/docs/superpowers/plans/2026-10-08-cc-completion.md +++ b/docs/superpowers/plans/2026-10-08-cc-completion.md @@ -72,8 +72,9 @@ def test_format_intl(): ... # e164→分组展示 "+254 712 345 678 - `classify(number, ip_iso) -> (kind, cc_dict)`:四分支判定树(b 分支=剥 IP 国码前缀(`country_code_for_region`)+ 剩余段 `parse(num, region)+is_valid_number` 严格校验;c=`parse` IP 国合法;d=naive 去前导0+IP 码;e=无建议国) - `NAME_TO_REGION`、`format_intl(e164)`(phonenumbers `format_number(International)`) - `transit(cc_state, reply, new_canon)`:状态机纯函数(affirm→ip_confirm 落定;country 重算再回显 attempts+1;canon 变化→重置;attempts≥2→source=fallback 落定;无 reply→attempts+1) - - `cc_due(cc_state)`:等待态判定(reminder 消费条件) - - `cc_settled(cc_state)`:落定判定(邮箱轻补解锁条件,spec §4 统一口径) + - `cc_due(cc_state)`:等待态判定(reminder 消费条件);**None(无 `_cc`,号本就带 +/00)→ 非等待**(邮箱轻补不回归) + - `cc_settled(cc_state)`:落定判定(邮箱轻补解锁条件,spec §4 统一口径);**None → True** + - 测试矩阵点名两条易漏转移(评审补):国名重述不重置 attempts;no_ip 上限 1 轮 - [ ] **Step 4: 跑绿矩阵** → **Step 5: 全量绿 + commit** `feat: cc_completion判定树+状态机纯函数` --- @@ -87,7 +88,8 @@ def test_format_intl(): ... # e164→分组展示 "+254 712 345 678 - [ ] **Step 1: 轮前钩子**(spec §6-1):即时扫描建 effective_raw 后**同步跑判定树**——裸号且无 `_cc`(或 canon 变化)→ 建 `_cc`(仅 whatsapp 组确认流;phone 组 ip_proposed 静默)→ 与一次性计数写回同事务落库。`_contact_completion_note` 的 cc 分支删除(其 email 分支保留),cc 提醒改由本钩子产出(Task 4 接) - [ ] **Step 2: 轮末钩子**(spec §6-2):四层合并后、D1 邮件前——消费 `cc_reply`(仅 `cc_due` 等待态,双门控 Python 侧)→ `transit` 状态更新落库;**剥离 cc_reply**(瞬态);**丢弃 extractor 回传的任何 `_` 前缀键**(出口卫生 3) - [ ] **Step 3: 存量迁移**(spec §4 尾):读到旧 `_cc_asked=True` 且号码裸 → 一次性改写为 `_cc{confirmed:false, source:fallback}`(不追问直通轻补) -- [ ] **Step 4: 集成测试**(FakeAI 流程):裸号轮当轮 `_cc` 已建(轮前钩子);cc_reply affirm→落定;canon 换号→重置重走;attempts 耗尽→fallback;出口无 `_` 残留/cc_reply 剥离;旧 `_cc_asked` 会话不重复问 +- [ ] **Step 3b(评审补)**:计数写回块(:263-283 `if completion_marks:`)条件扩为"计数或 `_cc` 新建任一存在";轮前钩子**在 `_build_context_reminder`(:258)之前**执行(写明顺序) +- [ ] **Step 4: 集成测试**(FakeAI 流程):裸号轮当轮 `_cc` 已建(轮前钩子);cc_reply affirm→落定;canon 换号→重置重走;attempts 耗尽→fallback;出口无 `_` 残留/cc_reply 剥离;旧 `_cc_asked` 会话不重复问;**非等待态收到 cc_reply → Python 侧忽略**(双门控确定性半边);**canon 组归并**(phone/whatsapp 同号确认一次、异号仅 whatsapp 走确认流——管道侧逻辑) - [ ] **Step 5: 全量绿(既有 CC 相关断言按拆除清单同步迁移)+ commit** `feat: 判定树轮前接入+cc_reply消费+出口卫生+存量迁移` --- @@ -102,6 +104,14 @@ def test_format_intl(): ... # e164→分组展示 "+254 712 345 678 - [ ] **Step 2: 实现**: - `no_contact_value(sentence, allow_number=None)`:逐 `LONG_NUMBER_RE` 匹配段 digits_only 归一比对,**全部段**命中 allow_number 才放行该句(混入异号照拦) - 新模板 `_CC_ECHO_EN/_ZH`("…reach you at {intl} — is that right?" 中英,**与 reminder/墙/断言三方同源**——沿用 `_CC_ASK_*` 拼装式结构改造) + - **no_ip 路径专属(评审补)**:IP 无效无可回显——保留一条 ask 形态模板 + (`_CC_ASK_*` 原句保留不拆除,服务 no_ip 轮"方便发带区号完整号吗"1 轮为限); + 该类轮墙裁决锚 = 问句短语("full number with country code"/"带国家代码")在场, + 与 e164 在场锚并列;补一条 no_ip 管道测试(防静默失能) + - **三处门控改线(评审补)**:旧 `completion_marks == ["_cc_asked"]` 触发点 + (cc_wall :304 / 让位句 :805-814 / cc 提醒注入 :837)全部改线到 `cc_due`; + conversation :755/:802-824 三处 Python 注入提醒里的"可请客户重发完整号一次" + 短语同步收敛为回显语义(防同场竞争降低首过命中率) - reminder:`cc_due` 时注入回显句(intl 由 Python 算好,不让 GLM 拼号);确认句墙(缓冲)裁决词从 "country code" 改为注入 e164 在场;conversation 墙区调用传 `allow_number=等待态的 e164` - 让位句改写(4b-3):"回复中绝不写出号码数字——**唯一例外是系统提供的补全号原文(逐字)**" - [ ] **Step 3: 跑绿 + 全量绿 + commit** `feat: 回显确认模板+确认句墙e164检测+白名单逐段放行` @@ -115,7 +125,13 @@ def test_format_intl(): ... # e164→分组展示 "+254 712 345 678 - Test: `tests/test_system_prompt_dual_contact.py`、`tests/test_extractor_evaluator_prompts.py` - [ ] **Step 1: 失败断言**(新语义):五处例外句含"回显补全后的完整号码";好差示例含回显组+自编号差例;extractor.md 含 cc_reply 字段说明与双门控声明 -- [ ] **Step 2: 改 system.md**(4b-1/2):五处禁令例外句(:59/:175/:223/:229/引导策略节,行号先 grep 核实)改"回显确认"语义;好差示例两改一增(裸号组改回显形态;增"AI 自编号码"差例) +- [ ] **Step 2: 改 system.md**(4b-1/2,评审修正——**grep 全量改写而非固定清单**): + grep "重发完整号/号码缺国家代码" 的**全部命中处**(实测 :7/:59/:175/:223/:229 + + 引导策略节 :198-200 + 好差示例 :162-166)改"回显确认"语义;**特别两处高权重锚**: + ① :7 语言规则模板句清单成员(旧追问句→回显确认句);② **:56 红线"绝不能在回复里 + 写出号码"加例外"唯一例外=系统提供的补全号原文(逐字)"**——不改则 GLM 拒写号、 + 墙轮轮替换(锚点竞争教训);好差示例两改一增(裸号组改回显形态;增"AI 自编号码"差例)。 + Step 1 断言按 **grep 命中计数**而非固定五处 - [ ] **Step 3: 改 extractor.md**(4b/§2 双门控):加 `cc_reply` 可选字段(`{"affirm": true}` / `{"affirm": false, "country": "..."}`)+ "仅当客户在回应号码确认时填写" - [ ] **Step 4: 断言全量迁移**(test_system_prompt_dual_contact 四断言按新语义重写;同源断言锚 `_CC_ECHO_*` 正文) - [ ] **Step 5: 全量绿 + commit** `feat: 提示词回显确认语义+extractor cc_reply字段+断言迁移` @@ -128,8 +144,8 @@ def test_format_intl(): ... # e164→分组展示 "+254 712 345 678 - Modify: `app/services/email_service.py`、`app/services/lead_push_service.py`、`app/services/conversation.py`(ev.contact_info 尾注 + 邮箱轻补条件) - Test: `tests/test_email_rendering.py`、`tests/test_lead_push_service.py` -- [ ] **Step 1: 失败测试**:首封渲染 e164+`(区号按 IP 推测,未经客户确认)`(confirmed=false 时);prefix_normalized **无**标注;主题行 e164 无标注;no_ip 裸号+`(缺国家区号)`;确认后(号码未变)**不补发**;换号走现有更正;push contact 纯 e164 + profile 含派生标注键;`_` 键过滤前消费 -- [ ] **Step 2: 实现**:email_service 渲染 `_cc`(正文/主题/更正/回头客,签名加参);lead_push `profile_out` 先消费 `_cc`(contact 用 e164、标注进 `号码补全说明` 派生键)再过滤 `_`;`ev.contact_info` 等待态尾注;`_contact_completion_note` 的 email 分支解锁条件改 `cc_settled` +- [ ] **Step 1: 失败测试**:首封渲染 e164+`(区号按 IP 推测,未经客户确认)`(confirmed=false 时);prefix_normalized **无**标注;主题行 e164 无标注;no_ip 裸号+`(缺国家区号)`;确认后(号码未变)**不补发**;换号走现有更正;push contact 纯 e164 + profile 含派生标注键;`_` 键过滤前消费;**跨会话 24h 去重(评审补)**——同客户新会话再留同一裸号,canon 对比集须并入 `_cc.e164` 的 canon,回访轻提醒不退化为全量询盘 +- [ ] **Step 2: 实现**:email_service 渲染 `_cc`(正文/主题/更正/回头客,签名加参);lead_push `profile_out` 先消费 `_cc`(contact 用 e164、标注进 `号码补全说明` 派生键)再过滤 `_`;`ev.contact_info` 等待态尾注;`_contact_completion_note` 的 email 分支解锁条件改 `cc_settled`;**canon 比对口径钉死(评审补)**:`ev.contact_info` 存裸号原文+尾注、e164 走派生,且同会话更正判定(:635 old_canons)与跨会话去重集(:577-591)**并入 `_cc.e164` 的 canon**——防 e164 替换本体造成"每轮误判换号→更正连发"与"回访退化" - [ ] **Step 3: 跑绿 + 全量绿 + commit** `feat: 出站补全渲染——首封e164+标注/主题行/推送派生/面板尾注` ---