Files
Jyotisha/docs/tasks/TASK-rectification-domain-alias-audit-20260909.md
T

7.1 KiB
Raw Blame History

TASK · 领域命名审计:health / health_pressure 与 occupation / other 两组别名在十处比较里各走各的,统一成一处归并(2026-09-09)

  • 基线:origin/staging @ 4067aff8
  • 分支:codex/rectification-domain-alias-audit-20260909,基于 origin/staging;与 codex/rectification-skipped-health-deadend-20260909BUG-626/627)串行——本单包含它的决策 1,若它先合入则本单只补其余站点
  • 执行方:coding agent;验收:Claude
  • 涉及文件:frontend/src/lib/rectification-agentic/v9/method-followup.tscore/candidate-contrast-packet.tsv9/server-focus.tsscripts/rectification/event_probes.pyscripts/rectification/refinement_packet.pyscripts/rectification/contracts.py
  • BUG 编号起点:BUG-628docs/BUG_HISTORY.md 当前最大 BUG-627
  • 优先级:P1(产品追问"其他领域会不会出现同样的问题":健康线还有六处同类漏洞;职业线一处;其余五个领域全线一致,无问题)

1. 审计结论

三套词汇并存:

健康 职业
证据账本(EVIDENCE_DOMAINS、引擎事件、contracts.py healthhealth_pressure 仅作 v1 兼容) occupation
焦点 / 拒答记录(DB target_domain 约束,persistableFocusDomain health other
计划层、引擎探针 / 分盘层 / 盘外提示、题干与关键词表 health_pressure occupation

教育、事业、感情、迁居、财务、家人六个领域三层同名,逐站核过,没有同类问题

2. 逐站清单(健康)

# 位置 比较的两边 后果 现状
H1 method-followup.ts::holdoutFollowupFor !declined.has(item.domain) 拒答记录 health vs 盘外提示 health_pressure 拒答 / 跳过的健康线被当作"没用过"再问,撞同 id 焦点静默 BUG-626
H2 同函数 occupied 账本 health vs 提示 health_pressure 已修(BUG-590 决策 4 已修
H3 remainingReverseVerifyProbes L718 declined.has(probe.domain) 拒答 health vs 引擎探针 health_pressure 采用后核对仍会问拒答过的健康线 未修
H4 remainingConflictProbes L789 同上 同上 区分题仍会问拒答过的健康线 未修
H5 probeYearAlreadyCovered L427 item.domain !== domain 账本 health vs 探针 health_pressure 用户已报 2024-10 受伤,仍可能被问"2024 年 10 月前后有没有生病受伤" 未修
H6 引擎 oos_blind_prompts covered 用事件域 事件 health vs 目录 health_pressure 有健康事件时仍下发"还没用过健康压力这条线"(真实 Case JSON 已见) 未修
H7 引擎 _event_years(events, "health_pressure")_existence_blocked_years 同上 已报年份不阻断健康探针,出重复 / 引导题 未修
H8 引擎 volunteered 集合(VOLUNTEER_ONLYhealth_pressure 事件 health 永远不等于 health_pressure 用户主动报了健康事件,D30 层仍被当"未主动提及"永不进入探针顺序——健康线被系统性低用 未修
H9 candidate-contrast-packet.ts L237 item.domain === "health_pressure" || HEALTH_RE.test(summary) 用摘要正则补别名 能工作,但是靠文案猜;摘要不含关键词就漏 改为归并
H10 datedCollectDomainBlocked / hasConfirmedHealth / declinedHealth 已归并 已修

3. 逐站清单(职业)

# 位置 后果 现状
O1 declinedDomains 对职业焦点得到 otherdeclined.has("occupation") 永远为假(L1348 / L1386 / L1957 三处) occupationCollectFocusClosedquestionId 前缀兜底;L1957 的兜底还额外要求 careerCovered——事业未覆盖时拒答职业会被再问 部分修
O2 declinedDomains 把职业拒答记成 other 塞进集合 目前无人查 declined.has("other"),无害 顺手清理

4. 决策记录

  1. 一个归并函数,两侧各一份,语义相同。 TScanonicalCollectDomain(raw, questionId?)healthhealth_pressuretarget_domain === "other"questionIdcollect:occupation: 开头 → occupation;其余原样。放在 v9/domain-alias.tsmethod-followup.tscandidate-contrast-packet.ts 全部经它比较;hasConfirmedHealth / declinedHealth 改为它的薄封装并保留。Pythonevent_probes.pycanonical_domain(raw)healthhealth_pressure),_event_yearsoos_blind_prompts.coveredvolunteered 三处经它;contracts.py 的 v1 兼容项不动。
  2. DB 不改target_domain 约束仍是 health / other;归并只发生在读取侧。persistableFocusDomain 不变。
  3. H8 单独确认产品口径:健康线本来就是"只有用户主动说才问"(SKILL.md §5),修完归并后主动报过健康事件的用户会开始收到 D30 层探针——这是原设计意图,不是新行为;进度记录写明。
  4. 不动门槛、四选项合同、SCORE_DELTASkill 不 bump。

5. 任务分解

  • 5.1 TS 归并函数 + H1/H3/H4/H5/H9/O1 六站改用;用例——每站一条:账本 health + 拒答 health + 探针 health_pressure → 不再问;职业拒答(topic other + collect:occupation: id)→ declined.has("occupation") 语义成立且事业未覆盖时也不再问职业。
  • 5.2 Python 归并 + H6/H7/H8;用例(tests/test_rectification_event_probes.py)——事件域 health 2024-10 → oos_blind_prompts 不含 health_pressure_existence_blocked_years("health_pressure") 含 2024volunteeredhealth_pressureD30 进入顺序。
  • 5.3 源码合同:agent-voice-copy-contract 或新合同测试锁"method-followup.ts 里除归并函数外不得出现字面量 "health" 比较"grep -n '"health"' 只允许在 domain-alias.ts)。
  • 5.4 记录:BUG-628(关联 BUG-590 决策 4、BUG-626、BUG-586 决策 2);CHANGELOG.mdPROGRESS-…CONTEXT.md 术语表补一条"领域别名:health ≡ health_pressureoccupation 在焦点层存为 other"。

6. 让步顺序

5.1 与 5.2 必做同一提交;5.3 必做(防第三次复发);5.4 不可省。

7. 开工前置命令

git fetch origin --prune
git worktree add -b codex/rectification-domain-alias-audit-20260909 .worktrees/rectification-domain-alias-audit-20260909 origin/staging
cd .worktrees/rectification-domain-alias-audit-20260909
ln -s /workspace/Jyotisha/frontend/node_modules frontend/node_modules
ln -s /workspace/Jyotisha/.venv .venv
grep -n '"health"' frontend/src/lib/rectification-agentic/v9/method-followup.ts frontend/src/lib/rectification-agentic/core/candidate-contrast-packet.ts scripts/rectification/event_probes.py scripts/rectification/refinement_packet.py
cd frontend && ./node_modules/.bin/tsc --noEmit; npm run lint 2>&1 | tail -1
ls tests/rectification-*.test.ts | grep -v database | xargs npx tsx --test 2>&1 | grep -E "^# (tests|pass|fail)"
cd .. && .venv/bin/python -m pytest tests/test_rectification_event_probes.py tests/test_rectification_v5_services.py -q