From 56722063f2058cc415a0b51879259e7f059b86db Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Tue, 29 Sep 2026 08:37:24 +0800 Subject: [PATCH] docs(tasks): rectification futile-collect stopgap and typed-event scoring research BUG-1084..1089 investigating. Typed events do not narrow the range (BUG-560 consequence) yet the flow keeps soliciting them; product chose stopgap first, research second. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8 --- docs/BUG_HISTORY.md | 77 +++++++++++++++++ docs/tasks/README.md | 2 + ...tification-futile-collect-stop-20260929.md | 85 +++++++++++++++++++ ...n-typed-event-scoring-research-20260929.md | 59 +++++++++++++ 4 files changed, 223 insertions(+) create mode 100644 docs/tasks/TASK-rectification-futile-collect-stop-20260929.md create mode 100644 docs/tasks/TASK-rectification-typed-event-scoring-research-20260929.md diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 6bb16234..551a8e6c 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -14577,3 +14577,80 @@ - 相关记录:BUG-1080 - 复发自:无 - 修复版本:`codex/self-edit-avatar-menu-20260928` 第 4 个提交 + +## BUG-1084 | 生时校正开场后一路邀请补经历,补来的经历不收窄范围 + +- 状态:investigating(Claude 诊断 + 离线复现;修复见 `docs/tasks/TASK-rectification-futile-collect-stop-20260929.md` T1) +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:`core/rectification-decision.ts::mayDeliverOnPrecision`、`v9/collection-question-pool.ts::cardHoldingLinesExhausted`(七条线 + 重问挡卡)、`user-copy.ts::rangeDeliveryIndistinct`、输入框占位、右栏 `refinement_packet` 的「可再补一件…」。 +- 用户现象:产品 staging 真机,31 分钟窗口,开场说 12 件带年份的经历、之后答约 10 张卡,界面「已对照 22 件」,范围始终是整窗;右栏和追问一直请用户再补经历。 +- 触发条件:训练门已开后,交付卡仍等七条线定向题及其重问问完;采集来的经历只进引擎先验。 +- 根因:打字经历只经 `_relative_support` 正比例先验(BUG-560),差距 1–2 分,够不到淘汰线 8 分;`buildInferenceState` 对 `classified_from === "evidence"` 的「是」跳过计分。能动分的只有点选卡 ±2。流程却按 09-16 / 09-26 决策继续索要经历。 +- 已确认事实(虚构出生日 12 例,±15 分钟,事件形状同真机):12 件经历后 11/12 例范围 = 整窗;先验 9–11 分;原始分差一倍的例子换算后只差 8、剪 2 分钟;选择题全按真值作答后宽度中位 17 分钟,≤10 分钟 2/12。 +- 修复:待执行(产品 2026-09-29 D1:采集只为开闸,门开后只问点选卡,问完即出卡)。 +- 验证:待补。 +- 防复发:待补。 +- 相关记录:BUG-560(blocked)、BUG-747~752、BUG-689、BUG-1089 +- 复发自:无(BUG-560 的用户可见后果,旧记录只处理了尺度,未处理流程) +- 修复版本:未修 + +## BUG-1085 | 生时校正交付正文「对照了 N 件经历,事件吻合率 P%」误导 + +- 状态:investigating +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:`user-copy.ts::deliveryTurnNarration`、`frontend/src/mastra/agentic-rectification.ts` 交付三句提示。 +- 用户现象:范围一分没缩,正文写「对照了 22 件经历,事件吻合率 95%」,读起来像很有把握。 +- 根因:N 含不参与收窄的口述经历(BUG-1084);P 是经历吻合度,与候选能否分开无关。 +- 修复:待执行(止血单 T2:删吻合率与件数,改写「用了 M 道选择题」,缩不下去时直说)。 +- 相关记录:BUG-1084 +- 复发自:无 +- 修复版本:未修 + +## BUG-1086 | 答题后剩余区间变成多段时,旁白仍说「范围没变」 + +- 状态:investigating(代码走读确认,待执行方写失败测试复现) +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:`core/credible-range.ts::unionStillValidRange`、`v9/probe-explain.ts::explainRangeChange`、`v9/choice-action.ts::composeChoiceNarration`。 +- 用户现象:中间某段已被排除,旁白仍是「已记录,范围没变;X 领先,Y 落后」。 +- 根因(走读):多段时 `unionStillValidRange` 返回 `null`,`explainRangeChange` 遇 `null` 返回空串,旁白落到「范围没变 + 领先落后」分支。 +- 修复:待执行(止血单 T3,用 `credible_intervals` 比较)。 +- 相关记录:BUG-569、BUG-634 +- 复发自:BUG-634 的旁白分支未覆盖多段情形 +- 修复版本:未修 + +## BUG-1087 | 交付轮同时带出一道采集题(「再问下去也分不开了」+「身体这边再问一次」) + +- 状态:investigating(真机截图;根因未定位) +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:交付轮出口、`guidedRetryPool` / 跳过线重问(候选入口,未确认)。 +- 用户现象:同一轮既显示交付状态与「再问下去也分不开了」,又在气泡末尾问一道健康线重问题。 +- 修复:待执行(止血单 T4,先按事故形状写失败测试,再定位根因写回本条)。 +- 相关记录:BUG-652、BUG-1084 +- 复发自:待定 +- 修复版本:未修 + +## BUG-1088 | 学业质量题一律问「那次上大学」,只记得年份的经历显示成「YYYY 年 1 月」 + +- 状态:investigating +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:`scripts/rectification/event_probes.py::_quality_user_meaning`、`_display_date_label` / `_event_month`(冻结计分文件,ERR-110)。 +- 用户现象:用户说的是某年一次艺考,卡片问「YYYY 年 1 月那次上大学,更接近如愿、将就调剂…」。 +- 根因:学业模板写死「上大学」,不看 `event_kind`;年精度经历 `date_start = YYYY-01-01`,取月不看 `precision`。 +- 修复:待执行(研究单 R0,改文字后按 ERR-110 用新 freeze 路径重新冻结)。 +- 相关记录:ERR-110 +- 复发自:无 +- 修复版本:未修 + +## BUG-1089 | 带年月的打字经历不按选择题规则计分,还挡掉同领域相邻年份的选择题 + +- 状态:investigating(离线研究单待执行;不上线) +- 首次发现 / 最近更新:2026-09-29 / 2026-09-29 +- 影响面:`core/build-state.ts::buildInferenceState`(evidence「是」跳过)、`event_probes.py::_existence_blocked_years`。 +- 用户现象:同一件「某年某月工作变动」,点选卡答「是」动 ±2 分,自己打字说约等于 0;说了之后那一年附近的选择题也不再出。 +- 已确认事实(虚构 12 例):12 件经历里去掉 4 件记得到月的,选择题 5/12 例变多,最终宽度中位 17 → 13 分钟。 +- 根因:计分通道不对称,见 `docs/tasks/TASK-rectification-typed-event-scoring-research-20260929.md`。 +- 修复:未修。研究单量「打字经历按选择题边界规则计分」在 v4 开放集三档是否过门;过门才立实现单,合入前产品确认。 +- 防复发:不得在研究未过门时改先验尺度或淘汰线(BUG-560)。 +- 相关记录:BUG-560、BUG-1048、BUG-1084 +- 复发自:无 +- 修复版本:未修 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index e9d6a30b..e4f3ec12 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -253,6 +253,8 @@ | `TASK-birth-sky-polish-20260928.md` | `PROGRESS-birth-sky-polish-20260928.md` | **天空封面第三轮**:星盘页弹层只留图;封面印「日期 时刻 · 城市」(推翻「不印出生资料」);过场放慢到约 6.5 秒;兑换弹窗改到首条付费消息被拒(402)时再弹;BUG-1080 过场被兑换弹窗挡住 | 已实现待验收(分支 `codex/birth-sky-pacing-20260928`,未推送);BUG-1080 investigating(Chrome 下「弹窗盖住过场」已排除,修复不依赖根因) | BUG-1080 | | `TASK-self-edit-avatar-menu-20260928.md` | `PROGRESS-self-edit-avatar-menu-20260928.md` | **本人可编辑 + 各页头像菜单 + 报告页去说明**:`/people` 本人可编辑出生资料(BUG-1081,`ab6c55f8` 漏掉);次级页头像弹同一账户菜单、弹窗项跳 `/?account=`;我的报告删顶部说明与统计 | 已实现待验收(分支 `codex/self-edit-avatar-menu-20260928`,未推送) | BUG-1081 | | `TASK-mobile-chart-and-confirmed-edit-20260929.md` | `PROGRESS-mobile-chart-confirmed-edit-20260929.md` | **手机星盘 + 确认时间可改 + 天空定格**:iPhone 星盘被宽表撑出屏幕(BUG-1083);confirmed 状态改声明字段也重置排盘时间(推翻 BUG-264 约定);「那一刻的天空」改为重放汇聚→定格→右上角分享;去掉报告星图封面 | 执行中(子代理,分支 `codex/mobile-chart-confirmed-edit-20260929`) | BUG-1083 | +| `TASK-rectification-futile-collect-stop-20260929.md` | — | **生时校正停掉无效补经历循环(止血)**:打字经历不收窄(BUG-560 后果),流程却一路索要,真机 22 件整窗不动;采集只为开闸、门开后只问点选卡问完即出卡;交付正文去吻合率;多段时旁白误报「范围没变」;交付轮带采集题 | 待领取 | BUG-1084~1087 | +| `TASK-rectification-typed-event-scoring-research-20260929.md` | — | **打字经历按选择题规则计分(离线研究,不上线)**:计分通道不对称 + 已入账年份挡题;R0 学业质量题措辞 / 年精度显示成 1 月(冻结文件,需重新冻结) | 待领取 | BUG-1088、1089 | | `TASK-serif-headings-20260928.md` | `PROGRESS-serif-headings-20260928.md` | **全站标题改用自托管宋体、正文保持黑体**:产品推翻 BUG-737「CJK 不用衬线」结论(保留「声明的字体必须可加载」「不落系统宋体」两条);Noto Serif SC SemiBold 按通用规范汉字表 6500 字 unicode-range 切片自托管(改名 Jyotisha Serif SC),swap 不 preload;首页宋体流量 ≤300 KB;先于天空封面单 | 已实现待验收(分支 `codex/serif-headings-20260928`,未推送) | 不开新 BUG;BUG-737 追加说明 | | `TASK-cend-ui-claude-alignment-20260916.md` | `PROGRESS-cend-ui-r1/r2/r3-20260916.md` | **C 端界面向 claude.ai 产品界面对齐(三轮串行 R1→R2→R3,都动 `globals.css`,不得并行)**:根因是 `frontend/CLAUDE_DESIGN.md` 扒的是 **claude.com 营销官网**,它自己在 Known Gaps 里写明 claude.ai 产品界面不在范围内,而 `DESIGN.md:3` 把它当成了产品界面的实现契约。**R1**:`--font-display` 里 Tiempos Headline / StyreneB **从未加载**(无 `@font-face`、`public/` 无字体、`layout.tsx` 只 vendor 了 Inter),中文标题全站落到 **宋体 / SimSun**,波及 20 处含助手回答的 h2/h3(BUG-737);亮色强调色 `#85432f` 与暗色 `#d78064` 不同源,产品拍板亮色换 **Claude coral `#cc785c`**,**易漏点**是 `globals.css:16` 的 `--color-ring` 硬编码在 `@theme inline` 里不跟随 `:root`,另有第四个 `:root` 亮色块(`:4358`)必须同步(BUG-738);`.composer-footer` 常驻 44px + 顶栏 68px + `--composer-reserve` 148px,每屏固定吃掉 216px,模型选择器移进输入框内部、删掉底栏、顶栏收到 46px 并删「分析对象」副标题。**R2**:空状态是营销落地页(hero 卡 + 两张 132px 入口大卡 + 3 列 156px 主题卡),输入框被压在 **800px 以上**内容之下,重排成「问候 + 居中输入框 + 两枚入口 pill + 一排 chip」。**R3**:侧栏两个 `
` 拍平成一条「最近」、星盘的两个入口(侧栏分组 + 账户菜单)收敛到一处、删掉逐条助手头像。**决策记录 D3 推翻 DESIGN.md「报告强调色与应用同源」一句**(报告刻意保留深棕)。原型图 https://claude.ai/code/artifact/da275da6-2954-4f50-99aa-32bb8694d38b(三套画面 + 明暗,页面标题就是建议字体栈的实际渲染)。环境缺口:无登录态无 Chrome,四项真机观感留 `docs/testing/`。BUG 段 737–738 | 待领取 | — | | `TASK-cend-surfaces-claude-alignment-20260916.md` | `PROGRESS-cend-shell-20260916.md`、`PROGRESS-cend-report-20260916.md`、`PROGRESS-cend-rectification-20260916.md`、`PROGRESS-cend-chart-eph-20260916.md` | **次级页面对齐(上一单的续篇,R4→R5/R6,R7、R8 可并行)**:星盘 `/chart`、星历 `/ephemeris`、报告 `/reports` **各是脱离 app 外壳的独立全屏页**,顶部只有一个「返回对话」链接、侧栏整个消失,且三家各写了一套一模一样的 `*-shell`/`*-topbar`/`*-hero` 骨架——与上一单 E5 同根因(营销站 band 结构被套到产品界面)。**R4** 抽只读导航外壳 `AppNavRail`(只用现成的 `GET /api/sessions` + `GET /api/account`,会话行走 `sessionHref` 跳 `/?c=`;**刻意不带**重命名/删除/收藏/归档——那套连着 `Home()` 的乐观更新与回滚,搬过来会撞 useState 增长门禁)。**R5** 星盘五 tab 下划线化 + 参数合表 + 行星表横向滚动;星历日期导航改 `‹ 日期 ›`。**R6** 报告中心卡片网格改行式列表;阅读页加常驻目录。**R7** 生时校正把可信区间从盘面板标题行提成常驻条(窄屏 `.is-compact` 下盘面板是 overlay,现在默认看不到区间),五个 `technique-audit` 折叠块收成两段。**R8** 设置内容区收窄(880px 弹窗里表单铺了 690px)、套餐卡三修饰符收敛成两态。**已解锁**:原挡路的设置单已于 `111b4a84`(BUG-698)合入。**两条不得回退**:BUG-698 的 `@supports (height: 1dvh)` 写法(重复声明回退会被 Lightning CSS 折叠)、BUG-616/617 的报告盘面 grid 实现。默认不占 BUG 号 | **R4–R8 全部已实现并验收合入** | R4:抽出 `AppNavRail`(只读,两个 GET,零写操作)+ `SecondaryShell`,三个次级页并入 app 外壳并删掉各自的 shell/topbar/hero;四个路由渲染标记**完全不变**(`/` `/chart` `/ephemeris` 仍 Static);CSS gzip −0.25%。`/reports/[reportId]` 留给 R6 与目录一起做。两处自身健壮性问题被测试抓到:`usePathname()` 可为 null、`fetch` 可能不存在。差点弄丢 BUG-717 的 eyebrow 文案(已放回)。R8:表单分区收窄到 440px(列表分区不变)、套餐卡三修饰符收敛成互斥的 `is-current` / `is-recommended`,`--highlighted` 删除改为滚动定位;手机端 `order:-1` 改挂 `[data-plan-alias]`(版位不是状态)。测试 3350→3354(净增 4),失败清单与基线逐条一致;`/` 仍 Static;我的干净构建实测 CSS gzip −3 字节。**遗留待产品拍板**:`?plan=` 深链现在完全没有视觉指向,只有滚动位置。R6:报告中心卡片网格改行式列表、阅读页并入外壳并把目录挪到右侧常驻。**任务书 E10 过期**——目录在 `cfcd369d` 就已存在,本轮是挪位置定稿而非从零加。挂外壳带出一个真实打印风险已处理:`.chat-app`/`.chat-panel` 是 `height:100%;overflow:hidden`,裸 `window.print()` 会把九节报告裁成一页,阅读页因此多挂一条只在挂载期生效的 print 样式解锁外壳。「生成中的分节进度」做不了——`REPORT_LIST_COLUMNS` 不返回节数,按 VOICE.md 不许前端编。R7:区间常驻条与盘面折叠收敛。**任务书 E9 也不准确**——对话区顶部早有常驻条 `RectificationTimeline` 且窄屏可见,真正只在盘面标题行的是**代表分钟**;因此没另造第二条,在既有条上补齐代表分钟与已答题数(与盘面同一次 `workingRectificationTime()` 调用)。折叠块实际是 **8 个**不是 5 个。**触发让步顺序第 5 条**:收窄进度未做——服务端无该字段,且 `candidate_range` 会放宽(BUG-572),前端相减会把一次放宽报成收窄,已写进 `BLOCKED.md`。顺带修掉一个**静默失效的旧断言**(`slice(indexOf(A), indexOf(B))` 在 B 改名后变成几乎整份文件,四条 `doesNotMatch` 假通过)| diff --git a/docs/tasks/TASK-rectification-futile-collect-stop-20260929.md b/docs/tasks/TASK-rectification-futile-collect-stop-20260929.md new file mode 100644 index 00000000..6a0d26e2 --- /dev/null +++ b/docs/tasks/TASK-rectification-futile-collect-stop-20260929.md @@ -0,0 +1,85 @@ +# TASK · 生时校正:停掉无效的补经历循环(止血单,2026-09-29) + +## 基线 + +- `origin/staging` @ `47eda7e1`(写作时 head;代码与线上部署同批,开工时以最新 `origin/staging` 为准)。 +- 分支 `codex/rectification-futile-collect-stop-20260929`,工作树 `.worktrees/rectification-futile-collect-stop-20260929`。 +- **串行**:本单先做。研究单 `TASK-rectification-typed-event-scoring-research-20260929.md` 与本单不改同一批文件,可以并行开工;研究单若进入实现阶段,排在本单合入之后。 +- **不得改冻结计分文件**(`scripts/research/sealed_holdout_rerun.py::PRODUCTION_FILES` 的 10 个文件,含 `event_probes.py`、`refinement_packet.py`、`decision_policy.py`),见 ERR-110。本单只动前端与 Agent 提示。 + +## 事故实证 + +产品 2026-09-29 staging 真机(窗口 14:35–15:05,31 分钟):开场一次说了 12 件带年份的经历,之后答了约 10 张卡(其中若干「先跳过 / 记不清」)。界面显示「已对照 22 件」「事件吻合率 95%」,范围始终是 14:35–15:05 整窗。每道题的旁白都是「已记录,范围没变;15:00–15:03 领先,14:40–14:43 落后」。右栏写「可再补一件记得时间的感情或关系变化」。最后一轮同时出现「再问下去也分不开了」和一道新的采集题「身体这边再问一次」。 + +离线复现(Claude,虚构出生日 1993–1995 年 12 个日期,北京,窗口 ±15 分钟,事件形状同真机:8 件只记得年份,4 件记得到月;脚本口径同 `scripts/research/fewer_probes_card_replay.py`,交付区间 = `unionStillValidRange`): + +| 口径 | 结果 | +| --- | --- | +| 12 件经历进引擎后的范围 | 12 例中 11 例 = 整窗 31 分钟,另 1 例 29 分钟 | +| 候选段先验分(`relative_support`) | 约 10 段,全部落在 9–11 分,淘汰要落后 8 分 | +| 原始分差距最大的一例 | 原始分 13.6 vs 28.5(相差一倍),换成百分比后 15 vs 7,只剪掉 2 分钟 | +| 可出的带年月选择题 | 每例 2–8 道 | +| 选择题全部按真值作答后的宽度 | 中位 17 分钟;≤10 分钟 2/12;1 例仍 31 | +| 去掉 4 件「记得到月」的经历(只留 8 件年份) | 选择题 5/12 例变多,最终宽度中位 **13** 分钟(比 12 件时更窄) | + +## 根因 + +1. **开场之后的口述采集不收窄范围。** 打字说的经历只经引擎打分,引擎分按 `decision_policy.py::_relative_support` 正比例换成百分比,差距被压到 1–2 分,够不到 `MIN_SEPARATION_LEAD = 8`(BUG-560,blocked:换尺度未过校准)。`core/build-state.ts::buildInferenceState` 又对 `classified_from === "evidence"` 的「是」跳过(注释称「引擎已计入」),所以这些经历在推断账本上约等于 0。能动分的只有点选卡(每题 ±2)。 +2. **补来的经历反而挡题。** 已入账年份会被 `_existence_blocked_years` 挡掉同领域相邻年份的选择题(上表最后一行)。 +3. **流程仍一路邀请补经历。** 09-16 D2/D6 与 09-26 D2 让交付卡等「七条线 + 一次重问」问完(`core/rectification-decision.ts::mayDeliverOnPrecision`、`v9/collection-question-pool.ts::cardHoldingLinesExhausted`);09-26 D4 的不可分句写着「补一件带年月的经历能帮助分开」(`user-copy.ts::rangeDeliveryIndistinct`);右栏读引擎 `refinement_packet.py` 的「可再补一件…」;输入框占位「继续说你记得的人生经历…」。 +4. **旁白误报「范围没变」。** 中间某段被排除、剩余区间变成不连续两段时,`core/credible-range.ts::unionStillValidRange` 返回 `null`;`v9/probe-explain.ts::explainRangeChange` 遇 `null` 返回空串,`v9/choice-action.ts::composeChoiceNarration` 便落到「已记录,范围没变;X 领先,Y 落后」。 +5. **交付正文的数字误导。** `user-copy.ts::deliveryTurnNarration` 写「对照了 N 件经历,事件吻合率 P%」,N 含不起作用的口述经历,P 与范围宽窄无关;Agent 提示 `frontend/src/mastra/agentic-rectification.ts` 同样要求第二句写吻合率。 + +## 决策记录(产品 2026-09-29) + +- **D1 采集只为开闸。** 口述采集(七条线定向题、跳过线重问、引导窗口题、任何「再补一件」邀请)只在训练门未开(`trainingGateOpen === false`:训练事件 < 3 或领域 < 2,见 `candidate_contrast.py::discriminator_gate_open`)时发起。门一开,只问点选卡(带年月存在题、质量题、风格题);点选卡问完(`refreshExhausted`)即出交付卡。 + - **推翻**:09-16 精度门任务书 D2/D4/D5 与 09-26 `TASK-rectification-fewer-probes-card` D2 中「七条线及其一次重问问完才出卡」「跳过线重问一次」;09-26 D4 不可分句里「补一件带年月的经历能帮助分开」。BUG-747~752 的防复发条里凡要求「七条线全轮到」的,本单起不再适用,执行方在各条下追加「2026-09-29 产品修订:见本任务书 D1」,不删原文。 + - 用户自己主动打字补经历仍照常收下入账,只是不再索要。 +- **D2 交付正文改口径。** 删掉「事件吻合率」和「对照了 N 件经历」。第二句改为「用了 M 道选择题」(M = 本 Case 计分的点选答案数,不含跳过 / 记不清)。范围一分没缩时,要直说「这个窗口按现在的方法缩不下去」,不得暗示补经历能分开。具体措辞对照 `frontend/docs/VOICE.md`,写进 VOICE。 +- **D3 旁白不得在范围变化时说「范围没变」。** 剩余区间变成多段时说出被排除的那段(如「已记录,排除了 14:40–14:43」)。 +- **D4 交付轮不得同时带采集题。** +- **不做**:不改打分、先验尺度、`MIN_SEPARATION_LEAD`、淘汰次数、采用 / 确认门、45 天闸门;不改冻结文件;不动研究单范围(让打字经历计分)。 + +## 硬红线 + +1. 离线回放:v4 开放集(`references/real_case_calibration/minute_rectification_holdout_v4.json`)±10 / ±30 / ±60 三档,按 D1 建模「门开后不再注入口述 / 引导经历」,与基线比:**真值在区间比例不降、宽度中位不变宽**,平均提问数下降。任何一格变差就停,把数字写进 PROGRESS 回报,不得调参数凑。 +2. 不放宽任何置信度边界(AGENTS §8.4、Part B4)。 +3. 全量前端测试用 Node 22(`/exec-daemon/node`),与开工基线逐条一致、新增失败 0;改动既有断言写「原值 / 新值 / 原因」三栏;tsc 0、lint 0 error;`/` 仍 Static;首屏 gzip ±2%。 +4. 改 Agent 提示或 Skill 文本按 CHANGELOG 规则 bump,并在 bump 后验证旧校正会话仍能打开(BUG-621 教训)。 +5. 隐私:测试夹具只用虚构数据;Bug 历史不写真机会话的任何事件内容。 + +## 任务分解 + +- **T1 D1 出卡时机(BUG-1084)** + - `mayDeliverOnPrecision` / `cardHoldingLinesExhausted` 及其调用方:训练门开后,定向七条线、重问、引导窗口都不再挡卡、不再发起;门未开时保持现状。 + - 输入框占位、`RECTIFICATION_COLLECT_WAITING_PLACEHOLDER`、`step-state.ts` 的 `next` 提示、`answer-choice.ts` 的「再说一件带年份的经历后…」在门开后都不再出现邀请句。 + - 右栏 `refinement_packet` 的「可再补一件…」:前端展示层按字段不渲染这一句(不得用中文正则匹配;Python 文件不动),研究单再决定引擎侧怎么改。 + - 验收:单测覆盖「门开 + 点选卡问完 → 交付」「门开 + 七条线未问 → 仍交付」「门未开 → 仍采集」;遍历七个领域的表驱动断言(沿用 BUG-747 的做法)。 +- **T2 D2 交付正文(BUG-1085)** + - `deliveryTurnNarration`、Agent 提示第二句、`rangeDeliveryIndistinct` 改口径;`skill-verification-report.ts` 里 80% / 60% 吻合率的说法若会流进气泡,一并去掉(折叠报告里可保留,标清「这是经历吻合度,不是范围可信度」)。 + - 验收:文案合同测试断言交付气泡不含「吻合率」「补一件」「再说一件」;VOICE 与 DESIGN 同提交更新。 +- **T3 D3 旁白(BUG-1086)** + - `composeChoiceNarration` / `explainRangeChange` 处理「前后区间段数或端点变化」:用 `credible_intervals` 比较,不再只比元组。 + - 验收:先写失败测试复现「中间段被排除 → 旁白说范围没变」,再修。顶栏在多段时显示什么,由执行方核实现状写进 PROGRESS;若也只显示首尾,本单只记录,不改 UI。 +- **T4 D4 交付轮不带采集题(BUG-1087)** + - 按事故形状(交付卡已出、跳过线仍有一次重问)写回归测试,先红后绿;根因写进 BUG-1087。T1 落地后此路径多半不再可达,仍要留测试。 +- **T5 回放与记录** + - 回放脚本放 `scripts/research/`(可在 `fewer_probes_card_replay.py` 上加一个 `--collect-after-gate off` 口径),JSON 结果进 `docs/research/`,数字进 PROGRESS。 + - `CHANGELOG.md`、`frontend/DESIGN.md`(交付卡 / 旁白)、`frontend/docs/VOICE.md`、`docs/testing/rectification-futile-collect-stop-20260929.md` 真机清单(至少:开场说 3 件两领域 → 只出点选卡 → 问完直接出卡;答题排除中间段时的旁白;交付后无采集题;旧会话可打开)。 + +## 让步顺序 + +时间不够时按此顺序保留:T1 > T2 > T4 > T3 > 回放以外的截图。T1 与回放缺一不可合入。 + +## 开工前置命令 + +```bash +git fetch origin --prune +export PATH=/exec-daemon:$PATH && node -v # 22.x +git worktree add -b codex/rectification-futile-collect-stop-20260929 .worktrees/rectification-futile-collect-stop-20260929 origin/staging +cd .worktrees/rectification-futile-collect-stop-20260929/frontend && npm ci && npm test 2>&1 | tee /tmp/futile-baseline.log # 记录基线通过 / 失败清单 +``` + +## BUG 编号 + +开工时核对 `docs/BUG_HISTORY.md` 最大号(写作时 BUG-1083 已被 `TASK-mobile-chart-and-confirmed-edit-20260929` 预留)。本单:**BUG-1084**(补经历循环)、**BUG-1085**(交付正文数字误导)、**BUG-1086**(多段时旁白说范围没变)、**BUG-1087**(交付轮带采集题)。四条已由 Claude 以 `investigating` 登记,执行方修复后补全并改状态。关联 BUG-560(blocked)、BUG-634、BUG-747~752、BUG-689。 diff --git a/docs/tasks/TASK-rectification-typed-event-scoring-research-20260929.md b/docs/tasks/TASK-rectification-typed-event-scoring-research-20260929.md new file mode 100644 index 00000000..966713ca --- /dev/null +++ b/docs/tasks/TASK-rectification-typed-event-scoring-research-20260929.md @@ -0,0 +1,59 @@ +# TASK · 生时校正:让带年月的打字经历参与收窄(离线研究单,2026-09-29) + +## 基线 + +- `origin/staging` @ `47eda7e1`(开工时以最新为准)。分支 `codex/rectification-typed-event-research-20260929`。 +- 性质:**离线测量 + 一处文字修正(R0)**。R1–R3 不改线上计分;有收益才由 Claude 另立实现单,并在合入前由产品确认。 +- 与止血单 `TASK-rectification-futile-collect-stop-20260929.md` 不改同一批文件,可并行。 + +## 事故实证 + +见止血单「事故实证」。与本单直接相关的三条: + +1. 同一件事,做成选择题答「是」动 ±2 分;自己打字说出来,只经引擎百分比先验,差距 1–2 分,而且 `core/build-state.ts::buildInferenceState` 对 `classified_from === "evidence"` 的「是」直接跳过。 +2. 打字经历会挡掉同领域相邻年份的选择题(`event_probes.py::_existence_blocked_years`)。虚构复现:12 件经历去掉其中 4 件记得到月的,最终宽度中位从 17 分钟**降到** 13 分钟。 +3. 质量题模板把所有学业经历都叫「那次上大学」(`event_probes.py::_quality_user_meaning`),真机把「艺考」问成「那次上大学」;只记得年份的经历 `date_start` 为 `YYYY-01-01`,`_display_date_label` 用 `_event_month` 取月,显示成「YYYY 年 1 月」。 + +## 根因 + +- 计分通道不对称:选择题走「大运边界月份 → 候选分两边 → ±2」,打字经历走「引擎原始分 → 百分比先验」。09-26 离线研究 R3 已量出:记得到月的事件在候选相隔约 8 分钟以上(慢档约 20 分钟)时可靠分开,靠的正是大运边界这条通道;引擎原始分在分钟级几乎没有区分力(BUG-560)。 +- 已入账年份挡题的规则是为了防重复提问,但被挡的是能动分的题,留下的是不动分的经历。 + +## 决策记录(产品 2026-09-29) + +- 产品选择「先止血,再研究」:本单只研究「打字经历按选择题同一套规则算分」是否可靠,**不上线**。 +- 不推翻 BUG-560:不改先验尺度、不改 `MIN_SEPARATION_LEAD = 8`、不改 3 次冲突淘汰。本单研究的是新增一条计分通道,门槛同 09-14 / 09-26 研究:头名命中不降、真值在区间不降、宽度中位下降,三档都过才算有收益。 +- R0 是用户可见的措辞错误,允许改 `event_probes.py` 文字,但必须按 ERR-110 用新的 freeze 路径重新冻结(`python3 scripts/research/sealed_holdout_rerun.py --freeze --freeze-path <新路径>`,不得覆盖旧记录),并说明计分输出逐字节不变。 + +## 硬红线 + +1. R1–R3 不改任何线上默认值;研究补丁只在一次调用内临时替换,脚本末尾断言已恢复(沿用 `offline_research_20260926_lib.py` 做法)。 +2. 只用公开 AA 名人(v4)与随机虚构时刻;不用任何真机会话内容。 +3. 同机 A/B:固定 `PYTHONHASHSEED`(ERR-111);每个 JSON 在两次运行下逐字节一致。 +4. 这是开放集回放,不是盲测;报告不得把数字写成准确率。 + +## 任务分解 + +- **R0 措辞修正(BUG-1088)**:质量题按 `event_kind` 选词(入学 / 转学 / 中断 / 考试等,不得一律「上大学」);`precision == "year"` 的经历只显示「YYYY 年」。单测 + 重新冻结 + 计分输出逐字节对比。可先行单独合入。 +- **R1 打字经历当作已答选择题(BUG-1089)**:对每件记得到月 / 日的训练经历,用选择题的同一套边界月份判定(`_evaluate_contexts` 口径)算出各候选的支持 / 冲突,按「是」计 ±2(月精度);只记得年份的分两种口径各跑一遍(不计分 / 只在跨年边界时计分)。v4 开放集 ±10 / ±30 / ±60,指标:头名命中、真值在区间、宽度中位、并列率、提问数。 +- **R2 容错**:沿用 09-26 R1 的做法,随机把 1 件、2 件打字经历的年月挪错 ±1–3 个月,量真值被挤出区间的比例。R1 有收益而 R2 挤出率明显高于 09-26 答错两题的水平(±30 约 7%),判为不过门。 +- **R3 挡题规则**:量 `_existence_blocked_years` 在 v4 上挡掉的选择题数;在 R1 口径下(打字经历已计分),把挡题范围缩到「同领域同年」后宽度与命中的变化。 +- **报告**:`docs/research/rectification_typed_event_scoring_2026_09_29.md` + JSON;一句话结论表(每项:是否建议立实现单)。 + +## 让步顺序 + +R0 > R1 > R2 > R3。R1 没收益时 R2 可只跑 ±30 一档。 + +## 开工前置命令 + +```bash +git fetch origin --prune +git worktree add -b codex/rectification-typed-event-research-20260929 .worktrees/rectification-typed-event-research-20260929 origin/staging +cd .worktrees/rectification-typed-event-research-20260929 +python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45 # 引擎类任务按 AGENTS §9 +PYTHONHASHSEED=0 python3 scripts/research/fewer_probes_card_replay.py --radii 30 --limit 3 --json-out /tmp/smoke.json # 回放链路冒烟 +``` + +## BUG 编号 + +开工时核对最大号。本单:**BUG-1088**(学业质量题措辞 / 年精度显示成 1 月)、**BUG-1089**(打字经历不计分且挡题,`investigating`,关联 BUG-560)。两条已由 Claude 登记。