fix(report): use the upstream reader edition for new longform bodies

New reports request reader_main from upstream origin/main 23b9609e.
KP and transit no longer copy an empty vars() dict, solar returns keep
birth_asc_sign_idx, and ordinary projection deletes internal lines whole.
This commit is contained in:
jesse-ux
2026-09-25 02:21:46 +08:00
parent 59c2301838
commit 3c2f7bd559
22 changed files with 3126 additions and 65 deletions
+48 -1
View File
@@ -13598,7 +13598,8 @@
- 现象 / 触发:真实引擎虚构golden仅将LF换成CRLF,正文下载残留22段图盘JSON;新分盘组仍可提取22盘。
- 根因:report-chart-block.ts的FENCE_RE在jyotish-chart语言标记后仅匹配LF,stripReportChartBlocks共用它;旧测试验证LF剥除和CRLF字节等价,没有覆盖含真实围栏的CRLF无JSON。
- 修复:按产品D14有限例外,将语言标记及围栏尾部边界改为匹配`\\r?\\n`;不标准化整篇换行,不改SVG、投影、生成链或下载器。
- 验证:真实虚构reader golden的LF、CRLF、混合换行均输出0段`jyotish-chart`围栏、22个SVG且`ordinaryOutputLeaks`为空;LF普通导出SHA256固定为`3c52e8bfcfcb3ce3852bd5323867a69bc47d0f9aa821a34692172e7d61c6bcb8`。定向测试已通过;尚无部署health证据。
- 验证:真实虚构reader golden的LF、CRLF、混合换行均输出0段`jyotish-chart`围栏、22个SVG且`ordinaryOutputLeaks`为空;当时 LF 普通导出 SHA256 为 `3c52e8bfcfcb3ce3852bd5323867a69bc47d0f9aa821a34692172e7d61c6bcb8`。定向测试已通过;尚无部署health证据。
- 2026-09-25:BUG-1026 把内部词从截断改成整行删除,上述 LF 哈希不再代表当前投影。围栏与 22 个 SVG 的合同仍在。新哈希见 BUG-1026。
- 防复发:report-chart-block与report-export-blocks定向回归覆盖真实golden CRLF/混合输入及独立LF hash锁;禁止只比较两个共同修改后的helper而声称历史输出不变。
- 相关记录:BUG-999/1003;TASK-report-chapter-export-fix-20260924.md。
- 复发自:BUG-999同输出边界的未覆盖换行路径,继承剥离器缺陷,非本轮新增回归。
@@ -13699,3 +13700,49 @@
- 相关记录:BUG-996、BUG-715
- 复发自:无
- 修复版本:本分支,待推送与部署核对
## BUG-1026 | 报告正文仍是审计版,投影把内部句截成半句
- 状态:investigating(本分支已改,未部署)
- 首次发现 / 最近更新:2026-09-24 / 2026-09-25
- 影响面:新个人长报告正文、普通投影、旧报告下载后的可见正文。已生成的 Markdown 不回填。
- 用户现象:正文出现「结论等级规则」、英文 boundary、「producer failed」和异常原文、`full-report://`、页码和「…所有行保持」这种半句,以及删表后留下的说明段。
- 触发条件:生成或打开个人长报告。正文走专业参考渲染;普通投影只拦聊天键,并在 `parameter_sensitive` 处截断句子。
- 根因:本仓最后一次引擎同步 `f2241463`(2026-09-03)早于上游读者版 `f3b5196f`(2026-09-09)。`cfcd369d` 把参考/审计版设成正文。本仓又自行加入结论等级规则、英文 boundary,以及把 error/reason 打进不可用小节。投影的 `projectProseLine` 保留内部词之前的半句,`tableIsInternal` 只删表。
- 修复:新报告请求 `edition: "reader_main"`。读者版从上游 `origin/main` `23b9609e`(含 `f3b5196f`)整段引入 `scripts/pl9_reader_export.py`。缺省 edition 仍是参考版。参考版也去掉上述三处自加泄漏;数据不可用的节整节不输出。投影遇内部词删整行,删表时连同紧邻说明段。报告版本 `pl9_personal_long_report.v3`。旧报告不迁移、不重算。
- 验证:虚构盘「虚构甲」1991-04-07 09:15 的真实引擎读者版 `ordinaryOutputLeaks` 为 0,并含出生资料、Ashtakavarga、标准大运、KP、Year Lord、Tajika、Muntha。定向 Python 与前端投影测试见 PROGRESS。没有登录浏览器,未声称生成过真实用户报告。
- 防复发:读者版 golden 与 `ordinaryOutputLeaks` 不得弱化;新增长报告请求体必须带 `edition: "reader_main"`。旧 `report-density-fictional-reader.json` 继续锁旧报告。投影 sha 改动须写明原值锁的是泄漏输出。
- 相关记录:BUG-999、BUG-1003、BUG-1009、BUG-1020、BUG-1027、BUG-1028
- 复发自:BUG-999。当时的测试只覆盖聊天导出键(`technique_truth`、`workflow_route` 等)和一份已经泄漏的参考版 sha,没有读者版正文,也不认识 PL9 审计词;截断被 sha 锁成了正确输出。BUG-1003 只清附录,BUG-1009 只改事实表列名。
- 修复版本:本分支,未推 staging,未部署。
- sha 三栏:普通投影 `01cc1e03c5adca2833e014156e1162fff12e5cb336e4484c5871859cd878acd7` → `f3aeb8f4b09ba0a78af4ab5e7aee4db32d7499b8e6b1488f2925b35fd91750b9`;LF 下载 `3c52e8bfcfcb3ce3852bd5323867a69bc47d0f9aa821a34692172e7d61c6bcb8` → `b7f6947f6ae6f82e4a972be3c1f2bc50260ed0c5f029847264f40a5ee6ba7b88`。原值锁的是截断后的泄漏正文。
## BUG-1027 | KP 与三项 transit 因空实例字典拷贝失败
- 状态:investigating(本分支已改,未部署)
- 首次发现 / 最近更新:2026-09-24 / 2026-09-25
- 影响面:网页全读路径里的 KP,以及 double transit、transit LL7L、行星聚集。CLI 的 argparse 实例不受影响。
- 用户现象:KP Lord / Sub 节为 blocked,原文是 `'types.SimpleNamespace' object has no attribute 'year'`。
- 触发条件:`_compute_full_reading_for_thematic` 用 `type('Args', (), {...})()` 把字段放在类上。`cmd_kp` 和 transit 执行 `SimpleNamespace(**vars(args))`,实例字典为空,随后读 `.year` 失败。
- 根因:`vars()` 不复制类属性。上游 `origin/main` `23b9609e` 的 API 同样用这种 Args,引擎同样用 `vars()`,空结果时不把异常打进读者正文,所以缺陷一直潜伏。
- 修复:`_copy_call_namespace` 同时读取实例字典和类属性。不改岁差、宫制或 KP 算法。API 主文件未改,类方法数不增加。
- 验证:`tests/test_report_reader_main.py` 用同样的空实例 Args 调用 `cmd_full_reading`,KP 与三项 transit 的 status 不是 blocked,文本里没有 `has no attribute`。
- 防复发:该类 Args 的回归留在上述测试。不要再写 `SimpleNamespace(**vars(args))`。
- 相关记录:BUG-561、BUG-1026
- 复发自:无。这是网页参数构造和 `vars()` 的潜伏缺陷,不是 BUG-561 的渲染分支。
- 修复版本:本分支,未推 staging,未部署。
## BUG-1028 | 太阳返照漏了出生上升,年主恒为火星
- 状态:investigating(本分支已改,未部署)
- 首次发现 / 最近更新:2026-09-24 / 2026-09-25
- 影响面:Muntha、Year Lord、年度章里的冲突句。
- 用户现象:Muntha 为 blocked;Year Lord 恒为火星 / 白羊座;年度句出现「当前优先候选指向conflict between vs Capricorn」。
- 触发条件:`solar_return_full_report` 读取 `birth_asc_sign_idx`,本仓 `calc_solar_return_chart` 的成功字典没有这个键。冲突门用整份字典比较,blocked 与正常值必判冲突;空的左侧对不上冲突正则,落到普通句。
- 根因:`f2241463` 同步上游时漏了 `scripts/solar_return.py` 里设置 `birth_asc_sign_idx` 的那一行。上游当前 `origin/main` 在返照字典里写入该键。本仓冲突门另外比了整份字典,上游已改成只比星座和主星,但仍会把 blocked 字典算进去;本单按 D4 在一侧 `status == blocked` 时不判冲突。
- 修复:成功的返照结果写回 `birth_asc_sign_idx`。Muntha 没有星座序号时 Year Lord 标 blocked,不再默认 0(火星)。冲突门跳过 blocked 一侧,只比较星座与主星。
- 验证:虚构盘 1991-04-07 的 2024/2026/2028 返照都有出生上升序号,Muntha 非 blocked,Year Lord 至少两年不同。一侧 blocked 的 Muntha 不再生成 conflict between。
- 防复发:`tests/test_report_reader_main.py` 锁住出生上升、两年不同的年主,以及 blocked 不冲突。不要在同步时只合一半太阳返照返回值。
- 相关记录:BUG-1026;同步提交 `f2241463`
- 复发自:无。这是同步漏合,不是旧 Muntha 测试覆盖过的路径。
- 修复版本:本分支,未推 staging,未部署。
+12
View File
@@ -2,6 +2,12 @@
Purpose: read this file before substantial project work. It exists to stop repeat mistakes caused by multiple Codex windows, WorkBuddy mirrors, local drafts, backup folders, and partial cloud-git visibility.
## 2026-09-25 · 读者版同步预检与上游 tip
- 工作树 `codex/report-reader-main-20260924`,基线 `514951d7`。Python 3.11.7(Anaconda)跑通 `pre_work_check.py`:远端 verified,碎片扫描与适配器诊断成功。focused tests 22 通过 / 1 失败,仍是 `.workbuddy/skills/jyotish-vedic-astrology` 镜像路径断言。没有制造镜像目录,预检整体 fail,不记为通过。
- 任务书写上游 tip `19195f6e`。`git -C G:\Ferti\yinduzhanxing fetch origin` 后 `origin/main` 是 `23b9609e330dbee70a4725bdc222b125d9b0e39f`,且包含读者版引入提交 `f3b5196f`。读者版按这个 tip 引入,不用 `.workbuddy`。
- 新的同步漏合见 ERR-109。
## 2026-09-24 · 星盘与报告组合版本推送预检
- 产品在获知CRLF合同冲突及构建/真机缺口后授权push到staging。fetch成功,HEAD与origin/staging均为5ff43b47f;写入成功仍须push与ls-remote另核。
@@ -373,3 +379,9 @@ Prevention: 不得把 `vedastro` 当作本地计算能力来源,也不得用
一次 official full snapshot 的请求清单实跑 `_official_full_snapshot_manifest` 数出来是 24 个(`events_overview` 1 + `dasha_all` 1 + `chart_core` 10 + `house_core` 12),fanout 开关 `VEDASTRO_FULL_SNAPSHOT_FANOUT_ENABLED` 的代码默认值就是 `"1"`(第 2520 行)。24 ÷ 5 个每分钟 ≈ 4.8 分钟,期间该进程所有 VedAstro 调用被同一把锁串起来;生产是 2 vCPU 单进程。参照延迟:本机单次 `api.vedastro.org` 往返 0.38 秒,快速模式(fanout 关)一次完整 snapshot 3.65 秒 `status=ok`。生产在国内 VPS,真实 RTT 未测,上述数字只是下限。
Prevention: 前台同步路径不得进入无上限排队,超预算即 fail-fast 降级并让调用方看出是限流而非「服务不可用」;排队总预算必须可配且默认不超过 `VEDASTRO_TIMEOUT_SECONDS`。不得靠调大免费层配额绕过——那是第三方的额度。判断「VedAstro 慢」之前先确认当前是不是无 key 的免费公共模式,以及 fanout 是否开着;两者都属于运行期 env 真相,不能从代码默认值推定。关联 BUG-065、BUG-161、BUG-718、BUG-720。
## ERR-109 | 上游读者版与太阳返照出生上升在同步时漏合 | observed 2026-09-25
本仓引擎同步停在 `f2241463`(2026-09-03)。上游 `f3b5196f`(2026-09-09)才引入 `reader_main`,`origin/main` 在 2026-09-25 fetch 后是 `23b9609e`,不是任务书写的 `19195f6e`。漏掉的还有 `calc_solar_return_chart` 返回值里的 `birth_asc_sign_idx`(上游 solar_return 成功字典会写这个键)。网页全读用 `type('Args', (), fields)()`,上游同样用 `SimpleNamespace(**vars(args))`,实例字典为空时 KP / transit 读不到 `year`;上游空结果不写进读者正文,所以这个缺陷在上游也潜伏。
Prevention: 引擎/上游同步类任务必须 fetch 后核对 `origin/main`,以实际 SHA 为准,并在进度和本台账写明与任务书 tip 的差异。读者版整段引入要带来源提交。不要把 `.workbuddy` 当主仓。同步太阳返照时核对返回键,而不只核对函数还在。关联 BUG-1026、BUG-1027、BUG-1028。
@@ -0,0 +1,46 @@
# PROGRESS · 报告正文换成读者版(2026-09-25)
## 结论
T1–T7 已在 `codex/report-reader-main-20260924` 完成。没有推 `staging`。没有登录浏览器,没有声称生成过真实用户报告。
## 基线与预检
- 分支 `codex/report-reader-main-20260924`,开工 HEAD `514951d7`,跟踪 `origin/staging`。
- 预检:Anaconda Python 3.11.7 运行 `scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45`。远端 `verified`,碎片扫描和适配器诊断成功。focused tests 失败 1 条:`.workbuddy/skills/jyotish-vedic-astrology` 镜像路径不存在。没有制造该目录。预检整体 **fail**,不记通过。这是台账里已有的镜像断言,不是新类错误。
- 上游:`git -C G:\Ferti\yinduzhanxing fetch origin` 成功。`origin/main` 实际是 `23b9609e330dbee70a4725bdc222b125d9b0e39f`,不是任务书的 `19195f6e`。`f3b5196f` 是其祖先。读者版按 `23b9609e` 引入。没有改上游工作区。
## 任务
| 项 | 结果 |
| --- | --- |
| T1 读者版 | 完成。`scripts/pl9_reader_export.py` 整段引入 `_render_pl9_user_markdown`、`render_pl9_parity_markdown` 及其读者版闭包。缺省 edition 仍是参考版。`pl9_ai_density` 依赖不在读者版闭包里,按让步 1 未引入。 |
| T2 生成链 | 完成。`personal-report-longform-generate.ts` 请求 `edition: "reader_main"`。版本 `pl9_personal_long_report.v3`。 |
| T3 自加泄漏 | 完成。结论等级规则、英文 boundary、不可用节的原始 error 都不再进入参考版。空数据节整节不输出。 |
| T4 KP / transit | 完成。`_copy_call_namespace` 不再依赖空的 `vars()`。虚构盘 `cmd_full_reading` 上 KP 与三项 transit 不是 blocked。 |
| T5 Muntha / Year Lord | 完成。返照结果写回 `birth_asc_sign_idx`。2024/2026/2028 的 Muntha 与 Year Lord 不恒定。一侧 blocked 不判冲突。 |
| T6 投影 | 完成。内部词删整行;删表连同紧邻说明。新增 PL9 词进入 `ordinaryOutputLeaks`。英文整段用连续 12 个英文单词,避免误伤行星名。读者版 fixture 命中为 0。 |
| T7 记录 | 完成。BUG-1026/1027/1028 仍空,已使用。1023–1025、1030 未占用。 |
## 断言三栏
| 位置 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `personal-report-density-retry.test.ts` 普通投影 sha | `01cc1e03c5adca2833e014156e1162fff12e5cb336e4484c5871859cd878acd7` | `f3aeb8f4b09ba0a78af4ab5e7aee4db32d7499b8e6b1488f2925b35fd91750b9` | 原 sha 锁的是截断后的泄漏正文 |
| `report-export-blocks.test.ts` LF 下载 sha | `3c52e8bfcfcb3ce3852bd5323867a69bc47d0f9aa821a34692172e7d61c6bcb8` | `b7f6947f6ae6f82e4a972be3c1f2bc50260ed0c5f029847264f40a5ee6ba7b88` | 同上,BUG-1020 当时锁的是投影前的泄漏输出 |
| `test_report_longform_gaps2.py` 空 KP | 必须出现 KP 原始表标题和 `kp_lord_sub_unavailable` | 整节不出现,且没有 `synthetic_kp_failure` | D3。BUG-561 的 blocked 标题把原始 error 打进了正文 |
| `test_report_longform_parity.py` 导航 | 必须含「结论等级规则」 | 该标题不出现 | D3 |
## 验证
- Python:`pytest tests/test_report_reader_main.py tests/test_annual_tajika_pack.py tests/test_professional_report_reference_api.py tests/test_api_server_growth_contract.py tests/test_report_longform_parity.py tests/test_report_longform_gaps2.py tests/test_repo_privacy_markers.py` 通过。`jyotish_api_server.py` 增长合同仍绿(未改该文件)。
- 前端:`tsc --noEmit` 0 错。`npm run lint` 0 error、121 warnings,均不在本单文件;没有为消 warning 改业务代码。点名测试:投影、导出哈希、读者版 fixture、`edition: "reader_main"` 通过。
- 快速门:`scripts/run_quality_gate.py --profile quick` 退出 1。编译、JSON、能力/碎片审计、BPHS 18/18,以及门禁里的 Python pytest 名单跑完后进入 `npm test`。`npm test` 在本机失败:Skill 运行时 symlink `EPERM`,以及 Windows 把迁移 symlink 收成普通文件后的 `duplicate migration filename`。这是已知环境缺口,不是本单断言。不把快速门写成通过。没有单独再跑全量 `npm test`,也没有跑 `next build`。
- Skill 版本不 bump。报告版本升到 v3。
## 没做
- 未推 staging,未改 workflow,未动 DNS。
- 未做登录浏览器验收。清单在 `docs/testing/report-reader-main-20260924.md`。
- 未引入 `pl9_ai_density` 附录。
- 旧报告不回填。
+1 -1
View File
@@ -174,7 +174,7 @@
| 任务书 | 进度 | 主题 | 状态 | 落点 |
| --- | --- | --- | --- | --- |
| `TASK-report-reader-main-20260924.md` | — | **报告正文换上游读者版 reader_main + KP / Muntha 计算缺陷 + 投影截断(BUG-1026/1027/1028)**:正文一直是上游审计版(读者版 09-09 才出、从未同步),本仓又自加「结论等级规则」/英文段/异常原文;投影黑名单不认 PL9 词汇且截断半句、删表留说明;KP args `vars()` 拷贝为空恒失败;Muntha 漏合 `birth_asc_sign_idx` → Year Lord 恒火星。产品拍板接入读者版、旧报告不回填。引擎类需 pre_work_check;排在 BUG-1020 fix 之后 | 待领取 | — |
| `TASK-report-reader-main-20260924.md` | `PROGRESS-report-reader-main-20260924.md` | **报告正文换上游读者版 reader_main + KP / Muntha 计算缺陷 + 投影截断(BUG-1026/1027/1028)**:正文一直是上游审计版(读者版 09-09 才出、从未同步),本仓又自加「结论等级规则」/英文段/异常原文;投影黑名单不认 PL9 词汇且截断半句、删表留说明;KP args `vars()` 拷贝为空恒失败;Muntha 漏合 `birth_asc_sign_idx` → Year Lord 恒火星。产品拍板接入读者版、旧报告不回填。 | 待验收 | `codex/report-reader-main-20260924` |
| `TASK-report-reader-actions-20260924.md` | — | **报告操作收敛**:列表只留「查看报告」;阅读页删「下载原始附录」「打印」,导出改图标按钮;导出对话框 ≥860 居中、窄屏仍贴底(修订 chapter-export D9/D10)。产品变更,不开 BUG 号 | 基本通过(Claude 09-24:入口收敛、图标、≥860 居中均符合;原始附录三文件因执行方权限未删、PROGRESS/清单未写 → 并入修复单) | `f125fae0`(未部署) |
| `TASK-report-chapter-export-fix-20260924.md` | `PROGRESS-report-chapter-export-20260924.md` | **CRLF图盘JSON残留(BUG-1020)**:旧剥离器只匹配LF;建议D5对错误围栏残留作有限例外,D13不构成该授权。 | 代码已验收(Claude 09-24),待部署(被同批门禁红阻塞) | `fa8fef55`/`133aca49`(未部署) |
| `TASK-report-chapter-export-20260924.md` | `PROGRESS-report-chapter-export-20260924.md` | **我的报告:分块导出 + 中文元信息 / 状态色 / 行内确认删除(BUG-1018/1019)**。旧整篇按钮由抽屉取代;常用 / 全部正文保持 D5 逐字节,所有组全选另附盘和核对表。后续产品裁决 D13:分盘必须带安全 SVG,有限替代原无 SVG 约束;JSON 围栏及内部字段仍禁。原生底部 dialog、760px、70%、860 两列、零额外请求、保留打印 / 原始附录。 | 已验收(Claude 09-24:同上;D13 SVG 与列表页删导出按钮均按产品口径;BUG-1018/1019 resolved;CRLF 见 fix 单) | `1420471a`(staging 已部署);真机清单欠 |
@@ -0,0 +1,10 @@
# 读者版正文真人核对(2026-09-25)
没有受控登录浏览器。下面各项不能写成已经通过。请用一个明确虚构或公开的出生时间,重新生成一份报告后再看。不要把旧报告当成新正文。
1. 打开新报告正文。不应出现「结论等级规则」、整段英文说明、「This reference export」、`producer failed`、`Traceback`、`object has no attribute`、`full-report://`、`blocked`、`PL9 第 N 页`。
2. 正文应能读到出生资料、力量 / Ashtakavarga、标准大运、KP、年度 Tajika。没有数据的小节应整节不出现,而不是一行报错。
3. 看两个不同年份的年度章。Muntha 星座应不同;Year Lord 至少有两年不一样,不应每年都是火星 / 白羊座,也不应出现「conflict between vs」。
4. KP 节应存在,不应是 `SimpleNamespace` 缺少 `year` 的失败句。
5. 下载普通 Markdown。不应留下「所有行保持」这种半句,也不应留下孤立的「- `」。图盘仍是安全 SVG,不是 JSON 围栏。
6. 打开一份这次改动之前生成的旧报告。正文应保持原样,只是下载投影比以前少一些内部词。不要求它变成读者版。