fix(rectification): 记录与校正区间冲突时记录优先、分歧并列(BUG-691)
医院记录那一分钟落在校正区间外时,交付卡以前只说一句「相差 N 分钟」:
没说默认按哪个时间排盘,采用按钮也仍写中性的「更像这个」,用户看不出
点下去会把之后的排盘换成另一分钟。
产品负责人 2026-09-14 拍板「记录优先,分歧如实呈现」:
- 冲突文案补满三层——默认仍按出生记录时间排盘、经历指向另一段时间相差
N 分钟、两条路都可以走。
- 冲突态采用按钮改「改用校正结果」,按钮下按列写明
「选它之后,排盘会从出生记录时间 hh:mm 换成 hh:mm」。
- 新增 FORBIDDEN_RECORD_VERDICT_PHRASE 锁住 D4:不得宣布记录不准,
也不得宣布校正结果无效。
只改文案层与采用入口措辞。打分、判据、采用 RPC、置信度与确认门控、
数据库一律未动;不新增入口、不加确认弹窗;记录落在范围内或来源是
「大概时间 / 时间段」时卡片与今天完全一致。Skill 未 bump,只补
references §6.1。
验收:tsc 0 错;lint 0 error;npm test 3335 项 fail 31,失败清单与基线
37e6c519 逐条一致(全部是无 Docker / 无外网的既有环境缺口);next build
通过且 / 仍 ○ Static;首屏 chunks gzip +269 B(+0.019%)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Opus 5
parent
63c419f375
commit
6df40c322c
@@ -10758,6 +10758,22 @@
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-691 | 医院记录与校正区间冲突时只并列差值,不说默认按哪个排盘,用户不知道点「更像这个」会换掉什么
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-14
|
||||
- 最近更新:2026-09-16
|
||||
- 影响面:`frontend/src/lib/rectification-agentic/birth-time-provenance.ts`、`v9/divergence-panel.ts`、`components/rectification-range-delivery.tsx`、`frontend/docs/VOICE.md`、`frontend/DESIGN.md`、Skill `references/candidate-comparison.md`
|
||||
- 用户现象:录入选了「医院记录」且记录那一分钟落在目前范围外时,交付卡只有一句「出生记录时间 04:40。目前范围不含这一分钟,相差 8 分钟」。没说默认按哪个时间排盘,也没说还能继续用记录;采用按钮仍写中性的「更像这个」,点下去实际上把之后的排盘从出生记录时间换成了另一分钟,用户看不出自己在换什么。
|
||||
- 触发条件:`birth_time_source = hospital_record`,且 `reported_birth_time` 落在 `credible_range` 之外,进入区间交付卡。
|
||||
- 根因:BUG-690 定了三档来源标签,但把「记录与范围冲突时站哪边」显式挂给产品负责人未决,所以冲突文案只实现了并列差值的前半句;采用入口本就是为非冲突态设计的「更像这个」,没有随来源分档。
|
||||
- 修复:产品负责人 2026-09-14 拍板「记录优先,分歧如实呈现」(依据:`docs/research/cluster_width_2026_09_14.md`,封存 20 例六题后头名簇命中率 0.80 / 0.55 / 0.35 对 ±10 / ±30 / ±60 分钟窗,证据强度撑不起推翻书面记录;但医院记录确实会因事后补记、五分钟整数舍入、家属转述而错,故不得反过来宣布校正结果无效)。`reportedTimeOffsetCopy` 的冲突分支补满三层:默认仍按记录排盘 / 经历指向另一段时间差 N 分钟 / 两条路都可以走。新增 `recordRangeConflict` 作为唯一的冲突判据,经 `RangeDeliveryProjection.record_conflict` 投给交付卡:冲突态按钮写「改用校正结果」,按钮下补一行「选它之后,排盘会从出生记录时间 hh:mm 换成 hh:mm」。只改文案与措辞,不改打分、判据、采用 RPC、置信度与确认门控,不动数据库,不新增入口。
|
||||
- 验证:`frontend/tests/rectification-record-conflict-copy-20260916.test.ts`(冲突判据只认落在范围外的医院记录;冲突文案含三层且不触 `FORBIDDEN_RECORD_VERDICT_PHRASE`;记录落在范围内的文案逐字不变;冲突态按钮与逐列确认句;`approximate` / `period_only` / 记录在范围内三态仍是「更像这个」且无确认句;投影往返后候选与代表分钟不变)。`rectification-birth-time-provenance-20260914.test.ts` 一条断言按「原值 / 新值 / 原因」三栏改写(该用例的 05:12 对 04:48–05:07 本就是冲突态)。`tsc --noEmit` 0 错,`npm run lint` 0 error,`npm test` 失败数与基线同为 31 条且逐条同名(全部是无 Docker / 无外网的既有环境缺口)。
|
||||
- 防复发:记录与校正冲突时默认站在记录一边,但两者必须并列;系统不得宣布任何一方无效——不得写「记录不准 / 记录错了 / 以证据为准」,也不得写「校正结果无效 / 不作数」。该禁令由 `FORBIDDEN_RECORD_VERDICT_PHRASE` 在文案层锁住,并写进 `frontend/docs/VOICE.md` 与 Skill `references/candidate-comparison.md` §6.1。冲突态改的只能是措辞,采用仍是校正采用时间,不是已确认的唯一出生分钟(BUG-587 红线维持)。
|
||||
- 相关记录:BUG-690、BUG-587、BUG-621
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-692 | 交付邀请语写「这两分钟」却与同段「4 个候选」矛盾;5 条契约断言未跟上
|
||||
|
||||
- 状态:resolved
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# PROGRESS · 记录与校正区间冲突:记录优先,分歧如实呈现(BUG-691)
|
||||
|
||||
- 任务书:`docs/tasks/TASK-rectification-record-conflict-copy-20260914.md`
|
||||
- 分支:`codex/rectification-record-conflict-copy-20260916`,worktree `.worktrees/rectification-record-conflict-copy-20260916`
|
||||
- 实际基线:`origin/staging` @ `37e6c519`(任务书写的基线 `c5fbee56` 已被 staging 超车约 40 个提交)
|
||||
- 执行日期:2026-09-16
|
||||
|
||||
## 0. 开工第一件事:事故是否仍复现
|
||||
|
||||
**仍然复现。** 任务书基线停在 09-14,其后 staging 合入了 BUG-721~733 等大量校正链路改动,所以先逐条核对了 §事故实证:
|
||||
|
||||
- `frontend/src/lib/rectification-agentic/birth-time-provenance.ts` 的 `reportedTimeOffsetCopy` 在 `hospital_record` + 记录落在范围外时,返回的仍然只有前半句:
|
||||
`出生记录时间 05:12。目前范围不含这一分钟,相差 5 分钟`
|
||||
D2 要求的三层(默认按哪个排盘 / 经历指向另一段时间 / 两条路都可以走)一层都没有。
|
||||
- 交付卡 `frontend/src/components/rectification-range-delivery.tsx` 的采用按钮在任何来源下都写 `RECTIFICATION_USER_COPY.rangeDeliveryMoreLikeThis`(「更像这个」),没有随来源或冲突态分档;按钮附近没有任何说明「换掉的是什么」的文案。
|
||||
- `docs/BUG_HISTORY.md` 里 BUG-691 查无此号(690 与 692 之间是真空号),BUG-690 的「修复」一栏还明确写着「医院记录与范围冲突时如何取舍挂给产品负责人」——本单正是那条挂起项的收口。
|
||||
|
||||
结论:没有被后来的轮次顺带修掉,按任务书执行。
|
||||
|
||||
## 1. 编号
|
||||
|
||||
`docs/BUG_HISTORY.md` 当前最大号是 **BUG-733**,但 691 是真空号(690 → 692)。任务书指定 BUG-691,且本单在语义上就是 BUG-690 的 D4 收口,故**填回 691 这个空号**并插在 690 与 692 之间,保持编号连续,不另起 734。
|
||||
|
||||
## 2. 改了什么
|
||||
|
||||
只动文案层与采用入口措辞。打分、判据、采用 RPC、置信度与确认门控、数据库一律未动。
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `frontend/src/lib/rectification-agentic/birth-time-provenance.ts` | 冲突分支文案补满 D2 三层;新增 `recordRangeConflict()` 作为唯一冲突判据;新增 `SWITCH_TO_RECTIFIED_LABEL`、`switchToRectifiedConfirmCopy()`、`FORBIDDEN_RECORD_VERDICT_PHRASE`(D4 锁) |
|
||||
| `frontend/src/lib/rectification-agentic/v9/divergence-panel.ts` | `RangeDeliveryProjection` 增 `record_conflict` 字段(build 与 parse 两侧对称),只是把判据结果投给 UI |
|
||||
| `frontend/src/components/rectification-range-delivery.tsx` | 冲突态按钮改「改用校正结果」;按钮下按列补一行「选它之后,排盘会从出生记录时间 hh:mm 换成 hh:mm」;已采用的列不显示该行 |
|
||||
| `frontend/src/app/globals.css` | 新增 `.rectification-range-delivery__switch-note`,与既有 `__provenance` 同字号同行高,未改间距与列宽 |
|
||||
| `frontend/src/lib/rectification-agentic/user-copy.ts` | 新文案登记进 `listUserVisibleCopy()`,纳入机器腔词表与 D4 体检 |
|
||||
| `frontend/docs/VOICE.md` | 增两行好/坏对照:D4 禁止措辞;冲突态按钮与确认句 |
|
||||
| `frontend/DESIGN.md` | §11 区间交付卡补「冲突时换措辞,不换形状」一段 |
|
||||
| `skills/.../references/candidate-comparison.md` | 新增 §6.1,写入 D1–D4 与拍板依据 |
|
||||
|
||||
### 具体文案
|
||||
|
||||
冲突态来源小字(原来只有第一句的前半):
|
||||
|
||||
> 出生记录时间 05:12,默认仍按这个时间排盘。你说的这些经历指向另一段时间,相差 5 分钟。你可以改用校正结果,也可以继续用记录
|
||||
|
||||
冲突态按钮:`更像这个` → `改用校正结果`
|
||||
按钮下每列各一行:`选它之后,排盘会从出生记录时间 05:12 换成 04:53`
|
||||
|
||||
记录落在范围内时逐字不变:`出生记录时间 05:00,落在目前范围内`,按钮仍是「更像这个」。
|
||||
|
||||
### 红线自查
|
||||
|
||||
- 硬红线 3(不新增多余入口):复用同一个采用按钮与同一个 accept RPC,没有加第二个按钮,也没有加确认弹窗。D3 说的「确认处」落在按钮正下方的说明行——这是动手的地方,且能给出精确的 hh:mm → hh:mm。
|
||||
- 硬红线 4(BUG-587):冲突态文案与确认句都没有出现「已确认 / 确定就是 / 唯一出生分钟是」,由测试正则锁住;采用仍是「校正采用时间」。
|
||||
- D5:`recordRangeConflict` 只读 `source` / `reportedTime` / `range` 三个已有量,不参与任何排序或淘汰;测试里额外断言冲突态与非冲突态的候选列表和代表分钟完全相同。
|
||||
- Skill **未 bump**(仍 10.0.26),按任务书 §5 让步顺序 2 只改 references。理由:本单不改 Agent 的工具链或判据,只补一条表达规则;bump 会让存量 Case 绑旧版本,按 BUG-621 教训得额外验历史可打开,收益不抵风险。`docs/testing/` 清单里仍保留一条「历史 Case 能打开」的人工检查。
|
||||
|
||||
## 3. 验收数字
|
||||
|
||||
- `./node_modules/.bin/tsc --noEmit`:**0 错**。
|
||||
- `npm run lint`:**0 error**(120 warning,全部是既有的 `no-unused-vars`,不在本单范围内,未顺手修)。
|
||||
- 定向:`npx tsx --test tests/rectification-record-conflict-copy-20260916.test.ts tests/rectification-birth-time-provenance-20260914.test.ts` → 9 tests / 9 pass / 0 fail。
|
||||
`npx tsx --test tests/agent-voice-copy-contract.test.ts` → 18 tests / 18 pass / 0 fail。
|
||||
- 全量 `npm test`:
|
||||
| | 基线 `37e6c519` | 本分支 |
|
||||
|---|---|---|
|
||||
| tests | 3329 | 3335 |
|
||||
| pass | 3283 | 3288 |
|
||||
| fail | **31** | **31** |
|
||||
| skipped | 15 | 15 |
|
||||
|
||||
失败清单逐条 `diff` 后**完全一致**(31 条同名),全部是既有环境缺口:无 Docker 的数据库 / 迁移 / 计费 / RLS 套件,以及无外网的 ephemeris / VedAstro / staging 同步套件。
|
||||
|
||||
注:任务书硬红线写「失败数 = 基线 27 条」,那是 09-14 的数字;在实际基线 `37e6c519` 上实测就是 31 条,口径按实测基线走。
|
||||
- 新增测试 6 条(`rectification-record-conflict-copy-20260916.test.ts`),测试总数只增不减。
|
||||
- `npm run build`:通过,`/` 仍是 `○ (Static)`。
|
||||
- 首屏体积:同机各构建一次(基线用 `git stash` 把本轮改动摘掉后重建),`.next/static/chunks/**/*.js` 逐个 gzip 求和 —— 基线 **1,438,383 B**,本分支 **1,438,652 B**,**+269 B / +0.019 %**,在 ±2% 内。(Next 16 Turbopack 的构建输出不再打印 First Load JS 一列,故改用这个可复算的口径。)
|
||||
|
||||
### 改过的既有断言(AGENTS §7.3 三栏说明)
|
||||
|
||||
两条,都是同一个原因——被改的用例本身就处在冲突态:
|
||||
|
||||
| 文件 | 原值 | 新值 | 原因 |
|
||||
|---|---|---|---|
|
||||
| `tests/rectification-birth-time-provenance-20260914.test.ts` | `assert.ok(html.includes(RECTIFICATION_USER_COPY.rangeDeliveryMoreLikeThis))` | `assert.ok(html.includes(SWITCH_TO_RECTIFIED_LABEL))` + 断言不再出现「更像这个」 | BUG-691 D3。该用例是 05:12 对 04:48–05:07,正是冲突态。非冲突态的「更像这个」由新测试逐态锁住,不是弱化 |
|
||||
| `tests/agent-voice-copy-contract.test.ts` | `assert.match(visible, /出生记录时间 05:12。目前范围不含这一分钟,相差 5 分钟/)` | 拆成三层断言(默认按记录排盘 / 指向另一段时间差 5 分钟 / 两条路都可以走)+ 按钮与确认句断言 + 全量 `FORBIDDEN_RECORD_VERDICT_PHRASE` 体检 | BUG-691 D2、D3。断言数从 1 条增到 6 条,是收紧不是放松 |
|
||||
|
||||
## 4. 环境缺口
|
||||
|
||||
- 无 Docker:数据库、迁移、计费、RLS 套件跑不了,失败清单与基线逐条一致(见上表)。
|
||||
- 无外网:ephemeris / VedAstro / staging 同步套件同上。
|
||||
- 无登录态与 Chrome:真实会话里「有医院记录 + 区间不含该分钟」的走查做不了,已写成 `docs/testing/rectification-record-conflict-copy-20260916.md`。
|
||||
- 本轮不动表,未跑 `npm run test:db`。
|
||||
|
||||
## 5. 交付
|
||||
|
||||
- 只提交到 `codex/rectification-record-conflict-copy-20260916`,**未推 staging**,验收与合入由 Claude 会话做。
|
||||
@@ -197,7 +197,7 @@
|
||||
|
||||
| `TASK-rectification-invite-copy-and-assertions-fix-20260915.md` | `PROGRESS-rectification-invite-copy-fix-20260915.md` | **P0 验收修复单**:BUG-689 的邀请语硬编码「这两分钟」却与同段话的「4 个候选」矛盾;BUG-689/690 各自把 4 条与 1 条契约断言留红(`npm test` 27→32)。修文案按候选数出话、两处断言跟上、并给精度研究 M1b 的 V1/V2 追加「未测」勘误(BUG-692) | 待验收 | `codex/rectification-invite-copy-fix-20260915` |
|
||||
|
||||
| `TASK-rectification-record-conflict-copy-20260914.md` | `PROGRESS-rectification-record-conflict-copy-20260914.md` | BUG-690 的 D4 收口:产品 2026-09-14 拍板**记录优先、分歧如实呈现**——默认仍按出生记录时间排盘(行为已成立),校正区间标成「证据倾向」,采用入口在冲突时改成「改用校正结果」;系统不得宣布记录错或校正无效(BUG-691) | 待执行 | `codex/rectification-record-conflict-copy-20260914` |
|
||||
| `TASK-rectification-record-conflict-copy-20260914.md` | `PROGRESS-rectification-record-conflict-copy-20260916.md` | BUG-690 的 D4 收口:产品 2026-09-14 拍板**记录优先、分歧如实呈现**——默认仍按出生记录时间排盘(行为已成立),校正区间标成「证据倾向」,采用入口在冲突时改成「改用校正结果」;系统不得宣布记录错或校正无效(BUG-691) | 已实现待验收 | `codex/rectification-record-conflict-copy-20260916`。开工先在 `37e6c519` 复验,事故**仍复现**(冲突文案只有前半句、按钮任何来源都写「更像这个」)。BUG-691 填回 690↔692 的真空号。只改文案层:冲突文案补满三层、冲突态按钮改「改用校正结果」+ 逐列写明 hh:mm→hh:mm;打分/判据/采用 RPC 未动,Skill 未 bump(只补 references §6.1)。tsc 0、lint 0 error、全量 3335/fail 31 与基线失败清单逐条一致。**未推 staging** |
|
||||
|
||||
| `TASK-rectification-birth-time-provenance-20260914.md` | `PROGRESS-rectification-birth-time-provenance-20260914.md` | 与上游流程对照发现的缺口(上游 R2):录入时已问「医院记录 / 家人记得大概 / 只知道时段」并落库 `birth_time_source`,但整条校正链只在放宽窗口时用过一次,决策与文案一律不看它——家人推算的时间和出生证在系统里等同对待,输出还直接称「你的出生时间」。本单把来源标签接进投影并分档措辞(BUG-690) | 待验收 | `codex/rectification-birth-time-provenance-20260914` |
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# 真人验收清单 · 记录与校正区间冲突文案(BUG-691)
|
||||
|
||||
自动化能锁住文案与按钮措辞,但造不出「有医院记录、且校正区间不含那一分钟」的真实会话。以下需要在 staging 用受控账号照做。
|
||||
|
||||
前置:`https://staging.jyotisha.chat/api/health` 的 `deployment.gitCommit` 等于本单合入后的 staging 提交。
|
||||
|
||||
## 1. 造一个冲突案子
|
||||
|
||||
1. 资料里新建一个虚构出生资料(不得用真人),出生时间填一个整分钟,**来源选「医院记录」**。
|
||||
2. 开一次生时校正,正常回答采集与区分题,直到出交付卡。
|
||||
3. 看交付卡顶部的范围。**需要范围不含你填的那一分钟**——若恰好含在范围内,换一个把记录时间填在窗口边缘的资料重来(例如资料写 05:12,而范围收在 04:48–05:07)。
|
||||
|
||||
## 2. 冲突态该看到什么
|
||||
|
||||
- [ ] 来源小字写满三层,措辞近似:「出生记录时间 05:12,默认仍按这个时间排盘。你说的这些经历指向另一段时间,相差 5 分钟。你可以改用校正结果,也可以继续用记录」。
|
||||
- [ ] 每一列的按钮写「**改用校正结果**」,不是「更像这个」。
|
||||
- [ ] 每个按钮下面有一行灰字,写明这一列换的是哪两个钟点:「选它之后,排盘会从出生记录时间 05:12 换成 04:53」。三列各写各的目标分钟,不得三列都写同一个。
|
||||
- [ ] 卡片形状没变:仍是至多三列并排、共有性格句只在顶部写一次、底部边界句还在、「查看验证报告」默认收起。没有多出任何按钮,也没有确认弹窗。
|
||||
|
||||
## 3. 不得出现的说法(D4)
|
||||
|
||||
通读卡片、旁白和采用后的收尾句,以下任何一种都算不通过:
|
||||
|
||||
- [ ] 「你的出生记录错了 / 记录不准 / 记录有误」
|
||||
- [ ] 「以证据为准 / 以记录为准 / 应该信……」
|
||||
- [ ] 「校正结果无效 / 不作数」
|
||||
- [ ] 把采用后的分钟说成「已确认的出生分钟」(BUG-587 红线)
|
||||
|
||||
## 4. 采用路径仍然正常
|
||||
|
||||
- [ ] 点「改用校正结果」后按钮依次显示「正在采用…」「已采用」,整张卡留在原处不闪。
|
||||
- [ ] 已采用的那一列不再显示第 2 节那行灰字。
|
||||
- [ ] 采用后的收尾句与卡片同一列对齐,没有 spinner、没有采用状态条。
|
||||
- [ ] 刷新页面后历史 Case 能正常打开(本单未 bump Skill 版本,但仍要确认,见 BUG-621 教训)。
|
||||
|
||||
## 5. 非冲突态回归(必须与今天一致)
|
||||
|
||||
- [ ] 医院记录那一分钟**落在**范围内:小字写「出生记录时间 hh:mm,落在目前范围内」,按钮仍是「更像这个」,按钮下无灰字。
|
||||
- [ ] 来源是「家人记得」:小字写「与你填的大概时间 hh:mm 相差 N 分钟」,按钮仍是「更像这个」。
|
||||
- [ ] 来源是「只知道时段」:小字写「与你给的时间段 hh:mm 相差 N 分钟」,按钮仍是「更像这个」。
|
||||
|
||||
## 6. 记录
|
||||
|
||||
任何一条不通过,写成 `TASK-rectification-record-conflict-copy-fix-<日期>.md`,并在 `docs/BUG_HISTORY.md` 里关联 BUG-691。
|
||||
Reference in New Issue
Block a user