diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index a623fba2..d7e75165 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -13306,7 +13306,8 @@ def cmd_double_transit_pac(args): # D1 层 overlap d1_overlap = jup_d1 & sat_d1 - for t in d1_overlap: + # 按名字排序:集合遍历顺序随 PYTHONHASHSEED 变,结果列表不得随之变(BUG-1185)。 + for t in sorted(d1_overlap): results['double_transit'].append({ 'layer': 'D1', 'target': t, 'jupiter_pac': results['d1']['jupiter'][t], @@ -13316,7 +13317,7 @@ def cmd_double_transit_pac(args): # D9 层 overlap d9_overlap = jup_d9 & sat_d9 - for t in d9_overlap: + for t in sorted(d9_overlap): results['double_transit'].append({ 'layer': 'D9', 'target': t, 'jupiter_pac': results['d9']['jupiter'][t], @@ -13326,7 +13327,7 @@ def cmd_double_transit_pac(args): # Chandra Lagna 层 overlap cl_overlap = jup_cl & sat_cl - for t in cl_overlap: + for t in sorted(cl_overlap): results['double_transit'].append({ 'layer': 'CL', 'target': t, 'jupiter_pac': results['cl']['jupiter'][t], @@ -13341,8 +13342,8 @@ def cmd_double_transit_pac(args): for name, rows in target_meta['D1'].items()} d9_ids = {name: _double_transit_target_identities(rows, event_house, event_lord) for name, rows in target_meta['D9'].items()} - for d1t in jup_d1: - for d9t in sat_d9: + for d1t in sorted(jup_d1): + for d9t in sorted(sat_d9): if d1_ids[d1t] & d9_ids[d9t]: results['double_transit'].append({ 'layer': 'D1+D9', 'target': f'Jupiter(D1){d1t} + Saturn(D9){d9t}', @@ -13350,8 +13351,8 @@ def cmd_double_transit_pac(args): 'saturn_pac': results['d9']['saturn'][d9t], 'strength': 'moderate', }) - for d1t in sat_d1: - for d9t in jup_d9: + for d1t in sorted(sat_d1): + for d9t in sorted(jup_d9): if d1_ids[d1t] & d9_ids[d9t]: results['double_transit'].append({ 'layer': 'D1+D9', 'target': f'Saturn(D1){d1t} + Jupiter(D9){d9t}', diff --git a/tests/fixtures/double_transit_d1_cl_golden.json b/tests/fixtures/double_transit_d1_cl_golden.json index 354a4d3a..fabbe9ce 100644 --- a/tests/fixtures/double_transit_d1_cl_golden.json +++ b/tests/fixtures/double_transit_d1_cl_golden.json @@ -1206,7 +1206,7 @@ } ], "strength": "strong", - "target": "Venus(对宫主)" + "target": "Venus(宫主)" }, { "jupiter_pac": [ @@ -1228,7 +1228,7 @@ } ], "strength": "strong", - "target": "Venus(宫主)" + "target": "Venus(对宫主)" } ], "stats": { @@ -1629,12 +1629,12 @@ "type": "Position" }, { - "desc": "合相(6.64°)", + "desc": "合相(4.07°)", "type": "Conjunction" } ], "strength": "strong", - "target": "Venus(对宫主)" + "target": "5宫(Pisces)" }, { "jupiter_pac": [ @@ -1651,12 +1651,12 @@ "type": "Position" }, { - "desc": "合相(4.07°)", + "desc": "合相(6.64°)", "type": "Conjunction" } ], "strength": "strong", - "target": "5宫(Pisces)" + "target": "Venus(对宫主)" } ], "stats": { @@ -1880,7 +1880,7 @@ } ], "strength": "strong", - "target": "Venus(对宫主)" + "target": "Venus(宫主)" }, { "jupiter_pac": [ @@ -1902,7 +1902,7 @@ } ], "strength": "strong", - "target": "Venus(宫主)" + "target": "Venus(对宫主)" } ], "stats": { diff --git a/tests/test_double_transit_cross_layer_pairing.py b/tests/test_double_transit_cross_layer_pairing.py index 48a07c1d..577efa1e 100644 --- a/tests/test_double_transit_cross_layer_pairing.py +++ b/tests/test_double_transit_cross_layer_pairing.py @@ -7,7 +7,7 @@ while D1 ``9宫`` met any ``{planet}_D9`` / ``D9_{planet}(宫主)`` target. Real engine runs on the three public AA charts of the evidence-card research (`consult_evidence_card_lib.load_public_charts`, raman ayanamsa, mean nodes, reference date fixed in the library). D1 / D9 / CL layer results are unchanged -by this fix; `tests/test_double_transit_d9_targets.py` holds the D1 / CL golden. +by this fix (they moved later with BUG-1185, the aspect count from 1); `tests/test_double_transit_d9_targets.py` holds the D1 / CL golden. """ from __future__ import annotations @@ -147,18 +147,28 @@ def test_seventh_house_pairs_d1_house_with_d9_house(charts) -> None: assert "7宫(Pisces)" in result["d1"]["saturn"] assert "D9_7宫(Cancer)" in result["d9"]["jupiter"] assert ("Saturn", "7宫(Pisces)", "Jupiter", "D9_7宫(Cancer)") in _cross(result) - assert result["summary"].startswith("⚠️ 跨层间接") + # 原值: summary 以「⚠️ 跨层间接」开头(D1 层没有双重过运) + # 新值: 「⚠️ D1 层 Double Transit 激活…」 + # 原因: BUG-1185(TASK-upstream-sync4-20261002 T2)相位改从 1 数后,木星 9 宫相位落到 D1 7 宫, + # D1 层本身已成双重过运,摘要按 D1 优先;跨层条目仍在(上一行) + assert result["summary"].startswith("⚠️ D1 层 Double Transit 激活") def test_ninth_house_no_longer_pairs_with_an_unrelated_d9_target(charts) -> None: - """Public chart, house 9: Mars_D9 is the lagna lord's D9 sign, not the 9th house.""" - result, ctx = _public(charts, "elizabeth_taylor", 9) - assert ctx["ll_name"] == "Mars" and ctx["event_lord"] == "Moon" - # Both hits are still there; only the pairing changed. - assert "9宫(Cancer)" in result["d1"]["jupiter"] - assert "Mars_D9(Capricorn)" in result["d9"]["saturn"] - assert all(d1_target != "9宫(Cancer)" for _, d1_target, _, _ in _cross(result)) - assert all(not d9_target.startswith("Mars_D9") for _, _, _, d9_target in _cross(result)) + """Public chart, house 9: Mercury_D9 is the lagna lord's D9 sign, not the 9th house. + + 原值: 泰勒 9 宫(木星在 D1 9宫(Cancer)、土星在 Mars_D9(Capricorn)) + 新值: 乔布斯 9 宫(土星在 D1 9宫(Taurus)、木星在 Mercury_D9(Cancer)) + 原因: BUG-1185 相位改从 1 数后泰勒那组命中不再同时出现;换成同一结构(D1 9 宫 + 命主 + D9 星座、命主不是事件宫主)的另一张公开盘,断言不变。 + """ + result, ctx = _public(charts, "steve_jobs", 9) + assert ctx["ll_name"] == "Mercury" and ctx["event_lord"] == "Venus" + # Both hits are there; the pairing must not join them. + assert "9宫(Taurus)" in result["d1"]["saturn"] + assert "Mercury_D9(Cancer)" in result["d9"]["jupiter"] + assert all(d1_target != "9宫(Taurus)" for _, d1_target, _, _ in _cross(result)) + assert all(not d9_target.startswith("Mercury_D9") for _, _, _, d9_target in _cross(result)) def test_every_cross_entry_joins_the_same_event_significator(runs) -> None: @@ -188,7 +198,14 @@ def test_every_same_house_hit_becomes_a_cross_entry(runs) -> None: assert (d1_planet.title(), d1_house, d9_planet.title(), d9_house) in cross, (chart_id, house) same_house.add((chart_id, house)) # On the library reference date these are the public-chart houses where both hits happen. - assert same_house == {("elizabeth_taylor", 6), ("elizabeth_taylor", 12), ("steve_jobs", 2), ("steve_jobs", 6), ("steve_jobs", 7)} + # 原值: {泰勒 6、12;乔布斯 2、6、7} + # 新值: 下列 10 格 + # 原因: BUG-1185 相位改从 1 数(土 3/7/10、木 5/7/9 落在正确的宫),命中的宫整体平移 + assert same_house == { + ("barack_obama", 12), ("elizabeth_taylor", 3), ("elizabeth_taylor", 5), ("elizabeth_taylor", 7), + ("elizabeth_taylor", 9), ("elizabeth_taylor", 11), ("steve_jobs", 1), ("steve_jobs", 3), + ("steve_jobs", 5), ("steve_jobs", 7), + } def test_event_lord_pairs_are_kept(runs) -> None: