# 进度:报告开篇解读 + 对话口吻 C1(issue #113,2026-10-27) - 任务书:`docs/tasks/TASK-voice-reading-20261027.md` - 分支:`codex/voice-reading-20261027`(基线 `origin/staging` `9ca933968`) - 执行:Claude(直接执行模式)。BUG-1460(C1)、BUG-1461(R1);staging 合入 #111 后最大号 1459,编号即为最终号。 ## 做了什么 | 项 | 状态 | 说明 | | --- | --- | --- | | C1 对话 | 完成 | `CHART_REASON_RULE` / `HOUSE_LIFE_AREA_RULE` / `TIMING_FOCUS_RULE`;示例改写;读心第 2 条收窄;VOICE 第七条原则补充 | | R1-1 事实包 | 完成 | `scripts/report_render/reading_facts.py`;`professional_report_reference` 接 `include_reading_facts`(只在 full_data + markdown),开关进缓存键,失败只返回 `gaps` | | R1-2 写作 | 完成 | `lib/personal-report-reading.ts`(提示词、重试、超时 120 s)+ `mastra/personal-report-reading.ts`(结构化输出,与合盘写作器同一模式) | | R1-3 校验 | 完成 | 外文、字段名、禁词(宿命 / 病名 / 投资 / 内部说法 / 北交点)、节数与顺序、长度、每节免责 ≤1 | | R1-4 存与读 | 完成 | 存进计算快照 v2 的 `reading` / `readingUnavailable`(不改表);读接口返回 `reading`,与英文版共用一次快照读取;页面在导读之后、引擎正文之前渲染,加「计算依据」,目录首条「解读」;英文不显示 | | R1-5 记账 | 完成 | 报告用量取解读调用的 token,没有解读时为 0;单价结算沿用 `completeUsage` | | R1-6 文档 | 完成 | DESIGN、VOICE、CHANGELOG、BUG_HISTORY、BLOCKED、真机清单 | ## 改动的既有断言(三栏也写在测试里) | 文件 | 原值 | 新值 | 原因 | | --- | --- | --- | --- | | `consultation-voice-contract.test.ts` | 「然后在括号里给出撑住这段判断的盘上依据」「每段最多一处括号」 | 依据写进正文「因为……」,宫位带领域,时间最多三件;旧句不得出现 | issue #113 C1 | | 同上 | 示例标签「括号里是依据的占位」;Bad 起点「多对象题」 | 「「因为」后面的依据是占位」;先是新 Bad「段尾括号复述」 | issue #113 C1 | | 同上 | 父母例括号 `(母亲这条线没有受冲;…)`、事业例括号 `(木星行运 10 宫;…)` | 依据进正文,宫位带领域 | issue #113 C1 | | 同上 | 「用户自己的心全篇最多读一句」 | 只在情绪、关系感受题读;结尾不猜动机 | issue #113 C1 | | 同上 | 是非题例 `不是。(母亲这条线没有受冲;4 宫主落 10 宫)…` | `不是。管母亲的 4 宫(母亲、家和住处)这条线没有受冲…` | issue #113 C1 | | `consult-no-presupposition-20261001.test.ts` | 受冲规则「括号里只写…」;`每段的判断后在括号里给…`;是非题例 | 「依据只写…用白话写进句子」;段规则后接三条新常量;是非题例新写法 | issue #113 C1 | | `consult-plain-speech-20261006.test.ts` | 「括号里的依据最多两条」「括号里只写最能说明问题的一两条」 | 「说出来的依据最多两条」「依据只写最能说明问题的一两条」 | issue #113 C1 | | `consult-upstream-functional-v2-20261002.test.ts` | 妈妈段例括号 | 「因为管母亲的 4 宫…没有受冲」 | issue #113 C1 | | `personal-report-worker.test.ts` | `/inputTokens: 0/` | `/inputTokens: generated\.usage\?\.inputTokens \?\? 0/` | R1 解读按实际 token 记账 | | `personal-report-view.test.ts` | `` | `headings={tocHeadings}`,只在有解读时多一条「解读」 | R1 解读进目录 | ## 环境缺口 见 `BLOCKED.md` 同名条目:无模型 key,真实解读输出和名人生平回测都没跑。 ## 验收数字(执行方自测,合入 `origin/staging` 8e05e4114 之后;Claude 另行复验) | 检查 | 结果 | | --- | --- | | `tsc --noEmit` | 0 错 | | `npm run lint` | 0 error(122 条原有警告) | | `npm test` 全量 | 5233 项,失败 25,与 staging 已知名单逐条相同 | | `next build` | `/` 仍 Static;首屏 gzip 699,756(合入前在 9ca933968 上为 727,789,staging 727,249,+0.07%;合入 #111 后的 staging 基线待复验时实测) | | Python | `test_report_reading_facts.py` 等报告 / 同源卡 / 增长合同 / 隐私 / 脚本数预算 44 项通过;合入前 `tests/test_report_*.py` 全量通过 | | 快速门 `--skip-frontend-runtime` | 通过(初版把新模块放在 `scripts/` 根目录,被脚本数预算拦下,已移到 `scripts/report_render/reading_facts.py`) |