Files
Jyotisha/docs/tasks/PROGRESS-rectification-fewer-probes-card-20260926.md
T
Jesse_ChenandClaude Opus 5.5 7203d94e9c
Independent Staging Quality Gate / validate (push) Successful in 11m49s
Independent Staging Quality Gate / publish (push) Successful in 3m44s
fix(rectification): 区分不开时不显示「最可能」副标题(验收补改)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 14:45:11 +08:00

15 KiB
Raw Blame History

PROGRESS · 生时校正:减少无效追问 + 交付卡以区间为主(2026-09-26)

  • 任务书:docs/tasks/TASK-rectification-fewer-probes-card-20260926.md
  • 分支:codex/rectification-fewer-probes-card-20260926,基线 origin/staging abb05b67(代码与线上 8a409434 相同)
  • 执行:Claude 子代理(直接执行模式,产品授权)。未推送。
  • 产品调整,不开 BUG 号。Skill 10.0.29 → 10.0.30。

结论先行

决策 做了什么 状态
D1 引导补经历最多 2 条 前端题池按 每个校正最多 2 道 引导窗口题(GUIDED_WINDOW_CASE_LIMIT = 2)。引擎 GUIDED_COLLECT_LIMIT 没有改,见下方「偏离」 完成(实现位置偏离任务书字面)
D2 定向题问完直接出卡 能挡住出卡的线只剩「七条定向线 + 跳过线一次重问 + 进行中的年月追问」;没问到的引导窗口题不再挡卡(cardHoldingLinesExhausted)。区间、淘汰、采用门、确认门、刷新未试不出卡(BUG-654/656)都不变 完成
D3 区间为主标题 主标题「目前范围 05:00–05:15(对照了 N 件经历)」不变,下面加副标题「最可能 05:07」(代表分钟) 完成
D4 百分比只在差距明显时显示 第一名比第二名高 ≥5 个百分点才每列写「相对可能性 N%」;否则不写数字,卡上一句「这几个时刻目前区分不开,补一件带年月的经历能帮助分开。」只有一列时两样都不写 完成
D5 不做 没改打分、淘汰阈值、确认门、45 天闸门 遵守
硬红线 1 离线回放 真值在区间内的比例没有下降(±30、±60 各多保住 1 例);区间宽度中位差 1 分钟(±10 窄 1,±30、±60 宽 1);平均提问 11.4 → 7.8 字面「不变」未完全满足,数字如实列在下面,请验收方裁决

偏离:D1 为什么不改 GUIDED_COLLECT_LIMIT

任务书写「GUIDED_COLLECT_LIMIT 由 6 改为 2」。这个常量在 scripts/rectification/event_probes.py,而该文件属于冻结评分身份(scripts/research/sealed_holdout_rerun.py PRODUCTION_FILES)。实测改这一行后 Python 快速门 4 条失败(tests/test_rectification_validation_integrity_gate.py:frozen_record_mismatch / production_scoring_sha256 不等),且记忆化 golden 也要改。BUG-1047 的防复发写明:改冻结评分文件(即使输出不变)必须在任务书里列出重新冻结验证记录。本任务书没有授权重新冻结,所以:

  • 引擎仍按 6 条排好序给窗口;前端题池在同一个校正里只问前两道没问过的窗口,第三道起不再出(新一轮引擎回执带来的新窗口也不会变成第三道)。
  • 对用户效果与「上限 2」相同,而且比「每张回执 2 条」更严(原来答完一题后引擎换了候选集,会再冒出新窗口)。
  • event_probes.py、golden 零改动;验证完整性门禁 4 条保持绿。

若产品仍要引擎侧也改成 2,需要另开一单写明 sealed holdout / reported offset 重新冻结。

离线回放(硬红线 1)

脚本 scripts/research/fewer_probes_card_replay.py,结果 docs/research/fewer_probes_card_replay_2026_09_26.json。

