Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
5.8 KiB
TASK · 家人拒答后继续采集(BUG-546)的修复单:补采集不得挤掉现成的区分题(2026-09-05)
- 基线:
origin/staging@998406ce(BUG-546 实现) - 分支:
codex/rectification-family-collect-continue-fix-20260905 - 验收方:Claude;本单是对
998406ce的验收结论,不是新需求 - BUG 编号起点:BUG-547(开工时
grep -n "^## BUG-5" docs/BUG_HISTORY.md | tail -1复核;BUG-542 仍为TASK-api-not-configured-mislabel-20260904.md预留)
1. 验收实证
在 998406ce 上跑 npx tsx --test tests/rectification-*.test.ts tests/agent-voice-copy-contract.test.ts:894 项,3 失败;同一命令在前一提交 329f8a21 上 0 失败。进度记录列出的套件没有包含这两个文件。
| # | 文件 / 用例 | 期望 | 实际 | 定性 |
|---|---|---|---|---|
| A | rectification-choice-card.test.ts · distinguish follow-up copy forbids competing-chart ranking |
学业/感情/事业/家人/职业/占问全覆盖、精度阶段 d4_refine、引擎给了一条搬家 A/B 探针(两候选分钟各一边、增益 0.4)→ 下一问是那张 A/B 卡 |
下一问变成财务口述采集「可以先问有没有记得住时间的收入变化…」;探针既不在 deferred_followup 也不在 dropped_probes |
行为回归 |
| B | rectification-occupation-coverage-exit.test.ts · career evidence alone still does not cover occupation |
下一问 occupation |
d2_finance |
顺序变更,与 BUG-546 决策一致,缺三栏断言说明 |
| C | 同文件 · training gate open does not mint yearless existence or quality varga cards |
下一问 occupation |
d2_finance |
同 B |
A 的复现路径不只在测试里:app/api/rectification/agent/route.ts 在 decision.nextAction === "ask_candidate_discriminator" 时调 buildMethodFollowupPlan 并把 plan.next_followup 写成焦点;现在只要财务 / 搬家 / 健康任一域未覆盖、未拒答,写下去的就是口述采集而不是区分卡,isRenderableChoiceOpenQuestion 为假,后续按口述路径走。
2. 根因
method-followup.ts::buildMethodFollowupPlan 的 if (!next) 链里,家人之后的分支从
!meetsAcceptanceEventQuality(evidence) && nextDatedCollectFollowup(...) 改成了无条件 nextDatedCollectFollowup(...)。这条分支排在 d4_refine 搬家 A/B 卡(同函数约 L2107)与其后所有 yearless / 精度层卡之前,所以只要 DATED_COLLECT_ORDER 里还有未覆盖域,现成的区分探针永远轮不到。
BUG-546 自己写的触发条件是"剩余区分探针被标成 no_split_among_active"——也就是没有可用区分题的时候。实现把它扩成了"不管有没有区分题都先采集"。
3. 决策记录
- BUG-546 的产品意图保留:家人答「没有」而候选分钟仍分得开时,不得直接给结果,要继续收未问过的带年份域(学业 → 财务 → 搬家 → 健康)。
- 但现成的区分题优先于口述补采集。引擎已经算出哪一问能把剩余分钟分开,就先问它;只有当本轮没有任何可渲染的区分卡(
yearlessDiscriminators与精度层 / 搬家 A/B 卡都拿不出choice_frame)时,才走 dated 补采集。这与Relocation stays out of domain rotation and is only asked at d4_refine的原始设计一致,也与 BUG-546 自述的触发条件一致。 isRemainingEvidenceCollect对deferAdoption/shouldSkipFollowupPersist的豁免保留(否则采集写不进焦点,又回到 BUG-546)。- B、C 两条断言允许改为
d2_finance,但必须在进度记录写"原值 / 新值 / 原因"。A 不允许改断言。
4. 硬红线
- 不动
DATED_COLLECT_ORDER、exhaustionSpokenCollectFollowup(BUG-520 口径)。 - 不放宽
meetsAcceptanceEventQuality与精确分钟确认门。 accepted早退路径(采用后只走remainingReverseVerifyProbes)不得受影响;BUG-350 / 463 / 499 / 502 / 518 / 519 / 536–539 / 544 的测试原样通过。- 已在
998406ce里改过的断言(collect-stall、adopt-narration、provisional-adopt、eight-method、range-offer-deadend、collect-direction)不得再改回去,除非同样写三栏说明。
5. 任务分解
5.1 补采集让位于区分题
- 把家人之后的 dated 补采集改成"无可渲染区分卡时才取":最直接的做法是把该
else if移到(或复制到)d4_refine搬家卡与 yearless 卡分支之后、!occupationCovered之前,且仍在if (!next)链内;或在分支条件里加"本轮 ranked / precision 探针都拿不出choice_frame"的判定。两种取一,进度记录说明为何。 - 验收:
rectification-choice-card.test.tsA 用例原样通过;新增用例——同样证据集但 没有 探针时,下一问是财务采集(证明 BUG-546 意图仍在)。
5.2 断言三栏说明
rectification-occupation-coverage-exit.test.tsB、C 改为d2_finance,三栏写进PROGRESS-rectification-family-collect-continue-20260905.md(追加一节,不新开进度文件)。
5.3 记录
docs/BUG_HISTORY.md:BUG-546 追加"复发/修正"段并新增 BUG-547(现成区分题被口述采集挤掉),关联 BUG-546、BUG-519。CHANGELOG.md一条。
6. 开工前置命令
git fetch origin --prune
git worktree add -b codex/rectification-family-collect-continue-fix-20260905 .worktrees/rectification-family-collect-continue-fix-20260905 origin/staging
cd .worktrees/rectification-family-collect-continue-fix-20260905
ln -s /workspace/Jyotisha/frontend/node_modules frontend/node_modules
cd frontend && npx tsx --test tests/rectification-*.test.ts tests/agent-voice-copy-contract.test.ts 2>&1 | grep -E "^# (tests|pass|fail)|^not ok"
收尾必须跑同一条命令并达到 fail=0,再 tsc --noEmit、npm run lint。