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

75 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-20260909`BUG-626/627)串行——**本单包含它的决策 1**,若它先合入则本单只补其余站点
- 执行方:coding agent;验收:Claude
- 涉及文件:`frontend/src/lib/rectification-agentic/v9/method-followup.ts``core/candidate-contrast-packet.ts``v9/server-focus.ts``scripts/rectification/event_probes.py``scripts/rectification/refinement_packet.py``scripts/rectification/contracts.py`
- BUG 编号起点:**BUG-628**`docs/BUG_HISTORY.md` 当前最大 BUG-627
- 优先级:**P1**(产品追问"其他领域会不会出现同样的问题":健康线还有六处同类漏洞;职业线一处;其余五个领域全线一致,无问题)
## 1. 审计结论
三套词汇并存:
| 层 | 健康 | 职业 |
| --- | --- | --- |
| 证据账本(`EVIDENCE_DOMAINS`、引擎事件、`contracts.py` | `health``health_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_ONLY``health_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` 对职业焦点得到 `other``declined.has("occupation")` 永远为假(L1348 / L1386 / L1957 三处) | 靠 `occupationCollectFocusClosed``questionId` 前缀兜底;L1957 的兜底还额外要求 `careerCovered`——事业未覆盖时拒答职业会被再问 | 部分修 |
| O2 | `declinedDomains` 把职业拒答记成 `other` 塞进集合 | 目前无人查 `declined.has("other")`,无害 | 顺手清理 |
## 4. 决策记录
1. **一个归并函数,两侧各一份,语义相同。** TS`canonicalCollectDomain(raw, questionId?)``health``health_pressure``target_domain === "other"``questionId``collect:occupation:` 开头 → `occupation`;其余原样。放在 `v9/domain-alias.ts``method-followup.ts``candidate-contrast-packet.ts` 全部经它比较;`hasConfirmedHealth` / `declinedHealth` 改为它的薄封装并保留。Python`event_probes.py``canonical_domain(raw)``health``health_pressure`),`_event_years``oos_blind_prompts.covered``volunteered` 三处经它;`contracts.py` 的 v1 兼容项不动。
2. **DB 不改**`target_domain` 约束仍是 `health` / `other`;归并只发生在读取侧。`persistableFocusDomain` 不变。
3. **H8 单独确认产品口径**:健康线本来就是"只有用户主动说才问"(SKILL.md §5),修完归并后主动报过健康事件的用户会开始收到 D30 层探针——这是原设计意图,不是新行为;进度记录写明。
4. 不动门槛、四选项合同、`SCORE_DELTA`Skill 不 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")` 含 2024`volunteered``health_pressure`D30 进入顺序。
- 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.md``PROGRESS-…``CONTEXT.md` 术语表补一条"领域别名:health ≡ health_pressureoccupation 在焦点层存为 other"。
## 6. 让步顺序
5.1 与 5.2 必做同一提交;5.3 必做(防第三次复发);5.4 不可省。
## 7. 开工前置命令
```bash
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
```