口径与 guided_collect_holdout_2026_09_16.json 同源:同一份 v4 开放集(20 例公开 AA 名人数据)、同样六道辨别题按真值作答、同样把引导窗口事件注入在真值候选自己的边界日期上(truth,理想作答),另跑 opposite(离真值最远的剩余候选的边界)做对照;三档半径 ±10 / ±30 / ±60。直接复用 guided_collect_holdout_replay.py 的 posterior_state、precision_gate、window_boundary_dates、synthetic_event。

与 09-16 脚本的唯一区别:09-16 在第一次达到精度门槛时就停(量「几件能达标」);这里按上线规则比较最终交付区间:

  • 改前:引导池问完才出卡(BUG-751),回执里的窗口(上限 6)全部问。
  • 改后:一个校正最多问前两道窗口(D1),七条定向线问完就出卡(D2)。
  • 七条定向线两边相同,不建模;提问数 = 6 道辨别题 + 问到的引导窗口题。

truth(理想作答)

半径 六题后:真值在区间内 / 宽度中位 改前:真值在区间内 / 宽度中位 / 平均提问 改后:真值在区间内 / 宽度中位 / 平均提问 区间完全相同的例数
±10 20/20 · 15 20/20 · 15 · 11.4 20/20 · 14 · 7.8 18/20
±30 20/20 · 33 19/20 · 33 · 11.4 20/20 · 34 · 7.8 13/20
±60 20/20 · 56 19/20 · 52 · 11.4 20/20 · 53 · 7.8 14/20

opposite(对照)

半径 改前:真值在区间内 / 宽度中位 / 平均提问 改后:真值在区间内 / 宽度中位 / 平均提问 区间完全相同
±10 20/20 · 15 · 11.4 20/20 · 15 · 7.8 19/20
±30 20/20 · 33 · 11.4 20/20 · 34 · 7.8 17/20
±60 20/20 · 54 · 11.4 20/20 · 53 · 7.8 14/20
  • 平均引导窗口题:改前 5.4 → 改后 1.8(有的例子引擎给不满 6 / 2 条)。
  • 精度门槛达标例数两边相同(±10:2/20;±30:1/20;±60:0/20),与 09-16「引导补件新增达标 0 例」一致。
  • 120 行里 25 行最终区间不同:改后更窄 6 行、更宽 19 行。
  • 改前丢了真值的两例都是多问出来的:±60 一例被收成 13 分钟、±30 一例被收成 5 分钟,真值都落在外面;改后这两例都保住真值(区间 55 / 35 分钟)。也就是说,多问的窗口题有时把区间收窄到错误的位置。
  • 与红线的差距:宽度中位差 1 分钟、真值比例只升不降。字面「均不变」不成立,只能说「真值不降、宽度中位 ±1 分钟」。不改代码去凑这个数。

方法局限(继承自 09-16 同口径,未修)

  • 窗口年份上限取 today.year,不看月份,所以注入的事件可能落在 2026-09-16 之后(09-16 JSON 里就有 2026-10-27 这类注入日期)。两边同口径,比较仍成立,但它不是真实用户能报出的事。
  • 改前模型只问一张回执里的窗口;真实线上答完一题后引擎会换回执、可能再冒出新窗口,所以改前真实提问数 ≥ 11.4,节省幅度只会更大。
  • 七条定向线不建模,提问数只算辨别题 + 引导题。

实现清单

