fix(rectification): equal-weight collect, year-cue questions, classifier no/unsure (BUG-641–643)

Ask finance and health like other domains, put year-cued collect questions first, and let the classifier distinguish decline vs skip. Skill 10.0.22.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-10 21:53:10 +08:00
co-authored by Cursor
parent 71eaeb2e8b
commit 52db714ba9
46 changed files with 1033 additions and 160 deletions
+51 -3
View File
@@ -8329,15 +8329,15 @@
- 状态:resolved
- 首次发现:2026-09-04
- 最近更新:2026-09-04
- 最近更新:2026-09-10
- 影响面:`collectionYearFields``spokenFollowupForUser``collect_method_evidence`
- 用户现象:家庭采集题写成「某年前后,家里如果有结婚、添丁或住院这类事,记得大概哪年就行。」既指定了年份又让用户报年份。
- 触发条件:家庭轮转把 dated 探针的 `year_label` 拼进 `USER_COLLECT_QUESTION.family`
- 根因:`68f0759e` 为 BUG-414/418「带年份的口语问、不出无年份分盘选择卡」把 dated 探针年份塞进采集口语。`USER_COLLECT_QUESTION.family` 本身以「记得大概哪年就行」结尾,拼在一起自相矛盾。本单只去年份前缀。家人拒答后若还有未问的财务/搬家/健康/职业采集,不得直接给结果——见 BUG-546(推翻本条原先「出采用卡不是缺陷」的收口)。
- 修复:采集口语不再拼「某年前后,」。`probe_year` / `semantic_key` 仍留给计分与去重。不出无年份分盘选择卡的半边保留。
- 验证:家庭采集口语等于 `USER_COLLECT_QUESTION.family`,同时 `probe_year > 0`。答完最后一道区分题后仍落家庭采集焦点,旁白不含探针年份。BUG-418 无年份分盘卡测试仍过。
- 防复发:`collect_method_evidence` 口语不得加年份前缀。不得为去前缀而丢掉 `probe_year` 或放回无年份分盘选择卡。
- 相关记录:BUG-414、BUG-418、BUG-546
- 防复发:采集口语不得既指定年份又说「记得大概哪年就行」。**口径被 BUG-642 改为带线索模板**:有 `probe_year` 时用「某年前后有没有…别的年份也行」;无线索模板仍用「记得大概哪年就行」。不得为去前缀而丢掉 `probe_year` 或放回无年份分盘选择卡抢在采集前面
- 相关记录:BUG-414、BUG-418、BUG-546、BUG-642
- 复发自:无
- 修复版本:待发布
@@ -9957,6 +9957,54 @@
- 复发自:无
- 修复版本:待发布
## BUG-641 | 财务与健康被写成「只有主动说才问」,服务器却会主动采集
- 状态:resolved
- 首次发现:2026-09-10
- 最近更新:2026-09-10
- 影响面:`skills/jyotish-birth-time-rectification/SKILL.md``conversation-strategy.md``scripts/rectification/event_probes.py`、Skill 10.0.22
- 用户现象:Skill 写财务/健康只有用户主动说才问,实际对话里服务器仍会问钱和身体;Python 采集探针又不给这两域年份线索。
- 触发条件:新校正走到方法覆盖采集;账本只有学业/感情时看 `evidence_collection_probes`
- 根因:三处口径各自为政。Skill L84 与 conversation-strategy 写 volunteer-onlyTS `DATED_COLLECT_ORDER` 自 BUG-462 起含 financePython `VOLUNTEER_ONLY` 把 finance / health_pressure 挡在 `missing_collection_domains``evidence_collection_probes` 外。
- 修复:Skill 10.0.22 改为财务、健康与其他领域同权,服务器按 `method_followup_plan.next_followup` 主动问。删除 `VOLUNTEER_ONLY``MAX_COLLECTION_PROBES` 3→7,避免学业+感情账本被前三个领域占满后发不出财务/健康。历史 10.0.21 包冻结,`resolveExactSkillPackage` 仍能打开。
- 验证:`tests/test_rectification_event_probes.py` 学业+感情账本含 finance 与 health_pressure`frontend/tests/skill-registry.test.ts` 10.0.21 精确解析;live SKILL.md 与 `versions/10.0.22` 逐字节相等。
- 防复发:现行 Skill / 10.0.22 不得再写「主动说才问」。不得把冻结历史包改写成新口径。不得把 `.workbuddy` 镜像当运行主仓。
- 相关记录:BUG-462、BUG-621、BUG-642
- 复发自:无
- 修复版本:待发布
## BUG-642 | 带年份线索的采集题被整句去前缀,无年份性格卡还能抢在采集前面
- 状态:resolved
- 首次发现:2026-09-10
- 最近更新:2026-09-10
- 影响面:`user-copy.ts``spokenFollowupForUser``nextDatedCollectFollowup`、方法覆盖链
- 用户现象:家人采集题号带 2021,题干却没有年份;同领域无年份性格卡可以抢在带线索采集题前面。
- 触发条件:`evidence_collection_probes` 给出 `age_band` 年份;同域还有 D12 等无年份对照。
- 根因:BUG-539 因「某年前后…记得大概哪年就行」自相矛盾而把年份前缀整句删掉。`sameDomainYearlessCard` 在感情/事业/家人未覆盖时优先于采集。
- 修复:采集题拆成无线索模板与带线索模板。有 `probe_year` 时写成「家里在 2021 年前后有没有…有就说个大概年月,别的年份也行。」不得同时出现「记得大概哪年就行」。未覆盖的感情/事业/家人先采集;`nextDatedCollectFollowup``DATED_COLLECT_ORDER` 内先排有年份线索的领域。带年月区分点选题仍在一切采集之前。
- 验证:`rectification-spoken-collect` / `rectification-eight-method` / `rectification-collect-stall`:家人 2021 采集口语含「2021 年前后」、不含「记得大概哪年就行」;感情/事业/家人未覆盖时 `next_followup` 是采集而不是无年份性格卡;existence 类 D12 仍记 `yearless_ungrounded_contrast`,没有单独的「拒答后出 D12 风格卡」用例。无 `probe_year` 用无线索模板。
- 防复发:有线索的采集口语必须带「某年前后」且允许别的年份。无线索模板不得带年份。不得让同域无年份性格卡抢在该域采集之前。
- 相关记录:BUG-539、BUG-418、BUG-629、BUG-641
- 复发自:BUG-539(整句去前缀把回忆线索一并删掉)
- 修复版本:待发布
## BUG-643 | 「没有 / 记不清」靠原字匹配,分类器分不出「没有」和「先放着」
- 状态:resolved
- 首次发现:2026-09-10
- 最近更新:2026-09-10
- 影响面:`turn-intent-classifier.ts``POST /api/rectification/agent``expectedWriteFromCollectIntent`
- 用户现象:只有整句等于「没有」或「记不清」才走跳过;「不记得了」「忘了」落到 Agent。采集题分类器只教了 `no`。用户用带年月的事回答采集题时,`expectedWrite` 仍是 none,BUG-635 守卫只剩正文「记下了」。
- 触发条件:采集焦点下打「没有」「不记得了」「2018 年 3 月开始欠债」。
- 根因:`isCollectDeclineUtterance` / `isCollectSkipUtterance` 去掉句末标点后要求整句相等。`shouldDeclineCollectFocus` 只认 `no``expectedWriteFromCollectIntent` 不把 collect 焦点上的 yes/weak_yes 当写入。
- 修复:删除两个原字匹配函数和路由短路。分类器:没有→`no`declined),记不清→`unsure`(skipped),带年月直接回答采集题→`yes``expectedWrite=evidence``collectFocusCloseStatus` 走既有 `applyCollectFocusDenial`。分类器失败记 `collectIntent=unclassified`,不做关键词兜底。
- 验证:`rectification-turn-intent-classifier.test.ts``rectification-spoken-collect.test.ts``rectification-unwritten-evidence.test.ts`collect + yes + 无写入 → 重试)。源码合同:route 与 classifier 不再引用那两个函数。
- 防复发:采集跳过/没有不得用正则或词表。collect 焦点 yes/weak_yes 必须 `expectedWrite=evidence`。分类器 null 不得回退到关键词。
- 相关记录:BUG-605、BUG-626、BUG-635
- 复发自:无
- 修复版本:待发布
## BUG-644 | 被顶替的采集题号永久占位,落库撞号后当成已问过并断流
- 状态:resolved