docs: #91 fix2 progress, BUG-1418 (yoga combination 未判定) and BUG-1419 (parity chapters keys / heading level)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HwMNZEzdzmrbPhuRNmZe3C
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1dd6203883
commit
c1aa72fcbf
@@ -37243,3 +37243,35 @@
|
||||
- 相关记录:BUG-1312。issue #91。
|
||||
- 复发自:无。
|
||||
- 修复版本:分支 `codex/full-data-parity-1-20261021`。
|
||||
|
||||
## BUG-1418 | 中文瑜伽「组合条件」整格变成「未判定」
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-10-22
|
||||
- 最近更新:2026-10-22
|
||||
- 影响面:个人报告完整数据版中文版的可用瑜伽表、瑜伽解释页「组合:」一句、阅读页瑜伽组合列。英文版不受影响。
|
||||
- 用户现象:staging 上写着「太阳与水星 同宫 (水日 合相)」「上升主落在干燥星座」的格子,在本分支印成「未判定」。0~19 号虚构盘的组合列共 174 格(0 号盘 8 格;不含解释页),此前 PROGRESS 统计 200 张虚构盘去重约 1030 条。
|
||||
- 触发条件:瑜伽来自 `yoga_rules.json` 的语义型条件(BVR / PyJHora 批量规则,只有英文 `note`)、只写了英文 `combo_template` 的自定义规则,或 `yogas_doshas.calc_raj_yogas` / `calc_dhana_yogas` 的 `H*_Lord(...) in H*` 组合句。
|
||||
- 根因:BUG-1416 的修复删掉了「先出英文、再短词回译」这条路,这些组合句的中文原本就是回译出来的,源头没有中文。`chinese_combination` 看到纯英文句子只能退回「未判定」。
|
||||
- 修复:`yoga_engine` 的语义条件返回 `BiText(中文, 原 note)`,中文取自新文件 `references/yoga_semantic_notes_zh.json`(一句 note 对一句中文,共 167 条,含 1 条英文模板);只写英文模板的自定义规则走同一张表;无 note 的两种条件类型各给一句固定中文。`yogas_doshas` 的王者 / 财富行加 `combination_zh`,原 `combination` 不改。`chinese_combination` 先取干净的 `combination_zh`。没有恢复回译,没有改 `jyotish_api_server.py`。
|
||||
- 验证:`tests/test_yoga_combination_chinese.py`(每条语义 note 都有且只有一句中文、互不相同、过中文卫生门;英文孪生保持原值;王者 / 财富行有中文组合句)。`tests/test_full_data_parity_chapters.py::test_chinese_yoga_combinations_are_not_blanked`(0、1、9 号盘组合列无「未判定」,英文无汉字)。0~19 号虚构盘与 origin/staging 逐格比对:2164 行,staging 有字而本分支「未判定」为 0;含英文词的组合格从 650 降到 24(多为 Yupa、Chakra 等专名)。
|
||||
- 防复发:中文组合句只能来自中文源字段或中文表,不得再翻英文。新增语义规则时必须在 JSON 表里加中文,测试会列出缺的 note。中文表一对一,检测器按组合句去重的结果不变:0~19 号盘检出的瑜伽行、强度、类别、英文组合句与 staging 完全相同(2250 行,只有两张盘内 `set` 遍历顺序不同,见 PROGRESS)。
|
||||
- 相关记录:BUG-1416(回译路径删除)、BUG-1312。issue #91。
|
||||
- 复发自:无(BUG-1416 修复的副作用)。
|
||||
- 修复版本:分支 `codex/full-data-parity-1-fix2-20261022`。
|
||||
|
||||
## BUG-1419 | 完整数据版新六章:11 节只印「未判定」和资料包键名,六章用一级标题把阅读页撑到 107 章
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-10-22
|
||||
- 最近更新:2026-10-22
|
||||
- 影响面:个人报告完整数据版末尾新加的六章(`scripts/report_render/parity_chapters.py`),中英两版。
|
||||
- 用户现象:Jaimini 计算细节、KP 计算口径、Tara 与 Chandra 矩阵、上升 Vargottamamsa、上升主与七宫主行运、八分法 Yoga Pinda、八分法加减、关系口径、多参考点行运、木土双重行运 PAC、行星聚集这 11 节只有一列,格子是「未判定」和 `summary`、`p5`、`stats`、`d1` 这类键名。另有 Argala、出生历法、本命 Tithi、Tajika 候选、Goel 尊贵、瑜伽类别把 `method`、`raw`、`applying`、`friend`、`raja` 原样印出。阅读页按 `##` 分章,六章是 `#`、各节是 `##`,0 号虚构盘中文报告的 `##` 从 38 个变成 107 个。
|
||||
- 触发条件:生成完整数据版报告(任何盘)。
|
||||
- 根因:渲染函数对嵌套字典逐键出行(`_named_status` / `_simple_module`),把键名当成「名称」,值是字典就印「未判定」;单字小写枚举没有映射也没被拦下。标题层级比阅读页约定高一级。旧测试把第一列(标签列)和键名都算作真实数据,所以没拦住。
|
||||
- 修复:11 节改读真实记录(逐节字段位置见 PROGRESS),印多列表格;`show()` 把整格是小写键名的值改印「未判定」,已知枚举补了中英映射;Tithi 主星模块不在公开资料包里,该节只列出生 Tithi 并写明原因。六章改 `##`、各节 `###`、Narayana 两种口径 `####`。前端未改。
|
||||
- 验证:`tests/test_full_data_parity_chapters.py`:每节必须在非第一列有真实值(只有「大运与小运交界检查」可以是一句话);任何表格单元格不得整格是键名;报告只有一个 H1,`##` 数等于去掉六章后的报告加 6,六章在最后、各节为 `###`。拿旧代码的 0 号盘输出套新规则:10 节不过、40 种键名格(第 11 节「关系口径」当时是一句固定话,新增的「非一句话节必须有表」一条会拦)。
|
||||
- 防复发:同上三条测试常驻;新节必须带表或列入只许一句话的白名单。
|
||||
- 相关记录:BUG-1416。issue #91。
|
||||
- 复发自:无(#91 A 段第 1 次打回的残留)。
|
||||
- 修复版本:分支 `codex/full-data-parity-1-fix2-20261022`。
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# PROGRESS:#91 A 段第 2 次打回(F1~F4)
|
||||
|
||||
- 分支:`codex/full-data-parity-1-fix2-20261022`,起点 `92b4e220`(`codex/full-data-parity-1-20261021` 顶端,已含最新 `origin/staging`)。
|
||||
- 执行:Claude 子代理,Linux,系统 `python3`(无 `.venv`),PyJHora 已屏蔽(虚构盘助手 `block_jhora()` / 临时脚本 `sys.modules["jhora"] = None`)。只用虚构盘。
|
||||
- 状态:本地完成,未推送。前端未改。
|
||||
- BUG:新增 BUG-1418(F3)、BUG-1419(F1 + F4)。开工时 `origin/staging` 最大号 1415,本分支 1417,其他 `origin/codex/*` 分支都不超过 1415。
|
||||
|
||||
## 结论
|
||||
|
||||
| 项 | 做了什么 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| F1 | 11 节改读资料包里的嵌套记录,印多列表格。连带修了 6 节把小写键名或枚举印成格子的问题(Argala、出生历法、本命 Tithi、Tajika 候选、Goel 尊贵、瑜伽类别)。没有新的白名单节 | 0、1、9、3、17、42、77、150 号盘中英两版逐节检查:白名单 4 节外,每节都有非第一列真实值,整格键名为 0,英文无汉字 |
|
||||
| F2 | 「每节有真实值」只认非第一列;一列表永远不过;只有「大运与小运交界检查」可以是一句话,其余节必须有表。新加「任何格子不得整格是键名」 | 拿修复前代码的 0 号盘输出套新规则:10 节不过,40 种键名格;第 11 节「关系口径」当时是一句固定话,由「必须有表」一条拦住 |
|
||||
| F3 | 中文组合句改由中文源给出(见下)。没有恢复回译 | 0~19 号盘与 staging 逐格比:2164 行组合格,staging 有字而本分支「未判定」= 0(修前 174);英文版汉字 0 |
|
||||
| F4 | 六章 `##`,各节 `###`,Narayana 两种口径 `####`。前端未改 | 0 号盘:H1 只剩标题 1 个;`##` 中文 44、英文 44;英文 staging 38 + 6;中文 staging 37 + 7,多出的 1 个是本分支中文附录新增的「宫主逐宫解释」(与英文版同节,第 1 轮已有),不是六章 |
|
||||
|
||||
## F1 各节数据来源
|
||||
|
||||
路径都在 `build_professional_report_reference_packet` 的输出里(顶层与 `worksheets` 下同名,渲染先读顶层)。
|
||||
|
||||
| 节 | 资料包位置 | 印出的列 |
|
||||
| --- | --- | --- |
|
||||
| Jaimini 计算细节 | `advanced_systems.jaimini.chara_karaka_7.karaka_table`、`chara_karaka_8.karaka_table_8` | 卡拉卡、七曜口径行星 / 度数、八曜口径行星 / 排序度数(`effective_degree_in_sign`)、罗睺倒数(`rahu_reverse_applied`)。上游 `jaimini_calculation_detail_markdown` 同样印七曜表 |
|
||||
| KP 计算口径 | `advanced_systems.kp.kp_profile`(`ayanamsa_display`、`requested_report_ayanamsa`、`house_system`、`cusp_source`、`timing_policy`、`status`)、`kp.house_basis`、`kp.house_occupancy_basis`、`kp.calculation_profile.node_mode`、`kp.ruling_planets` | 项目 / 内容;另一表印七个 ruling planets |
|
||||
| Tara 与 Chandra 矩阵 | `advanced_systems.nakshatra_adv.tara_chandra_combined.<行星>` | 星宿、Tara 序号(+1)、Tara(中文 `tara_cn`,英文取 `tara_name` 括号前)、Tara 吉凶、Chandra 位(`rashi_from_moon` +1)、Chandra、Chandra 吉凶、合并结果(`combined_score` 映射)。上游 `nakshatra_combined_markdown` 同列 |
|
||||
| 上升 Vargottamamsa | `strengths_and_scores.lagna_vargottamamsa`(`d1_sign`、`d9_sign`、`is_lagna_vargottamamsa`) | D1 上升星座、D9 上升星座、是否 Vargottamamsa |
|
||||
| 上升主与七宫主行运 | `timing_and_predictive_systems.transit_ll7l`(`lagna_lord`、`seventh_lord`、`reference_date`、`p5` / `p8` / `parivartana` 的 `hit` 与 `details`) | 参考日、上升主、七宫主;检查项 / 是否成立 / 明细。明细句按引擎固定格式解析成中英文,解析不了的不印 |
|
||||
| 八分法 Yoga Pinda | `strengths_and_scores.ashtakavarga.yoga_pinda.planets`、`planet_weights`、`summary` | 星座、所在星座点数、Rashi / Graha / Yoga Pinda、行星权重;最强 / 最弱行星、合计、平均。上游 `ashtakavarga_yoga_pinda_markdown` 同源 |
|
||||
| 八分法加减 | `strengths_and_scores.ashtakavarga.sodhita`(`raw_bav`、`trikona_bav`、`sodhita_bav`、`ekadhipatya_audit`)、`ashtakavarga.shodhya_pinda` | 原始 BAV 合计、三方净化后、单宫主净化后、Rashi / Graha / Shodhya Pinda;单宫主净化改动的星座对(前 / 后) |
|
||||
| 关系口径 | `strengths_and_scores.planetary_friendship`(`method`、`source_planets`、`rows`、`status`) | 保留原说明句;表印口径、计入星体、是否计入交点、行数、状态 |
|
||||
| 多参考点行运 | `timing_and_predictive_systems.transit_multi_reference`(`references`、`target_date`、`transit_analysis.<行星>.house_from_ref`) | 参考点 / 星座 / 优先级;行星、星座、度数、从四个参考点起的宫 |
|
||||
| 木土双重行运 PAC | `timing_and_predictive_systems.double_transit_pac`(`d1` / `d9` / `cl` 的 jupiter / saturn 目标、`double_transit`、`stats`、`event_house`) | 参考日、事件宫、D9 上升、月亮上升、命中数;层 / 行星 / 目标 / 相位。目标名按引擎固定格式解析(BUG-1060 / 1061 的命名),解析不了的不印 |
|
||||
| 行星聚集 | `timing_and_predictive_systems.planetary_congregation`(`natal.lagna`、`natal.house_7`、`transit.<宫>`、`hit`) | 参考日、是否有聚集;本命上升宫、本命第七宫、各行运宫的行星 |
|
||||
|
||||
连带修的 6 节:Argala 读 `advanced_systems.argala.houses.house_N`(Argala / Virodhargala 数、有效 Argala 宫、`net_result`);出生历法读 `birth_and_parameters.panchanga.raw`(Tithi、星宿、Yoga、Karana、星期、星期主星、Hora 主星及吉凶);本命 Tithi 读同一处的 `tithi`;Tajika 候选补出名称、相位、剩余度数并映射入相 / 离相;Goel 尊贵的 friend / neutral / enemy 补映射;瑜伽类别改用中英类别表。
|
||||
|
||||
**Tithi 主星**:`tithi_lord` 只出现在 `raw_module_usage_map`,公开资料包没有。该节只列出生 Tithi(名称、半月、序号、月日黄经差),并在表下写「Tithi 主星模块没有进公开报告资料包」。没有在渲染层另推主星:报告只印资料包里有的东西,是否把 `tithi_lord` 接进资料包留给 B 段 / Claude 定。
|
||||
|
||||
`_PACKET_GAPS` 仍是原来 4 节(Navamsha 小运时长、五鸟活动、Rashi Tulya Navamsa、当前多系统收敛),没有新增。
|
||||
|
||||
顺带看到、未改:`cmd_planetary_congregation` 在 `event_house = 7` 时把 `house_7` 与 `house_{event_house}` 指到同一个列表,同一颗星会被追加两次(17 号盘「月亮、月亮、水星……」)。渲染层去重显示,引擎未动,留给 Claude 判断是否另立单。
|
||||
|
||||
## F2 测试改动(三栏)
|
||||
|
||||
| 断言 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `test_every_section_has_a_real_cell_except_the_four_public_gaps` 的 `_section_has_real_cell` | 任一数据格(含第一列标签)不是「未判定」即算真实值;无表时任一行文字即算 | 只看非第一列;排除「未判定 / Not determined / — / - / 空」;无表时只认非标题的句子;另外除「大运与小运交界检查」外每节必须有表 | 第一列是标签,键名也落在第一列,旧判定让一列表和键名都过了(F1 的 11 节) |
|
||||
| `test_parity_chapters_go_through_local_conventions` 的英文探针 | 源字段 `divorce`,期望 `relationship strain` | 源字段 `Divorce risk`,期望 `relationship strain risk` | 单个小写词现在按内部键名处理、不印;探针改成读者会看到的短语,替换逻辑不变 |
|
||||
| 标题定位(`_chapter_text`、`_section_body`、`test_empty_packet…`、`test_three_fictional…`) | 章 `# `、节 `## `、Narayana `### ` | 章 `## `、节 `### `、Narayana `#### `;章名用整行匹配计数 | F4 标题降一级 |
|
||||
|
||||
新增测试:`test_every_section_has_a_real_cell_outside_the_label_column_unit`、`test_no_table_cell_is_a_raw_packet_key`(`^[a-z][a-z0-9]*(_[a-z0-9]+)*$`,0、1、9 号盘中英)、`test_six_chapters_are_reader_chapters_and_sections_sit_below_them`(只有一个 H1;`##` 数 = 去掉六章的同一份报告 + 6,且最后 6 个就是六章;`###` 数 = 69 节)、`test_chinese_yoga_combinations_are_not_blanked`,以及 `tests/test_yoga_combination_chinese.py` 三条。
|
||||
|
||||
`grep` 过 `tests/` 与 `frontend/tests/`:六章标题与层级只有 `tests/test_full_data_parity_chapters.py` 引用。
|
||||
|
||||
## F3 中文组合句来源
|
||||
|
||||
| 来源 | 改法 | 是否影响检出 |
|
||||
| --- | --- | --- |
|
||||
| `yoga_engine._eval_semantic_condition` 的 `note`(166 条) | `success()` 返回 `BiText(中文, 原 note)`;中文在新文件 `references/yoga_semantic_notes_zh.json` | 一对一映射,去重键的相等关系不变;`combination_en` 仍是原 note |
|
||||
| 无 `note` 的条件(`planet_in_house`、`planet_in_lagna`,原来印类型键) | 每种类型一句固定中文,英文孪生仍是类型键 | 同类型仍合并成一条 |
|
||||
| 只写英文 `combo_template` 的自定义规则(`PyJHora aligned source logic`,2 条规则) | 同一张表查中文,英文孪生保留原句 | 无 |
|
||||
| `yogas_doshas.calc_raj_yogas` / `calc_dhana_yogas` | 每行加 `combination_zh`(宫主、落宫、行星中文名),原 `combination` 不改 | 无 |
|
||||
| `appendix_language.chinese_combination` | 先取干净的 `combination_zh` | — |
|
||||
|
||||
没改:哪些瑜伽成立、强度、类别、评分,`references/yoga_rules.json`,`scripts/jyotish_api_server.py`。
|
||||
|
||||
检出不变的核对:0~19 号盘,staging 与本分支各取 `detected_yogas`、`yogas`、王者 / 财富行的(规则、名称、强度、类别、英文组合句)共 2250 行,集合完全相同。两张盘(1、17)里王者 / 财富行先后顺序不同:`calc_raj_yogas` 遍历 `set`(`dual_lords`、`BENEFICS`),字符串 `set` 的顺序随进程的哈希种子变(未单独复测 staging 两次)。没有改。
|
||||
|
||||
比对方法:`git worktree add --detach .worktrees/fix2-91-base origin/staging`,两边各渲染 0~19 号盘中文,按表头含「组合条件」的表逐行比(同名同序)。完成后已删除该工作树。
|
||||
|
||||
| | staging | 修前 | 修后 |
|
||||
| --- | --- | --- | --- |
|
||||
| 组合格总数(0~19 号盘) | 2164 | 2164 | 2164 |
|
||||
| staging 有字、本分支「未判定」 | — | 174 | 0 |
|
||||
| 「组合:未判定」(解释页) | 0 | — | 0 |
|
||||
| 含英文词的组合格(不计 PyJHora、Mandi 等专名) | 650 | — | 24 |
|
||||
|
||||
剩下 24 格是规则中文模板本身带的专名,例如「行星集中在特定宫位(Yupa 拴马柱)」「PyJHora aligned Bheri瑜伽: …」。
|
||||
|
||||
## 体积(0 号虚构盘,字符数)
|
||||
|
||||
| | staging | 修前(`92b4e220`) | 修后 |
|
||||
| --- | --- | --- | --- |
|
||||
| 中文 | 430,566 | 517,991 | 522,047 |
|
||||
| 英文 | — | 993,608 | 1,000,010 |
|
||||
| 中文 `##` 个数 | 37 | 107 | 44 |
|
||||
| 英文 `##` 个数 | 38 | 107 | 44 |
|
||||
|
||||
## 测试
|
||||
|
||||
解释器:系统 `python3`。PyJHora 屏蔽。
|
||||
|
||||
| 命令 | 退出码 | 用时 |
|
||||
| --- | --- | --- |
|
||||
| `python3 -m pytest tests/test_full_data_parity_chapters.py tests/test_full_data_parity_appendix.py tests/test_report_english_sweep_smoke.py tests/test_report_english_edition.py tests/test_report_full_data_fix.py tests/test_python_hygiene_budget.py tests/test_api_server_growth_contract.py tests/test_repo_privacy_markers.py tests/test_yoga_combination_chinese.py -q` | 0(120 项) | 183 秒 |
|
||||
| `python3 -m pytest tests/test_report_english_sweep.py -q`(200 张虚构盘) | 0 | 550 秒 |
|
||||
| 瑜伽、阅读页、解释源、完整数据相关的其余 27 个测试文件(`tests/` 下文件名含 yoga / report_reader / full_data / pl9 / interpretation / professional_report / full_reading_module,去掉上面已跑的) | 0(118 项) | 56 秒 |
|
||||
| `python3 scripts/run_quality_gate.py --profile quick` | 1 | 271 秒 |
|
||||
|
||||
快速门:py_compile、JSON 校验、四个审计脚本、pytest(209.8 秒)都通过;停在 `npm test`,原因是这个工作树没有 `frontend/node_modules`(`tsx` 找不到)。本单没改前端,这一步是环境缺口,不是通过。
|
||||
|
||||
隐私标记测试在本文与 BUG 记录提交后又跑了一次:退出码 0。
|
||||
|
||||
第一轮必跑列表里 `test_report_full_data_fix.py::test_yoga_effect_does_not_assert_lifespan` 红过一次:新瑜伽类别表把 `ayur` 印成 Longevity,撞上 BUG-1210 不把寿命当断语的约束。改成「体质 / Constitution」后通过(提交 `1dd620388`)。
|
||||
|
||||
## 偏离
|
||||
|
||||
- 没有推送,没有改前端、`scripts/jyotish_api_server.py`、`references/yoga_rules.json`、冻结打分文件。
|
||||
- F1 范围比 11 节多了 6 节:新测试「格子不得是键名」会抓到它们,不修就过不了 F2。
|
||||
- 中文报告 `##` 是 staging + 7,不是 + 6;多的「宫主逐宫解释」来自本分支第 1 轮的中文附录,与英文版同节。测试按「同一份报告去掉六章」计数,英文正好 staging + 6。
|
||||
- `references/yoga_semantic_notes_zh.json` 是新文件(任务允许加中文模板 / 字段)。
|
||||
@@ -524,3 +524,4 @@
|
||||
| `TASK-synastry-staging-fix-fix-20261022.md` | `PROGRESS-synastry-staging-fix-fix-20261022.md` | **#85 第 1 次打回**(T7~T11 主体通过):新地址没登记进路由清单致快速门红;CHANGELOG 与 T11 矛盾;侧栏点亮测试是空断言 | 已合入 staging | `codex/synastry-staging-fix-20261021` |
|
||||
| `TASK-report-english-han-leak-fix-20261022.md` | `PROGRESS-report-english-han-leak-fix-20261022.md` | **#89 第 1 次打回**:改了冻结的校正打分文件 `jaimini.py`;测试的 PyJHora 屏蔽没传到子进程(测的不是生产那份报告,也是慢的原因);缺英文时留空藏住漏洞 | 已合入 staging | `codex/report-english-han-leak-20261021` |
|
||||
| `TASK-full-data-parity-1-fix-20261022.md` | `PROGRESS-full-data-parity-1-fix-20261022.md` | **#91 A 段第 1 次打回**:新六章 69 节里 16 节在三张虚构盘上整节「未判定」,其中 12 节数据在资料包里、是读错了字段;测试抓不到整节未判定;新六章绕过了报告口径替换;中文附录悄悄丢列和瑜伽条目要量出来 | 本地完成,待验收 | `codex/full-data-parity-1-20261021` |
|
||||
| — | `PROGRESS-full-data-parity-1-fix2-20261022.md` | **#91 A 段第 2 次打回**(Claude 口头修复单 F1~F4):11 节只印「未判定」和键名改读真实记录;测试只认非第一列真实值、禁止键名格;中文瑜伽组合句由中文源给出(BUG-1418);六章降为 `##`、节 `###`(BUG-1419) | 本地完成,待验收 | `codex/full-data-parity-1-fix2-20261022` |
|
||||
|
||||
Reference in New Issue
Block a user