Files
Jyotisha/docs/tasks/PROGRESS-full-data-parity-1-fix2-20261022.md
T
Jesse_ChenandClaude Opus 5.5 c1aa72fcbf
Independent Staging Quality Gate / validate (push) Successful in 20m33s
Independent Staging Quality Gate / publish (push) Successful in 4m57s
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
2026-10-22 22:11:48 +08:00

112 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 是新文件(任务允许加中文模板 / 字段)。