Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
74 lines
11 KiB
Markdown
74 lines
11 KiB
Markdown
# TASK · 报告正文换成上游读者版 + KP / Muntha 计算缺陷 + 投影截断(2026-09-24)
|
||
|
||
## 基线
|
||
|
||
- 本仓 `origin/staging = 9c9b66d6`。上游 `https://github.com/732642856/yinduzhanxing.git`,本机检出 `/workspace/yinduzhanxing` @ `19195f6e`;读者版引入提交 `f3b5196f`(2026-09-09「fix: add clean high-density PL9 reader export」)。
|
||
- 分支 `codex/report-reader-main-20260924`。**引擎 / 上游同步类任务:开工前必须按 AGENTS §9 读 `docs/research/pre_work_error_ledger.md` 并跑 `python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45`**;不得把 `.workbuddy` 镜像当主仓。
|
||
- 串行:**`TASK-report-chapter-export-fix-20260924.md`(BUG-1020)先合**,本单后合(两者都会动报告 golden 与导出锁)。与 `TASK-report-reader-actions-20260924.md` 文件不交叉。
|
||
|
||
## 事故实证
|
||
|
||
产品 09-24 真机报告正文出现大量非人读内容,例如:「结论等级规则 - executed / partial_verified…」「Sudarshana Chakra(三参考点原始结构)…PL9 第 8 页的三层图格尚未逐格对照…不输出 producer 自带的复合评分」「本节仅披露 PL9 图盘提取…OCR 候选」「Domi 受控样本的 16 个星座行已在 PL9 第 42 页 fixture 中匹配」「…所有行保持」(半句)、「KP Lord / Sub 原始表(本地计算) blocked / kp_lord_sub_unavailable KP producer failed: 'types.SimpleNamespace' object has no attribute 'year'」、报告身份块(`full-report://…`、`pl9_personal_long_report.v2`、hash、`质量检查: blocked`、`Chart Identity: birth=user_provided…`)、英文「This reference export combines…」、年度章「annual_tajika_pack」「kp_monthly_report_packet」「Muntha 当前优先候选指向conflict between vs Capricorn」、「Patyayini Dasha 外部回放(PyJHora/JHora) blocked / annual_replay_unavailable year=2027」。
|
||
|
||
三层根因(`origin/staging` 实证):
|
||
|
||
1. **用错格式**:正文 = `scripts/professional_report_reference.py` → `render_pl9_markdown`(`scripts/jyotish_engine.py`),这是上游的**专业参考 / 审计版**。上游另有读者版 `reader_main`:`_render_pl9_user_markdown`(上游 `scripts/jyotish_engine.py:11722`,docstring "user-facing … without parity/audit scaffolding")、`_pl9_export_markdown_for_edition`(:13099)、`render_pl9_parity_markdown`(:13148);上游审计 `docs/research/pl9_reader_main_information_coverage_audit_2026_09_09.md` 声明读者版不含 `blocked` / `parameter_sensitive` / `PyJHora` / `producer` / `schema` / `source_path`。本仓引擎这四个符号 **0 命中**(最后一次引擎同步 `f2241463` 在 09-03,早于 `f3b5196f`)。`cfcd369d`(09-06)把参考版设为正文,而 `TASK-report-longform-parity-20260905` 当初只批准它作附录。
|
||
2. **本仓自加的泄漏**:`_render_finished_reading_navigation`(「结论等级规则」,`bab07187` 引入,上游无);`_professional_report_reference_boundary_notice` 的英文段(`3b09bbbe`);`_kp_lord_sub_section` / `_year_replay_subblocks` 走 `_blocked_planned_section` 打印原始 `error/reason`(`cfcd369d`,上游在空结果时返回 `[]`)。
|
||
3. **投影是短黑名单且有破坏性**:`frontend/src/lib/report-public-projection.ts` `INTERNAL_HEADINGS` / `INTERNAL_KEY_TOKEN` / `ORDINARY_OUTPUT_LEAK_PATTERNS` 不认识 PL9 词汇;`projectProseLine` 在 `parameter_sensitive` 处**截断句子**(产生「…所有行保持」和孤立的「- `」),`tableIsInternal` 删整表而保留其标题和说明段。`personal-report-density-retry.test.ts` 把这份泄漏输出的 sha256 锁成 golden。
|
||
|
||
两个真实计算缺陷:
|
||
|
||
4. **KP 永远失败**:`scripts/jyotish_api_server.py` `_compute_full_reading_for_thematic` 用 `type('Args', (), {...})()` 构造参数(字段在类上、实例 `__dict__` 为空);`jyotish_engine.py` `cmd_kp` 执行 `SimpleNamespace(**vars(args))` 只拷到 `ayanamsa`,随后读 `.year` 抛错。同型写法还在 `transit_args = SimpleNamespace(**vars(args))`(double_transit_pac / transit_ll7l / planetary_congregation),网页路径同样会失败。上游有同样潜伏缺陷,只是空结果时不输出。
|
||
5. **Muntha / Year Lord 恒错**:`scripts/solar_return.py` 读 `sr.get('birth_asc_sign_idx')`,本仓 `calc_solar_return_chart` 返回字典**从不设置该键**(上游在 solar_return.py:501 设置;`f2241463` 合并时漏掉这半)。结果 Muntha 恒为 `blocked`,Year Lord 回退 `muntha_sign_idx=0` → **恒为火星 / 白羊座**;`annual_tajika_pack.py` `_field_with_conflict_gate` 用整字典比较,blocked 与正常值必判冲突,`_field_brief` 生成「conflict between vs X」,引擎 `_humanize_reader_summary_line` 的冲突正则因空组匹配失败,落到 `simple_match` 渲染成「当前优先候选指向conflict between vs X」。**这是年运结论的正确性缺陷**,不只是文案。
|
||
|
||
## 决策记录(产品 2026-09-24)
|
||
|
||
- **D1 新报告正文改用上游读者版 `reader_main`**:从上游 `f3b5196f..19195f6e` 同步 `_render_pl9_user_markdown`、`_pl9_export_markdown_for_edition`、`render_pl9_parity_markdown` 及其依赖;`professional_report_reference.py` 增加 `edition` 参数,网页生成链(`frontend/src/lib/personal-report-longform-generate.ts`)请求 `edition: "reader_main"`。专业参考版不再作为正文,也**不再提供用户入口**(原始附录入口已由 `TASK-report-reader-actions` 删除)。
|
||
- **D2 旧报告不回填**:已生成的报告保持原正文(投影修复后会比现在干净);用户可重新生成。不写迁移、不批量重算。
|
||
- **D3 删除本仓自加的三处**:「结论等级规则」块、英文 boundary 段、`_blocked_planned_section` 打印原始 error/reason 的做法(改为:数据不可用的节整节不输出,与上游一致)。这些即使在参考版里也删。
|
||
- **D4 修两个计算缺陷**:KP / transit 的 args 拷贝改为不依赖 `vars()`(显式读取所需字段,或 `_compute_full_reading_for_thematic` 改用真 `SimpleNamespace`);补回 `birth_asc_sign_idx`;`_field_with_conflict_gate` 在一方 `status == "blocked"` 时不判冲突、取另一方;比较只比关键字段(星座 / 主星),不比整字典。
|
||
- **D5 投影修正**:`projectProseLine` 遇内部 token **删整行**而不是截断;`tableIsInternal` 删表时连同紧邻的表头说明段一起删;新增 PL9 词汇防线(`blocked`、`executed`、`partial_verified`、`missing_in_local`、`producer`、`parity`、`PL9 第 N 页`、`full-report://`、`pl9_*`、`*_unavailable`、`*_pack` / `*_packet` 标识符、Python 异常形态 `object has no attribute`、`Traceback`、整段英文),用于 `ordinaryOutputLeaks` 检测(读者版输出必须 0 命中)。
|
||
- **D6 Skill / 报告版本**:报告版本号从 `pl9_personal_long_report.v2` 升 v3(读者版);Skill 是否 bump 由执行方按 CHANGELOG 规则判断并写明。
|
||
|
||
## 硬红线
|
||
|
||
1. 许可证边界:上游代码按既有同步方式整段引入并注明来源提交,不改动上游算法口径(除 D4 两个缺陷,且须在 BUG 记录说明上游同样存在)。
|
||
2. 不改 Ayanamsa / Node / 宫制 / 大运口径与置信度边界(AGENTS §8.4)。
|
||
3. 读者版 golden **必须由真实引擎生成**(AGENTS §7.4),用明确虚构生日;旧 `report-density-fictional-reader.json` 保留给旧报告回归,新增 reader_main fixture。
|
||
4. `ordinaryOutputLeaks(读者版正文) = []`,且 D5 新增的每一类词汇在读者版 golden 中 0 命中;该断言不得弱化。
|
||
5. 旧 golden sha 断言(`personal-report-density-retry.test.ts` 等)改动必须写三栏,说明"原 sha 锁的是泄漏输出"。
|
||
6. `scripts/jyotish_api_server.py` 不得增长(`test_api_server_growth_contract.py`);新逻辑进独立模块。
|
||
7. 快速门 `run_quality_gate.py --profile quick` 与相关 Python 定向测试必跑;不改 workflow / 并发 / 数据库结构。
|
||
|
||
## 任务分解
|
||
|
||
- **T1 同步读者版**(`scripts/jyotish_engine.py` 或新模块、`scripts/professional_report_reference.py`)。验收:Python 测试——同一虚构 packet,`edition="reader_main"` 输出不含 D5 词汇、含上游审计文档列出的核心章节;`edition` 缺省仍为参考版(后向兼容)。
|
||
- **T2 生成链切换**(`personal-report-longform-generate.ts`、快照 schema 若需版本字段)。验收:`professional-report-reference-route.test.ts` 断言请求体带 `edition: "reader_main"`;新报告版本 v3。
|
||
- **T3 删自加泄漏**(D3)。验收:参考版输出也不再含「结论等级规则」「This reference export」「producer failed」。
|
||
- **T4 KP / transit args**(D4 前半)。验收:Python 测试用 `type('Args', (), {...})()` 形态的参数调用 `cmd_full_reading` 路径,KP 与三项 transit 结果非 blocked。
|
||
- **T5 Muntha / Year Lord**(D4 后半)。验收:虚构生日的太阳回归 `birth_asc_sign_idx` 存在,Muntha 非 blocked,Year Lord 随年份变化(至少两年不同);`annual_tajika_pack` 在一方 blocked 时无「conflict between」。
|
||
- **T6 投影**(D5)。验收:`report-public-projection.test.ts` 新增 PL9 词汇用例;「…所有行保持」类截断不再出现(整行删除);旧 fixture 投影后不再含孤立「- `」。
|
||
- **T7 记录**:`docs/BUG_HISTORY.md` **BUG-1026** 报告正文用了审计版 + 投影截断(关联 BUG-999、1003、1009;复发自 BUG-999——写明为何当时的测试只覆盖聊天键没拦住);**BUG-1027** KP args 拷贝失败;**BUG-1028** Muntha 缺 `birth_asc_sign_idx` 致 Year Lord 恒火星(关联 `f2241463` 同步漏合)。`docs/research/pre_work_error_ledger.md` 追加"上游同步漏合"条目。CHANGELOG、PROGRESS、`docs/testing/report-reader-main-20260924.md`(生成一份新报告,逐章检查无英文 / 页码 / blocked / 异常原文;年度章 Muntha 与 Year Lord 每年不同;KP 节存在)。
|
||
|
||
## 让步顺序
|
||
|
||
1. 上游读者版依赖过多、整段引入会让本仓引擎失控时,允许以新模块 `scripts/pl9_reader_export.py` 引入并在引擎中薄注册。
|
||
2. D5 的英文整段检测若误伤行星英文名 / 术语,允许改为"连续 ≥ 12 个英文单词的段落"判定。
|
||
3. 不得让步:D1(正文换读者版)、D4(两个计算缺陷)、红线 3、红线 4。
|
||
|
||
## 开工前置命令
|
||
|
||
```bash
|
||
git fetch origin --prune
|
||
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45
|
||
git -C /workspace/yinduzhanxing fetch origin && git -C /workspace/yinduzhanxing log --oneline -1 origin/main
|
||
git worktree add -b codex/report-reader-main-20260924 .worktrees/report-reader-main-20260924 origin/staging
|
||
cd .worktrees/report-reader-main-20260924
|
||
.venv/bin/python scripts/run_quality_gate.py --profile quick # 记基线
|
||
cd frontend && ./node_modules/.bin/tsc --noEmit && npm test 2>&1 | tail -5
|
||
```
|
||
|
||
## BUG 编号
|
||
|
||
本单 **BUG-1026 / 1027 / 1028**(1021–1025 已被同日其它单预留),开工时核对。
|