Files
Jyotisha/docs/tasks/TASK-rectification-grounding-20260927.md
T

13 KiB
Raw Blame History

TASK · 生时校正:旁白事实有据 + 去掉重试按钮 + 给模型的资料瘦身(2026-09-27)

基线

  • 开工时 git fetch 后的最新 origin/staging(写进 PROGRESS)。诊断基于 599fe7a9。
  • 分支 codex/rectification-grounding-20260927,工作树 .worktrees/rectification-grounding-20260927。
  • 并行:codex/consult-evidence-card-20260927(普通对话数据卡)正在改 frontend/src/app/api/consult/**、frontend/src/lib/stream-agent-response.ts、frontend/src/mastra/index.ts、consultation-* 与可能的 jyotish-vedic-astrology Skill。本单不得修改这些文件;两单都可能改 skills/skill-package-registry.json、CHANGELOG.md、docs/BUG_HISTORY.md、docs/tasks/README.md,后合入的一方负责 rebase 合并,保留双方条目。

事故实证(诊断 2026-09-27,真实 Agent + 记录提示词的假模型 + 本机真实引擎,公开 AA 盘;行号按符号定位)

复现脚本与数据:/tmp/claude-1000/-workspace-Jyotisha/725df462-ac7f-4544-90b7-60fba1501ed7/scratchpad/zz-diag-rect-context.test.ts,同目录 measure*.json、regen.json、offer.json、compare-projection.json、jolie30.json(执行方可参考并改写成提交的回归测试)。

主链没有 BUG-1053 那种盲写:每次尝试一个 agent.stream,写正文的步看得到 read-case 与 batch 结果;题干(服务端校验 + 模板退回)、验证报告(服务端拼装)、采用旁白(结构化事实 + 数字白名单)、兜底句(batch recaps)均有依据。问题如下:

  • D1(复发自 BUG-588,已复现)服务端范围句被证据轮裁句裁掉,旧范围反而留下。 frontend/src/lib/rectification-agentic/v9/agent-run-attempt.ts(withRangeChangedAfterEvidence / withRescoreSkippedNotice,约 L588–600)先把「范围从 A 变为 B。」接到正文末尾;agent-run-finish.ts(action === "evidence" 分支 trimSpokenTurnForInterview,约 L169)再按 collect-prompt.ts trimEvidenceTurnBody(超过两句只留首句)裁掉。模型写两句 → 落库只剩首句,流式时范围句先闪出再被 replace 撤回;模型首句带 read-case 里的旧范围 → 落库旧范围。「这次没有重新比较」「候选比较这次没跑成」同样被裁。batch 返回(rectification-v9-tools.ts 约 L1706–1733)没有重算后的范围,模型唯一的范围来源是旧值;系统提示(frontend/src/mastra/agentic-rectification.ts 约第 39 行)又鼓励「有收窄就说进度」。证据轮与交付轮正文没有任何数字/时刻校验。
  • D2(新,BUG-1053 同型,已复现)「重试」重新生成是盲写且不校验就落库。 v9/regenerate-turn.ts(约 L150–157)agent.generate 只给旧正文 + read-case,Skill 未注入,输出不剪问句、不补范围句、不查数字/禁用词,直接 regenerate_agentic_rectification_turn。复现:写出「范围收在 09:00–09:05,吻合率 90%」原样落库,实际范围 08:54–09:24。入口在 frontend/src/components/rectification-agentic-chat.tsx(最新助手消息操作栏,约 L589)。
  • D3(新,已确认)read-case 超 6KB 时先清空对话与证据。 v9/turn-decision.ts enforceTurnDecisionBudget(约 L268–286)超限清空 recent_turns、relevant_evidence_summary,保留每个约 458 字节的候选定位元数据。模型消息里没有历史(agent-run-messages.ts 约 L46–74),read-case 是唯一对话记忆。9 个候选、2 条短对话即触发;约 7 个及以上候选的常见窗口都会「失忆」。现有测试只断言不超上限。
  • D4(BUG-588 / BUG-569 同族,按代码确认)点选题答案里带日期经历时,范围变化无人说。 v9/agent-route-typed-message.ts(约 L147–170、L227–247)deferFollowup 时 applied.narration 不落库;answer-choice.ts persistV9ChoiceAction 已先写入新推断,随后 Agent 轮 prepare 读到的 rangeBeforeCompare 已是答题后范围,两边都不写范围句。
  • R1(BUG-593 旁路) offer-candidates 返回完整投影(rectification-v9-tools.ts 约 L2139–2187),含 dasha_agreement_pre_inference、house_table_pre_inference、representative_time_pre_inference;compare 里 engine_indistinguishable_width_minutes 可被引用。compare 返回的验证报告 Markdown 出现两次(skill_verification_report 与 range_delivery.verification_markdown 逐字相同)。
  • R3 交付轮「三句(范围、吻合率、边界)」指令在打字证据轮无法落地:写正文时还没做交付决定(agent-run-finish.ts persistNextInterviewIfIdle),也没有吻合率数据。
  • R4 Mastra 自动注入 <available_skills> 与「请调用 skill 工具」,与引导语「不要调用 skill」矛盾,还带出临时目录路径。
  • 体量(公开盘 30 分钟窗、3 件事、9 个候选;token 为经验估算):Skill 10.0.31 全文每次调用重发约 10.7K 字符(证据轮只用得上 §5、§7,约 30%);14 个工具 schema 每步重发约 13.7KB;read-case 5.8K 字符中 4.1K 是候选元数据;compare 返回 32K 字符;offer 返回 100K 字符(含 31KB candidate_contrast_packet、27KB 探针)。一轮典型证据轮 4 次调用合计约 59K 输入 token,每次固定约 14K。

根因

服务端事实句与模型正文共用一条「先拼后裁」的管线,事实句不受保护;重新生成沿用了 V5 之前的自由重写、丢了校验;read-case 的预算裁剪顺序把最该留的对话记忆放在了最先被砍的位置;给模型的工具返回和 Skill 没有按轮次瘦身。

决策记录(产品 2026-09-27)

  • P1 生时校正里去掉「重试(重新生成)」按钮(产品偏好:多余入口宁可删除也不修)。普通对话的重试不受影响。服务端重新生成路径若只服务于校正则一并删除;数据库函数 regenerate_agentic_rectification_turn 本单不删(AGENTS §7.6 两轮规则:先下线代码,另开单再退役函数)。
  • P2 资料瘦身与四个修复一起做:read-case 瘦身与预算顺序、compare/offer 剥离与去重、batch 补重算后范围与是否交付、Skill 按轮次切片、关掉 Mastra <available_skills> 注入。
  • P3 证据轮与交付轮的范围、时刻、吻合率只由服务端说;模型正文里带时刻或百分比的句子,若与服务端事实不符则整句丢弃(AGENTS 三通道原则:正则只当门不当刀,不就地删词)。
  • 本单不推翻 BUG-606 / BUG-615 的「证据轮正文短」口径:裁句仍作用于模型正文,只是服务端事实句不再参与裁句。

硬红线

  1. 服务端事实句(范围变化、未重算、比较失败、以及 D4 的答题范围句)永不参与裁句,落库与流式最终态一致(不得先出现再被 replace 撤回)。
  2. 落库正文中出现的任何 HH:MM 区间 / 代表分钟 / 百分比,必须等于服务端当轮事实(白名单),否则该句不落库。测试用两句正文、首句带旧范围的真实 runV9AgentTurn 场景(诊断复现 1、2),以及带编造吻合率的场景。
  3. 9 个候选、若干条对话时,read-case 仍保留 recent_turns 与 relevant_evidence_summary;超限时先砍候选明细(保留 time / score / status / cluster_range),最后才动对话与证据摘要。锁回归。
  4. 不改打分、候选生成、交付门槛、收敛规则、题目选择逻辑;不改 Python 引擎;不动冻结计分文件(ERR-110)。瘦身只改给模型看的投影,不改落库的推断与回执。
  5. 历史校正会话仍能打开(BUG-621):若 bump Skill,旧版本快照保留、registry 标 deprecated。
  6. 前端红线全套(tsc 0、lint 0 error、全量测试 Node 22 失败名单与基线逐条一致、/ ○ Static、gzip ±2%、改断言三栏);全量 Python 门禁集必跑(含 tests/test_api_server_growth_contract.py,handler 伪造点不得增长、注释里也不得出现该字面量)。
  7. 隐私 AGENTS §8;只用公开 AA 盘或虚构数据。
  8. 禁止 git stash;只 git add <具体路径>,提交前看 git diff --cached --stat(ERR-112);不推送。

任务分解(每条带验收标准)

T1 D1 修复:事实句不参与裁句 + 数字白名单(BUG-1055,复发自 BUG-588)

  • 顺序改为:先对模型正文执行证据轮裁句与数字白名单(P3),再追加服务端事实句;流式不再先接后撤。
  • batch 工具返回补上重算后的 credible_range 与「本轮是否交付」,模型不再只能用旧值;系统提示「有收窄就说进度」改为「范围由系统说,你不写时刻和百分比」。
  • 验收:诊断复现 1、2 与编造吻合率场景转为回归测试并通过;「这次没有重新比较」「候选比较这次没跑成」保留;BUG-588 原测试不弱化。

T2 D2:去掉生时校正的重试按钮(BUG-1056)

  • 校正消息操作栏不再显示重试;普通对话不变。服务端重新生成入口对校正会话返回明确的不可用(或整条删除若无其他调用方);删除随之无用的代码与文案。
  • 验收:UI 测试(校正消息无重试、普通对话有);接口测试;DESIGN.md / VOICE.md 同步;数据库函数不动并在 PROGRESS 记「待另开单退役」。

T3 D3:read-case 瘦身与预算顺序(BUG-1057)

  • 候选只留 time / score / status / cluster_range;删掉与 inference.candidates 重复的 candidate_summary.candidates;超限时先砍候选明细、最后才动 recent_turns 与证据摘要。
  • 验收:红线 3 回归;9 个候选时 read-case 体量与内容对比表写进 PROGRESS。

T4 D4:点选题 + 带日期经历路径的范围句(BUG-1058,关联 BUG-588 / BUG-569)

  • deferFollowup 路径把答题前范围传给随后的 Agent 轮,或把 applied.narration 的范围句按 T1 规则并入正文(二选一,写明理由)。
  • 验收:真实路由级回归:点选题答案带日期经历、范围变化时,落库正文有且仅有一句服务端范围句。

T5 compare / offer 投影剥离(R1、R3)

  • offer 给模型的投影走与 compare 相同的剥离(去掉 *_pre_inference、对照包、探针,保留交付所需的结论字段);验证报告 Markdown 只留一份;engine_indistinguishable_width_minutes 不给模型。
  • 交付轮的正文指令与「写正文时是否已知交付」一致(配合 T1 的「本轮是否交付」)。
  • 验收:投影合同测试(真实引擎响应 fixture,AGENTS §7.4);offer / compare 模型可见体量前后对比表;BUG-593 原测试不弱化。

T6 Skill 按轮次切片 + 关掉 <available_skills> 注入(R4)

  • 证据轮只给 Skill §5、§7 等本轮相关章节(切片规则写成代码常量并测试);删掉只在 full_diagnostics 里才有的字段说明或改到需要时才给;关掉 Mastra 自动 skills 注入。
  • 可选:按轮次收窄每步给模型的工具 schema(只给本轮会用到的),不影响现有工具调用路径时才做。
  • 若 Skill 文本改动则 bump 版本(快照、registry sha、旧版 deprecated),CHANGELOG 写明。
  • 验收:记录提示词的假模型测试断言证据轮不含无关章节、不含 <available_skills>;典型证据轮每次调用的固定开销与合计输入 token 前后对比表(目标:固定开销从约 14K 降到 8K 以下,给出实测)。

T7 记录

  • docs/BUG_HISTORY.md:BUG-1055~1058 完整记录(D1 写「复发自 BUG-588」及为何旧测试没拦住:只用单句正文);R1 在 BUG-593 下补充。
  • CHANGELOG;frontend/DESIGN.md(操作栏);frontend/docs/VOICE.md(范围由系统说的口径);docs/tasks/PROGRESS-rectification-grounding-20260927.md(体量前后对比、红线测试清单、失败名单对比、三栏改动);docs/testing/rectification-grounding-20260927.md(真机:说一件带年月的事看范围句是否完整留存;候选多时说「那年」看是否记得;点选题顺手打字补经历看有无范围句;校正消息下没有重试按钮);docs/tasks/README.md 本单一行改「待验收」。

让步顺序

  1. T1、T2、T3、T4 必须完成(用户可见的错误)。
  2. T5 必须完成剥离部分;去重可降级。
  3. T6 的 Skill 切片与关注入必须做;工具 schema 收窄可留下一单。

开工前置命令

cd /workspace/Jyotisha && git fetch origin --prune
git worktree add -b codex/rectification-grounding-20260927 .worktrees/rectification-grounding-20260927 origin/staging
ln -s /workspace/Jyotisha/frontend/node_modules .worktrees/rectification-grounding-20260927/frontend/node_modules
cd .worktrees/rectification-grounding-20260927 && git status -sb
export PATH=/exec-daemon:$PATH   # Node 22

先读:AGENTS.md(§5–§8)、frontend/AGENTS.md、frontend/DESIGN.md、frontend/docs/VOICE.md、docs/BUG_HISTORY.md 的 BUG-569、588、593、606、615、621、1047、1053、docs/research/pre_work_error_ledger.md ERR-110/111/112。开工先在未改动的基线上跑全量前端测试(Node 22)与全量 Python 门禁集,存日志作对比。

BUG 编号

本单预留 BUG-1055(D1)、BUG-1056(D2)、BUG-1057(D3)、BUG-1058(D4);并行的数据卡单新缺陷从 BUG-1059 起。开工与提交时各核对一次最大号。