文件 改动
frontend/src/lib/rectification-agentic/v9/collection-question-pool.ts 新增 GUIDED_WINDOW_CASE_LIMIT = 2,guidedWindowPool 在本校正已问满 2 道窗口时返回空;新增 cardHoldingLinesExhausted(进行中的年月追问 + 跳过线重问 + 七条定向线,不含窗口)
frontend/src/lib/rectification-agentic/v9/decision-from-dossier.ts narrowingExhaustion 的 guidedCollectExhausted 改用 cardHoldingLinesExhausted(仍要求刷新已试)
frontend/src/lib/rectification-agentic/v9/method-followup.ts 出卡状态(sessionOutcomeAllowsDelivery)下,计划的收尾补问不再带引导窗口——否则卡出来了,下面还挂着一道「某年某月之间有没有什么事」、「更像这个」被锁。跳过线重问与七条定向线照旧
frontend/src/lib/rectification-agentic/core/rectification-decision.ts 只改注释:mayDeliverOnPrecision 逻辑不变
frontend/src/lib/rectification-agentic/user-copy.ts RANGE_DELIVERY_PERCENT_MIN_GAP = 5、rangeDeliveryShowsPercents、rangeDeliveryMostLikely、rangeDeliveryIndistinct,并登记到 listUserVisibleCopy
frontend/src/components/rectification-range-delivery.tsx 副标题「最可能 HH:MM」;按 D4 显示百分比或那一句
frontend/src/app/globals.css .rectification-range-delivery__most-likely、.rectification-range-delivery__indistinct
frontend/DESIGN.md / frontend/docs/VOICE.md 交付卡一节、出卡时机、D3/D4 文案
skills/jyotish-birth-time-rectification/**、versions/10.0.30/、skills/skill-package-registry.json、case-status.ts Skill bump 10.0.30(sha256 ade7b748…102c,10.0.29 标 deprecated、快照保留,历史校正按绑定版本打开不受影响——BUG-621)
scripts/research/fewer_probes_card_replay.py、docs/research/fewer_probes_card_replay_2026_09_26.json 离线回放

Skill 为什么要 bump:原 SKILL.md 写「所有线(含引导窗口题、跳过线重问、未覆盖领域题)问完后……才交付目前范围」,candidate-comparison.md 写「每列写相对可能性」,都与 D2 / D4 相反,不改会让 Agent 读到错误规则。改了三处:SKILL.md 出卡句 + 引导题「一次校正最多两道」;conversation-strategy.md 同步(它还残留 10.0.27 的「出卡须 precision_gate_met」旧句,一并改正);candidate-comparison.md 卡片结构与百分比规则。

测试

前端(Node 22.14.0)

项 结果
tsc --noEmit 0 错
npm run lint 0 error(126 warnings,均为既有;改动文件无新增 warning)
npm test 4012 条 / 24 fail / 27 skip;基线(同代码 origin/staging,Node 22)4002 / 24 / 27
失败清单对比 24 条与基线逐条同名(全部是 Docker / DB 套件),新增失败 0
测试名单对比 消失 0;新增 10(frontend/tests/rectification-fewer-probes-card-20260926.test.ts)
npm run build -- --webpack 通过;/ 仍 ○ (Static)
首屏 gzip(rootMainFiles 4 个文件) 130933 B,与基线 130933 B 相同(0%)

新增 10 条测试覆盖:D4 阈值(5 点、顺序无关、单列不显示);D3 标题与副标题;D4 差距 ≥5 显示三列百分比且无那句;差距 <5 无任何数字、只有一句、三列与排序不变;文案登记与 VOICE 一致;D1 每校正 2 道(:next 重问算同一道、进行中的不算、满额后落到定向线);D2 窗口未问不挡卡、跳过线重问与进行中的年月追问仍挡卡;D2 门槛未达也按现行规则出卡、确认门不开;D2 出卡状态(completed_with_range / provisional_range / adopt_representative)的下一问不是引导窗口题,采集状态仍会问。

改动的既有断言(三栏已写在测试文件里)

只有 Skill 版本号:15 个文件里的 RECTIFICATION_SKILL_VERSION / skill_version / 包路径 "10.0.29" → "10.0.30",4 个文件里的 /^version: 10\.0\.29$/ → 10\.0\.30,skill-registry.test.ts 的版本与 sha256。每处上方一行「原值 / 新值 / 原因:D2 出卡句与 D4 卡上百分比规则写进 Skill(2026-09-26)」。没有其他既有断言被改动或弱化。

Python

项 结果
快速门 pytest 集(gate-pytest-args) 948 passed / 1 skipped,与基线相同
tests/test_event_probes_guided_windows.py、tests/test_rectification_engine_memoization.py 通过(event_probes.py 与 golden 未改)

截图(真实 Chrome 151 headless,CDP,虚构数据)

组件用 renderToStaticMarkup 渲染、挂 next build 产出的正式 CSS,在真实浏览器里截:docs/testing/rectification-fewer-probes-card-20260926/

文件 内容
gap-wide-1280.png / gap-wide-390.png 45% / 30% / 25%:副标题「最可能 05:07」,三列都有「相对可能性」
gap-narrow-1280.png / gap-narrow-390.png 35% / 33% / 32%:无任何百分比,卡上一句「这几个时刻目前区分不开……」

两种宽度页面 scrollWidth 等于视口(无横向滚动),「更像这个」最小高度 44px。这不是登录态整页走查——完整对话里的出卡时机与文案要真机看,清单见 docs/testing/rectification-fewer-probes-card-20260926.md。

观察(未改,留给产品)

  1. 差距 <5 时卡上可能同时出现三句「分不开」:说明行里的「这几个候选按现有信息分不开。」(线都问完时)、参考题用过时的「这两分钟按现有信息分不开,参考题已经用过。」和新加的 D4 句。本单按任务书只加 D4 句,没删另外两句。
  2. 副标题「最可能 HH:MM」在差距 <5 时仍显示(任务书 D3 无条件)。它和「目前区分不开」并存,读起来略拧;边界句「这只是代表性候选……」仍在卡底。
  3. 送卡时若本校正还没问满 2 道引导窗口,交付旁白末尾仍会写「现在还剩 …… 再对照几件经历会更准」,这是邀请用户自己补,不是系统还会追问。
  4. 候选已经明显分开(separation.sufficient)那条老路径不经过精度门槛,采集计划里若还有引导窗口题(本校正不足 2 道时)仍会先问——这不是「为门槛追问」,且受每校正 2 道上限约束,本单未改。

环境缺口

  • 无 Docker:24 条 DB / 部署套件与基线同样失败,已逐条比对。
  • 无登录态与模型凭据:真实对话里的出卡时机、Agent 旁白是否遵守新 Skill 句,留待部署后按 docs/testing/ 清单真机走查。
  • 未推送、未部署。

验收(Claude,2026-09-26)

基于 origin/staging 7ddce2c9 rebase 后独立复跑(Node 22.14):

项 结果
tsc --noEmit 0 错
npm run lint 0 error(126 warning,均为既有)
npm test 4012 / 24 fail / 27 skip;失败名单与基线 test15.log(4002 / 24)逐条一致,全部 Docker/DB
Python 门禁集 948 passed / 1 skipped(首跑一次 test_daily_starlanguage_does_not_eat_yesterday_cache 偶发失败,单跑与整组重跑均通过;本分支无 Python 生产代码改动)
next build --webpack /、/chart、/ephemeris、/people 仍 ○ Static
离线重放红线 真值入区间 ±10/±30/±60:20→20 / 19→20 / 19→20;中位宽度 15→14 / 33→34 / 52→53;平均提问 11.4→7.8。宽度 ±1 分钟视为噪声、入区间率不降反升,判通过
D1 落点 执行方把上限放在前端每 Case 2 条,而不是改引擎 GUIDED_COLLECT_LIMIT(冻结计分身份,需重冻结),认可

验收时补改一处:各列不写百分比(区分不开)时,副标题「最可能 HH:MM」同时隐藏——「最可能」与「区分不开」并排自相矛盾,与产品「区间为主」口径一致。同步改 DESIGN / VOICE / CHANGELOG / 真机清单与 Skill candidate-comparison.md(10.0.30 未发布,快照同改,包哈希 926db1ab…3a13 → ade7b748…102c)。定向复跑 rectification* + skill* 1490 条 0 fail,tsc 0。

遗留给产品:区间 < 5 分差时卡上可能同时出现范围说明、平局句与「区分不开」句;截图见同目录,真机时看是否嫌重复。