Files
Jyotisha/docs/tasks/TASK-upstream-sync4-20261002.md
T

111 lines
15 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.
# TASK · 上游同步第四轮:婚姻断语、过运相位、Shadbala、格局列表、月亮/太阳类格局、Arudha 单一来源、定位星循环(2026-10-02)
- 基线:`origin/staging` @ `588282c2`(已含功能吉凶 v2 `57782aea`…`51f3f47b`,BUG-1158/1180~1182;**本单不重复做功能吉凶**)。
- 上游参照:`/workspace/yinduzhanxing` `origin/main` @ `0a6696c5`。只按下表逐处移植,不整文件覆盖。
- 分支 / worktree:`codex/upstream-sync4-20261002` / `.worktrees/upstream-sync4-20261002`
- 依据:`docs/research/engine_model_gap_and_astrologer_questions_2026_10_02.md`(Claude 10-02 全项目梳理)+ 同日对上游 `0a6696c5` 的逐项比对(32 项中上游真正修好 4 项,其余见 §7「不在本单」)。
- **并单与串行**:本单 **吸收** `TASK-yoga-lunar-node-consistency-20261002.md`(作为 T5,原单不再单独派发)。同一天改 `references/yoga_rules.json`、`scripts/jyotish_engine.py`、`scripts/jyotish_api_server.py` 的其他任务书须排在本单合入之后。
- BUG 编号:开工时核对 `docs/BUG_HISTORY.md` 最大号(本单写作时为 BUG-1182),从 **BUG-1183** 起顺延。
## 1. 事故实证(行号按符号定位,开工时以符号为准)
| 项 | 我方位置(`origin/staging`) | 现象 | 上游修复 |
| --- | --- | --- | --- |
| A 婚姻计数断语 | `scripts/marriage_counting.py` `_interpret_marriage_count`、`_marriage_recommendations`;消费方 `scripts/jyotish_api_server.py` `_derived_marriage_evidence`(count ≤ 1 记 `positive`) | 输出「一次终身关系,忠诚度较高」「两段重要关系,可能再婚」「第一段关系由吉星主导,质量较好」等确定性事件断语;`marriagecount` 在前端 `consultation-workflow.ts` `domainDetailsKeys` 白名单里,`projectDomainEvidence` 会把 `conclusion` 投给模型 | `0afa2780`:改成只描述几何指数,删全部关系次数与质量断语 |
| B 双重过运相位错一宫 | `scripts/jyotish_engine.py` `_check_pac`:`((t_house - p_house + 12) % 12) == offset` | 宫距从 0 起数却与 1 起数的相位号比:土星 7 宫相位判到第 8 宫,木星 5/9 判成 6/10,火星 4/8 判成 5/9。BUG-1060/1061 审计同一命令时没查到这一行 | `2dd6062a`(09-24):`% 12) + 1 == offset` |
| C Shadbala 四处计算错 | `scripts/shadbala.py`:Ayana 南北判断用 `raw_tropical`(可溢出 360°);`_calendar_lords` 用 `ceil(jd+1)%7` 求星期(在儒略日正午换日)且把星期序号当时主序号;Surya Siddhanta 平黄经每 7 天对齐一次星期、整数截断丢掉不足一日的运动;Chesta 中点跨 0° 算错 | 时力、动力分量错,影响行星强弱排名 | `0afa2780`:`north = tropical < 180`;民用星期按日期算并查 `_HORA_ORDER`;平运动连续计时、去掉 desantara 二次修正;新增 `chesta_from_longitudes` 短弧中点 |
| D 格局列表截断与空列表回退 | `scripts/jyotish_api_server.py` `_detect_yogas` 末尾 `return yogas[:10]`;`_chart_from_full_reading` 里 `normalized['yogas'] = chart.get('yogas') or yoga_module.get('yogas') or …` | 超过 10 条的格局被丢;已评估为空的列表被旧预览「复活」 | `e9beae6b`:去掉 `[:10]`;按「字段存在」而非「真值」取第一份列表 |
| E 月亮类 / 太阳类格局数罗计 | `references/yoga_rules.json` `bvr_002/003/004`(Sunapha/Anapha/Durudhara)、`bvr_016/017/018`(Vesi/Vosi/Ubhayachara)只排除日或月;`kemadruma_yoga` 计罗计;`scripts/yoga_expansion.py` `detect_kemadruma` 不计 | 同一张盘同时出现「月亮孤立」与「月亮有星」(泰勒、齐达内);太阳第 2 宫只有计都也判 Vesi 成立 | `2dd6062a`:bvr_002~004、016~018 只数五星;10 条重复规则进 `RETIRED_RULE_IDS`。**上游 Kemadruma 仍计罗计**(见决策 3) |
| F Arudha 宫号当星座号 | `scripts/yogas_doshas.py` `calc_arudha_lagna`、`calc_upapada_lagna`:`lord_idx = lord_house - 1` 把「第几宫」当白羊起算的星座序号,且无 1/7 宫例外 | 同一张盘 AL 与 `jaimini.calc_arudha_padas` 不同(虚构巨蟹盘:本函数 6 宫,jaimini 9 宫) | `0afa2780`:宫号→星座换算;补 1/7 例外(**从落点数第 10**,与我方 `jaimini` 的「从源宫数」不同,见决策 4) |
| G 定位星循环与未标定概率 | `scripts/jyotish_engine.py` 定位星链「最终定位星」段(多星互换循环时硬选一颗);Dasa 收敛段写死 `probability = '85-92%' / '75-85%' / '50-65%' / '+15-20%'` | 报告 PL9 表展示错误的「最终定位星」;无标定依据的概率进报告 | `e9beae6b`:`final_dispositor_from_chain`(仅自循环为终点,多星循环写 `Cycle: A -> B -> A`);`probability = None` + `probability_basis` |
## 2. 根因
上一轮同步(sync3)只对照到上游 `db8cdf4a`(09-27),并且是挑选移植:09-24 `2dd6062a` 的过运相位与格局规则、09-29 以后的 `eaa180b5`(婚姻计数第一刀)、10-02 的 `e9beae6b`(除功能吉凶外的部分)与 `0afa2780` 都没有吸收。B 项在 BUG-1060/1061 审计双重过运时漏查:那两次只核对了目标取值与跨层配对,没有核对相位判定本身。
## 3. 决策记录(产品 2026-10-02 授权)
1. 本单移植 A~G 七项;**不搬**上游 `career_analysis.py` / `assertion_policy.py`(我方普通对话不调用,事业卡已带 D10/A10/AL/AmK/功能吉凶,产品已定「不猜行业、问用户」)、上游新增的约 20 个技法脚本、PyJHora 抓取与回放脚本(AGPL 边界)、`nakshatra_dasha` / `pancha_pakshi` 修复(产品不调用)。
2. A 项:婚姻计数在我方产品里**只保留几何指数**,文案用中文中性表述(例:「关系几何指数 N:方法里的星座距离,不代表婚姻或关系的次数」);`_derived_marriage_evidence` 一律记 `neutral`,不再按次数判 `positive`。
3. E 项:沿用原月亮单已定口径——**经典定义只计火、水、木、金、土五星**(BPHS 月亮瑜伽章、Phaladeepika、B.V. Raman《Three Hundred Important Combinations》第 2–5 条),Kemadruma 两处(规则版与 `detect_kemadruma`)也只计五星,因此**与上游 Kemadruma 计罗计不同**,进度记录里写明并告知上游。太阳类 Vesi/Vosi/Ubhayachara 同样只计五星(排除月亮与罗计)。Kemadruma 的角宫解除条件不动,只在进度记录列出两处差异。执行方须引原文出处并核对 PyJHora 的实现;出处与此不符则停下报告。
4. F 项:产品口径是「多余入口宁可删除也不修」。先查 `yogas_doshas` 的 AL/UL 是否出现在任何用户可见面(报告、原始附录、数据卡、星盘页、接口响应)。**AL/UL 只留一个来源 `jaimini.calc_arudha_padas`**:可见则改成取 jaimini 的值,不可见则删除并行计算。1/7 宫例外从哪里数(源宫 / 落点)是占星师清单第 5 题,**本单不改 jaimini 的现行口径**,也不移植上游「从落点数」。
5. C 项:只移植算法修正与对应回归测试;上游把 Mercury/Venus 互换输入的 profile 改名为「历史对照、无 Raman 出处」的元数据也一并搬(只改描述,不改默认 profile)。太阳最低要求 5.0 → 6.5(清单 F3)**不在本单**,归引擎硬 bug 组。
6. 打分语义变化按 BUG-1181 先例办理:任一项让生时校正同输入出不同分,就把 `scripts/rectification/scoring_service.py` `ALGORITHM_VERSION` 升到 `rectification-v5-matrix-scoring-11`,记忆化 golden 新写 v3 文件、v1/v2 冻结不动,校正研究记录按 ERR-110 重新冻结。「日期窗合同」已按代数判断(≥ 9),本次升版不需要迁移。
## 4. 硬红线
1. `scripts/jyotish_api_server.py` 只做 D 项的 bugfix 级改动,`tests/test_api_server_growth_contract.py` 必须通过;新逻辑不进主文件。
2. 不得复制上游 AGPL 相关代码(PyJHora 抓取 / 回放、`*_pyjhora_*` 脚本);本单涉及的上游改动均为上游自写代码,移植时在提交说明里写上游提交号。
3. 不改除 E 项列明规则以外的任何格局成立条件;不改功能吉凶(v2 刚合入);不改 Narayana、岁差、罗计投射相位(占星师清单第 3、2、7 题)。
4. golden 必须由真实引擎生成(`JYOTISH_API_CHART_CACHE_TTL_SECONDS=0 PYTHONHASHSEED=0`,见 BUG-1060 防复发);改既有断言写「原值 / 新值 / 原因」三栏,不得静默弱化。
5. 生时校正 v5 77 例评测任一格下降 > 1 个百分点:停下,回退造成下降的那一项,报产品。
6. 升评分版本后必须验证历史校正 Case 仍能打开(BUG-621 教训),并跑 `tests/test_rectification_engine_memoization.py` 全文件。
7. 不改数据库结构、不动 `.gitea/workflows/**`、不提升 `main`、不 push 代码分支(交 Claude 验收后由 Claude 推 staging)。
## 5. 任务分解
每项一个提交,提交说明含上游提交号与 BUG 号。
### T1 · 婚姻计数只留几何指数(A)
- 改 `marriage_counting.py` 两个函数按决策 2;`_derived_marriage_evidence` 改 `neutral`。
- 检查个人报告(`scripts/pl9_reader_export.py` 及全读报告)是否展示这些断语,展示则一并改为中性。
- **验收**:`rg "再婚|段关系|第一段|终身关系|忠诚度" scripts/marriage_counting.py` 无命中;虚构盘(1990-06-15 10:30 北京)`/api/consultation_workflow` 婚恋主题证据里的婚姻计数条目只有几何指数且 sentiment 为 neutral;在进度记录里写明该条目是否实际出现在模型视图(用 `toModelOutput` 实测);新增回归测试锁禁句。
### T2 · 双重过运相位改为 1 起数(B)
- `_check_pac` 一处 `+ 1`;罗计仍投 5/7/9(不改,清单第 7 题)。
- **验收**:新测试覆盖土星 3/7/10、木星 5/7/9、火星 4/7/8 各一例正、反向;`tests/test_double_transit_d9_targets.py` 通过;`tests/fixtures/double_transit_d1_cl_golden.json` 与数据卡 golden 按采集脚本重生成,进度记录给出变化条目数与三栏说明;BUG 记录关联 BUG-1060/1061 并写明当时为何没拦住。
### T3 · Shadbala 四处计算修正(C)
- 先确认产品各面(星盘页、报告、数据卡、生时校正)实际调用哪条 Shadbala 入口,只改可达路径;移植上游对应测试:`test_shadbala_ayana_wrap`、`test_shadbala_hora_civil_weekday`、`test_shadbala_mean_motion_continuity`、`test_chesta_circular_midpoint`(去掉其中依赖 PyJHora 原始抓取的部分)。
- **验收**:移植测试全过;两张虚构盘改前 / 改后七星 rupa 与排名对照表写进进度记录;Shadbala 相关既有测试通过或按三栏说明更新。
### T4 · 格局列表不截断、不回退(D)
- `_detect_yogas` 去掉 `[:10]`;`_chart_from_full_reading` 的 `normalized['yogas']` 改为按「是 list」取第一份(顺序:`yoga_module.yogas` → `yoga_module.detected_yogas` → `chart.yogas`,与上游一致);全文件再搜一遍同类 `or` 链取格局列表的写法,一并列进进度记录。
- **验收**:新测试:12 条格局全部返回;`yoga_module.yogas = []` 时不回退到 `chart.yogas`;growth contract 通过;数据卡卡长若因格局变多超出 BUG-1175 的上限,按既有截断规则处理并在进度记录说明。
### T5 · 月亮类、太阳类格局只计五星(E,吸收原月亮单)
- `bvr_002/003/004`、`bvr_016/017/018`、`kemadruma_yoga`、`detect_kemadruma` 统一只计五星;同名重复规则参照上游 `RETIRED_RULE_IDS` 退役(规则留在文件里、不参与检测),退役清单逐条写进进度记录。
- **验收**:泰勒、齐达内盘不再同时出现 Kemadruma 与 Sunapha/Anapha;反例「计都单独在月亮后一宫」不成格、正例「土星在同位」成格;太阳类同理(计都单独在太阳第 2 宫不成 Vesi);名人回测 golden 用 capture 脚本重生成;出处与 PyJHora 核对写进进度记录;列出与上游 Kemadruma 的差异供告知上游。
### T6 · Arudha 只留一个来源(F)
- 按决策 4 查清可见面,再改为取 `jaimini.calc_arudha_padas` 或删除并行计算。
- **验收**:两张虚构盘上,报告、原始附录、数据卡、接口响应中的 AL/UL 全部与 `jaimini` 一致;新测试锁定「只有一个来源」(例如 `yogas_doshas` 的 AL/UL 等于 jaimini 的值,或该字段已不存在)。
### T7 · 定位星循环与去掉未标定概率(G)
- 移植 `final_dispositor_from_chain`;Dasa 收敛段 `probability` 改 `None` 并加 `probability_basis`。
- **验收**:火星金星互换的虚构盘,报告 PL9 定位星表显示 `Cycle: …` 而非硬选一颗;任何报告输出里不再出现「85-92%」一类概率;报告 golden 重生成并给出差异摘要。
### T8 · 生时校正影响、回测与记录
- 跑 `tests/test_rectification_engine_memoization.py`;分数变化则按决策 6 升 scoring-11、写 v3 golden。
- 跑 v5 77 例评测,改前 / 改后逐格对照表写进进度记录(红线 5)。
- 验证历史校正 Case 可打开(红线 6)。
- 有模型凭据时跑名人生平回测(72 份),对比 BUG-1182 收口后的基线;没有凭据写成环境缺口并进 `BLOCKED.md`。
- `docs/BUG_HISTORY.md`(从 BUG-1183 起)、`CHANGELOG.md`、`docs/tasks/PROGRESS-upstream-sync4-20261002.md`;在 `docs/tasks/README.md` 状态板把本单与原月亮单两行更新。
## 6. 让步顺序
时间不够时按此顺序保留:T1 → T4 → T2 → T5 → T3 → T6 → T7 → T8 的回测部分。T8 的记忆化与 v5 评测不可让步:只要合入了会改分数的项,就必须做。v5 评测触红线 5 时,先回退 T3,再回退 T5,逐项复测。
## 7. 不在本单(另行处理)
- 占星师清单(`engine_model_gap_and_astrologer_questions_2026_10_02.md` §6,27 题):Narayana 起法、岁差统一(含上游已把 `transit_trigger` 默认改 Raman)、罗计相位、落陷取消、Arudha 例外数法、天蝎/水瓶主星(上游 `yoga_engine` 已默认单主)、Kemadruma 解除条件等。
- 两边都还在的硬 bug:太阳 Shadbala 最低要求 5.0(应 6.5)、8 星制 PiK 排位与罗睺反算、`neechabhanga_lord_exalted` 永不成立、`curse_yoga_detector` 的「过早死亡风险」措辞、校正事件精度一律写 day——归「引擎硬 bug」任务书。
- 普通对话喂料补漏(查询路径丢 hit、精度闸、末段子运、摘要删日期等)——另一份任务书,排在本单之后。
## 8. 开工前置命令
```bash
cd /workspace/Jyotisha
git status -sb | head -1
git fetch origin --prune
git worktree add -b codex/upstream-sync4-20261002 .worktrees/upstream-sync4-20261002 origin/staging
cd .worktrees/upstream-sync4-20261002
git log -1 --oneline # 应 ≥ 588282c2
git -C /workspace/yinduzhanxing fetch origin && git -C /workspace/yinduzhanxing log -1 --oneline origin/main # 0a6696c5 或更新;更新则先比对新增提交
grep -oE "^## BUG-[0-9]+" docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45
.venv/bin/python scripts/run_quality_gate.py --profile quick # 记基线
```
上游代码一律用 `git -C /workspace/yinduzhanxing show 0a6696c5:<path>` 或 `git show <提交> -- <path>` 读取,不在上游工作树里做任何改动。