Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
9.4 KiB
TASK · 采集方向修复单:带年份补采集不得抢在感情 / 事业前面(2026-09-04)
上游任务书:docs/tasks/TASK-rectification-collect-direction-20260904.md(实现 3847e9c9,已合入 origin/staging)。
本单是验收后的修复单,只处理验收未通过项与一条门禁阻塞;5.1 / 5.3 / 5.4 已验收通过,不重做。
0. 基线
- 基线 commit:
origin/staging3847e9c9(fix(rectification): collect a dated third event before OOS and occupation)。 - 分支:
codex/rectification-collect-direction-fix-20260904,工作树.worktrees/rectification-collect-direction-fix-20260904。 - 验收环境:无 Docker(25 条
docker ENOENT基线失败)、无登录态、无模型凭据。
1. 事故实证
1a. 新案例第二问从「感情」变成了「家人」(验收发现,P1)
任务书 §3 决策 3 写的顺序是「家人→学业→财务→搬家→健康→事业→感情」,并要求进入计划主流程。执行方按字面把 nextDatedCollectFollowup 插在 buildMethodFollowupPlan 的方法覆盖轮转之前(method-followup.ts 中 if (!next && !meetsAcceptanceEventQuality(input.evidence)) 一段,位于 !dashaCovered 之后、sameDomainYearlessCard / d9_relationship 轮转之前)。
结果:训练门未开(前 3 件事几乎总是如此)时,任何新案例的路径变成:
| 已有证据 | 45bdb63e(原) |
3847e9c9(现) |
|---|---|---|
| 1 件事业 | d9_relationship / relationship |
relatives / family |
| 1 件感情 | d10_career / career |
relatives / family |
| 1 件学业 | d9_relationship / relationship |
relatives / family |
| 事业 + 感情 | relatives / family |
relatives / family(一致) |
本地重放(buildMethodFollowupPlan 带 holdoutValidation: "not_started")与 3847e9c9 改写的 17 条断言一致:rectification-eight-method(7 条 d9_relationship → relatives)、rectification-walkthrough-polish、rectification-question-ownership、rectification-choice-card、rectification-v10-conversation-focus(relationship / collect_retry: true → family,同时丢掉了「已关闭的感情采集 → retry 文案」这条路径)。
这不是执行方偏离,是任务书 §3 决策 3 给的顺序没有区分「新案例的前两问」与「缺第三件事时的补采集」。这条由任务书作者承担。
1b. 为什么感情 / 事业必须在前
BLOCKING_COVERAGE_IDS = { dasha_events, d9_relationship, d10_career, relatives }:D9 / D10 / 六亲三层是采用门的前置(BUG-463),家人在第三位是既定顺序。sameDomainYearlessCard(domain)只在轮转里生效:感情 / 事业若已有无年份的区分卡,轮转会直接出卡;提前的 dated 分支绕过了它。closedCollectFocuses的 retry 路径(USER_COLLECT_QUESTION_RETRY.relationship)也只在轮转里;提前分支让它永远不会被触发。
1c. 门禁阻塞(非本单引入,但挡住本单上线)
https://staging.jyotisha.chat/api/health 的 deployment.gitCommit 停在 7b1354a7。其后 7ee7f825(fix(ui): collapse product weights and radii onto the shared Button)把 globals.css 里原生 input 的 padding: 0 12px 改成 padding: 0 var(--space-3),但 frontend/tests/admin-model-management-ui-contract.test.ts 的 global native input sizing excludes Ant Design picker internals 仍锁 padding: 0 12px;。backend-quality-gate 跑 npm test --prefix frontend,所以 7ee7f825、5c5f25a3、3847e9c9 全部没有部署。本地全量:2655 tests / 26 fail,其中 25 条是无 Docker 基线,唯一新增就是这条。
2. 根因
- 任务书顺序定义错位:把「补第三件带年份的事」的顺序当成了整个训练门未开阶段的顺序,覆盖了新案例的前两问。
- 插入点错位:dated 分支应当是轮转里「家人」之后、「职业」之前的一个环节,而不是轮转前的总闸。
7ee7f825改 CSS 未同步合同测试。
3. 决策记录
DATED_COLLECT_ORDER的定义不动(家人→学业→财务→搬家→健康→事业→感情),仍是唯一定义;exhaustionSpokenCollectFollowup(Agent 穷尽路径)继续用它,rectification-range-offer-deadend那条「搬家在职业前」的改写保留。- 计划主流程只改插入位置:删掉轮转前的
if (!next && !meetsAcceptanceEventQuality(...))分支;在轮转里!familyCovered分支之后、!occupationCovered分支之前加一段:训练门未开且nextDatedCollectFollowup(input.evidence, declined)有结果时取它。此时感情 / 事业 / 家人已 covered 或 declined,nextDatedCollectFollowup只会给出学业→财务→搬家→健康。 - 本单顺带解堵 §1c:改测试不改 CSS(CSS 改动是设计意图,不为测试改业务代码)。若开工时
origin/staging上这条测试已被 Button 会话修好,跳过并在进度记录写明。 - 1a 表里被改写的 17 条断言全部回退到原值,每条保留三栏说明(原值 =
3847e9c9的值,新值 =45bdb63e的值,原因 = 「dated 分支移到家人之后,前两问恢复感情 / 事业」)。
4. 硬红线
- 不改
holdoutValidationStatus语义;不动采用 / 确认门(BUG-463);不改declinedDomains(BUG-520);不改holdoutFollowupFor、validateSpokenPrompt、collectionProgressFromReceipt(已验收)。 - 顺序只保留
DATED_COLLECT_ORDER一处定义,不得再抄一份。 - 事故案例的三种形状(上游任务书 §1:after-no / after-occupation / no-decline)改完后必须仍然得到学业采集题,不得回到 occupation 或
other。 - 不写任何案例数据;不动 Python;不 bump Skill。
- 进度记录必须贴六行汇总 + 退出码(
# tests / # pass / # fail / # cancelled / # skipped / exit);# cancelled非 0 视为未通过(BUG-523)。
5. 任务分解
5.1 dated 分支移到轮转内(BUG-531)
- 改
frontend/src/lib/rectification-agentic/v9/method-followup.ts:删轮转前分支;轮转内新增else if (!meetsAcceptanceEventQuality(input.evidence) && (dated = nextDatedCollectFollowup(input.evidence, declined)))形式的环节(写法自定,位置必须在家人之后、职业之前)。 - 验收:
buildMethodFollowupPlan一件事业 →d9_relationship;一件感情 →d10_career;事业 + 感情 →relatives;事业 + 感情 + 家人拒答 →d5_education(不是 occupation);事业 + 感情 + 家人拒答 + 学业拒答 →d2_finance;四件跨两域(训练门已开)→ 不进 dated 分支(沿用3847e9c9新测试)。persistNextInterviewAfterChoice家人答「没有」后焦点collect:education:collect_method_evidence(rectification-collect-direction-20260904.test.ts既有用例不动)。- 上述新增断言放进
rectification-collect-direction-20260904.test.ts。
5.2 回退 17 条断言(随 5.1 同一提交)
- 文件:
rectification-eight-method、rectification-walkthrough-polish、rectification-question-ownership、rectification-choice-card、rectification-v10-conversation-focus。rectification-range-offer-deadend、rectification-agentic-entry、rectification-spoken-prompt、rectification-v9-agent不动。 rectification-v10-conversation-focus必须恢复collect_retry: true与USER_COLLECT_QUESTION_RETRY.relationship两条断言。- 验收:
git diff 3847e9c9 -- frontend/tests中每处改动都有三栏说明;测试总数 ≥ 2655。
5.3 门禁解堵(BUG-532,可能已被别的会话处理)
- 改
frontend/tests/admin-model-management-ui-contract.test.ts:正则接受padding: 0 var\(--space-3\);(或与7ee7f825的实际值一致),三栏说明写明「7ee7f825把间距收敛到 token」。 - 验收:
npx tsx --test tests/admin-model-management-ui-contract.test.ts全过;全量失败清单只剩无 Docker 基线。 - 进度记录同时写:这条阻塞是谁引入的(commit)、是否已在别处修。
5.4 记录
docs/BUG_HISTORY.md:BUG-531(新案例第二问被家人抢占,关联 BUG-528,写明任务书顺序错位是根因)、BUG-532(7ee7f825CSS 与合同测试脱节;若别处已修则改为关联记录)。docs/tasks/PROGRESS-rectification-collect-direction-fix-20260904.md;docs/tasks/README.md加一行;CHANGELOG.md一句话。
6. 让步顺序
- 5.1 + 5.2 是核心,不能让。
- 5.3 若 Button 会话已修:跳过;若冲突:以先合入 staging 的为准,本单 rebase。
- 三栏说明可以合并写在测试文件顶部一段(列明所有回退行),但每条断言旁至少留「见文件头」。
7. 开工前置命令
git fetch origin --prune
git worktree add -b codex/rectification-collect-direction-fix-20260904 .worktrees/rectification-collect-direction-fix-20260904 origin/staging
ln -s /workspace/Jyotisha/frontend/node_modules .worktrees/rectification-collect-direction-fix-20260904/frontend/node_modules
grep -o "BUG-5[0-9][0-9]" docs/BUG_HISTORY.md | sort -u | tail -1 # 核对起点
cd frontend && ./node_modules/.bin/tsc --noEmit && npm run lint
npx tsx --test tests/rectification-*.test.ts tests/admin-model-management-ui-contract.test.ts
npm test
8. BUG 编号起点
origin/staging 上最大号 BUG-530,本单从 BUG-531 起;开工时再核对一次,若被别的会话占用则顺延并在进度记录写明。