fix(transit): double-transit rows in a stable order; cross-layer tests follow the aspect fix (BUG-1185)
With the aspect count from 1 (42d1582f) the public charts get same-layer
overlaps for the first time, and the overlap / cross-layer loops iterated
Python sets, so the double_transit list order changed with PYTHONHASHSEED
(the D1/CL golden failed under seeds 1 and 2). The loops now iterate sorted
names; the golden is recaptured and passes under seeds 0/1/2/5.
tests/test_double_transit_cross_layer_pairing.py: three expectations updated
with original / new / reason (Jobs house-7 summary now leads with the D1
layer; the ninth-house non-pairing example moves to Jobs house 9; the
same-house set is recomputed).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0176cb3008
commit
db5a0509da
@@ -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}',
|
||||
|
||||
+8
-8
@@ -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": {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user