fix(engine): D9 double-transit targets check the D9 signs they name (BUG-1060)

`cmd_double_transit_pac` placed the `D9_{N}宫` target on the D9 lagna sign
and the `D9_{lord}(宫主)` target on that planet's D1 longitude. Both now sit
on D9 signs (D9 house-N sign; the lord's navamsa sign), built in one
testable helper. Target names, D1 and Chandra Lagna layers are unchanged
(pre-fix golden, byte-identical). Evidence-card golden regenerated with the
capture script (one public chart: double-transit conclusions 9 -> 10).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-27 17:30:05 +08:00
co-authored by Claude Opus 5.5
parent 5671039af0
commit f6fa367f2b
6 changed files with 2655 additions and 20 deletions
+29 -18
View File
@@ -13020,6 +13020,33 @@ def _check_pac(planet_name, planet_lon, target_lon, asc_idx):
return results
def _double_transit_d9_targets(asc_deg, natal, event_house, event_lord, ll_name):
"""Double Transit PAC 的 D9 层目标:返回 (D9 上升索引, {目标名: 参与 PAC 的经度})。
D9 层把过境木星/土星按 D1 星座叠到 D9 盘上、宫位从 D9 上升数,所以每个目标
都取 D9 盘上的星座中点:
- ``D9_{N}宫(<星座>)``:D9 第 N 宫星座(BUG-1060:此前误用 D9 上升星座);
- ``D9_{宫主}(宫主)``:D9 第 N 宫宫主在 D9 的星座(BUG-1060:此前误用该星 D1 度数);
- ``{D1 第 N 宫主}_D9(<星座>)`` / ``{上升主}_D9(<星座>)``:该星在 D9 的星座(KN Rao「宫主 D9 星座」)。
"""
d9_asc_idx = _navamsa_idx(asc_deg)
d9_event_si = (d9_asc_idx + event_house - 1) % 12
d9_event_sign = SIGNS[d9_event_si]
d9_event_lord = SIGN_LORDS[d9_event_sign]
def d9_si(planet):
return _navamsa_idx(natal.get(planet, {}).get('degree', 0))
event_lord_d9_si = d9_si(event_lord)
ll_d9_si = d9_si(ll_name)
return d9_asc_idx, {
f'D9_{event_house}宫({d9_event_sign})': d9_event_si * 30 + 15,
f'D9_{d9_event_lord}(宫主)': d9_si(d9_event_lord) * 30 + 15,
f'{event_lord}_D9({SIGNS[event_lord_d9_si]})': event_lord_d9_si * 30 + 15,
f'{ll_name}_D9({SIGNS[ll_d9_si]})': ll_d9_si * 30 + 15,
}
def cmd_double_transit_pac(args):
"""Double Transit PAC + D9 层计算"""
# 1. 计算本命星盘
@@ -13074,26 +13101,10 @@ def cmd_double_transit_pac(args):
}
# 4. D9 层敏感点
d9_asc_idx = _navamsa_idx(asc_deg)
d9_asc_idx, d9_targets = _double_transit_d9_targets(asc_deg, natal, event_house, event_lord, ll_name)
d9_asc_sign = SIGNS[d9_asc_idx]
d9_event_si = (d9_asc_idx + event_house - 1) % 12
d9_event_sign = SIGNS[d9_event_si]
d9_event_lord = SIGN_LORDS[d9_event_sign]
# 宫主的 D9 星座(KN Rao 关键)
event_lord_d9_si = _navamsa_idx(event_lord_lon)
event_lord_d9_sign = SIGNS[event_lord_d9_si]
ll_d9_si = _navamsa_idx(ll_lon)
ll_d9_sign = SIGNS[ll_d9_si]
d9_event_house_lon = (d9_asc_idx * 30) + 15
d9_event_lord_lon = natal.get(d9_event_lord, {}).get('degree', 0)
d9_targets = {
f'D9_{event_house}宫({d9_event_sign})': d9_event_house_lon,
f'D9_{d9_event_lord}(宫主)': d9_event_lord_lon,
f'{event_lord}_D9({event_lord_d9_sign})': event_lord_d9_si * 30 + 15,
f'{ll_name}_D9({ll_d9_sign})': ll_d9_si * 30 + 15,
}
event_lord_d9_sign = SIGNS[_navamsa_idx(event_lord_lon)]
# 5. PAC 检查
results = {
@@ -8,7 +8,13 @@ default twelve-month horizon. External VedAstro is not called (same stand-in
as the research runner). Each response is trimmed by key only: every kept
value is the engine's own value, unchanged.
PYTHONHASHSEED=0 python scripts/research/capture_consult_evidence_card_golden.py
JYOTISH_API_CHART_CACHE_TTL_SECONDS=0 PYTHONHASHSEED=0 \
python scripts/research/capture_consult_evidence_card_golden.py
The chart cache (`scratch/local/api_chart_cache`, 15-minute TTL) stores
responses with sorted keys, so a warm cache changes dict and list order (not
values) between runs; TTL 0 keeps every request cold and the output
byte-reproducible (BUG-1060).
"""
from __future__ import annotations
+2
View File
@@ -102,6 +102,8 @@ CORE_PYTEST_TARGETS = [
"tests/test_punarphoo_observation.py",
# Native technique layers exposed to the web consultation (evidence card v2).
"tests/test_consultation_native_layers.py",
# BUG-1060: Double Transit PAC D9 targets use the D9 signs their labels name.
"tests/test_double_transit_d9_targets.py",
"tests/test_relationship_event_class_evidence.py",
"tests/test_thematic_dasha_info_source.py",
"tests/test_report_orchestrator_marriage_timing.py",