2dc6194671
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
5.6 KiB
5.6 KiB
TASK · 刚在区分卡上答过"是",紧接着又被问同一领域的采集题(2026-09-05)
- 基线:
origin/staging@c295b853(含 BUG-546/547) - 分支:
codex/rectification-probe-answer-covers-domain-20260905 - 执行方:coding agent;验收:Claude
- 涉及文件:
frontend/src/lib/rectification-agentic/v9/method-followup.ts、decision-from-dossier.ts(把已答探针透传给计划层);不改引擎 - BUG 编号起点:BUG-549(开工时
grep -o "^## BUG-5[0-9][0-9]" docs/BUG_HISTORY.md | tail -1复核;BUG-542 仍为TASK-api-not-configured-mislabel-20260904.md预留)
1. 事故实证(staging,2026-09-05)
用户连续三轮:
| 轮 | 助手问 | 用户 |
|---|---|---|
| 1 | 区分卡「2024 年 4 月前后,有没有入职、换工作或职责加重?A/B/C/D」 | 点选 |
| 2 | 区分卡「2015 年 5 月前后,有没有搬家或长期住到外地?A/B/C/D」 | 点选 |
| 3 | 口述采集「工作上呢,还记得哪年入职、换工作,或职责一下子变重吗?」(USER_COLLECT_QUESTION.career 原文) |
反馈"相同的问题又问了一遍" |
第 1 轮如果点的是 A/B(发生了),用户已经交代了一件 2024 年 4 月的工作变化;第 3 轮再让他"说哪年入职、换工作",在用户眼里就是同一道题。
2. 根因
- 区分卡的点选答案只进推断层(
applyChoiceWithoutEvidence→inference_state.answered_probes,classified_from: "choice"),不写证据账本。这是既定设计(BUG-389–393:探针与账本分层,不双计分),本单不推翻。 - 计划层判断"某领域问过没有"只看账本:
method-followup.ts::hasConfirmedDomain驱动relationshipCovered / careerCovered / familyCovered(约 L1563–1565)和datedCollectDomainBlocked(DATED_COLLECT_ORDER补采集)。已答探针只以askedProbeKeys(字符串集合)进入计划层,用于探针去重,不参与领域覆盖判断,且不带answer_class。 - 区分卡在场时
if (!next)采集链不跑;BUG-546/547 之后区分卡问完才进采集链,于是"刚答完的领域马上被再问一次"从偶发变成必现。
3. 决策记录
- 对探针答 A/B(
yes/weak_yes)的领域,视为该领域采集已覆盖:careerCovered/relationshipCovered/familyCovered与datedCollectDomainBlocked都要把它算进去。不写账本、不改meetsAcceptanceEventQuality、不动训练门与确认门。 - 答 C/D(
no/unsure)不算覆盖:用户说那年没发生,仍可能有别的年份,采集题是新信息。此项产品可否决——若觉得连 C/D 后紧跟同领域采集也别扭,改为"同领域采集至少隔一轮",在进度记录写明选了哪个。 - 领域从探针的
domain字段取;answered_probes行只有semantic_key,执行方用eventProbes按semantic_key/probe_id回查 domain,回查不到的行忽略(不要从semantic_key前缀硬拆字符串)。 - 不删
USER_COLLECT_QUESTION.career这类文案,不新增"除了刚才那次以外"的变体文案。
4. 硬红线
- 不得把点选答案写进证据账本(BUG-389–393 分层);不得放宽
meetsAcceptanceEventQuality、buildConfirmationGate。 - BUG-546(无区分卡时继续补采集)与 BUG-547(有卡先问卡)的用例原样通过。
- BUG-520:区分卡答"否"不是领域拒答,
declinedDomains不改。 - 任务书 / 进度 / Bug 历史只用抽象年份。
5. 任务分解
5.1 已答探针透传到计划层
buildMethodFollowupPlan新增可选入参answeredProbes?: readonly { semantic_key: string; probe_id?: string; answer_class: string }[],由decision-from-dossier.ts现有的askedProbeKeys同一来源(inference_state.answered_probes)填充;adopt-narration.ts、interview-state.ts、answer-choice.ts、route.ts的调用点同样透传(缺省为空数组,行为不变)。- 验收:
tsc0 错;不传时所有既有用例结果不变。
5.2 覆盖判定叠加
- 新增
domainsAnsweredYes(answeredProbes, eventProbes): Set<string>;relationshipCovered / careerCovered / familyCovered与datedCollectDomainBlocked用hasConfirmedDomain(...) || answeredYes.has(domain)。 - 验收:
frontend/tests/rectification-choice-card.test.ts或rectification-collect-direction-20260904.test.ts新增用例——账本无 career 证据、answered_probes含 career 探针yes、无剩余区分卡 → 下一问不是 career 采集(按DATED_COLLECT_ORDER落到下一未覆盖域或职业口述);同样输入但answer_class: "no"→ 仍问 career 采集(决策 2)。
5.3 记录
docs/BUG_HISTORY.mdBUG-549;CHANGELOG.md;docs/tasks/PROGRESS-rectification-probe-answer-covers-domain-20260905.md;docs/testing/rectification-probe-answer-covers-domain-20260905.md(真实环境:对某领域区分卡点 A 后,该领域的"哪年…"采集题不再出现)。
6. 让步顺序
5.1 + 5.2 一起做,不可拆;5.3 不可省。
7. 开工前置命令
git fetch origin --prune
git worktree add -b codex/rectification-probe-answer-covers-domain-20260905 .worktrees/rectification-probe-answer-covers-domain-20260905 origin/staging
cd .worktrees/rectification-probe-answer-covers-domain-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。