- A1: ashtakavarga_shodhana.calc_sodhita_av (her entry; ashtakavarga.py frozen), level=not_calibrated + prediction_scoring_allowed=False on the chain; legacy subtraction stays removed (BUG-1209). - A2: select_narayana_seed_sign strength_profile rath_empty_sign_lord_strength_v1, shared by source-aware seed, MD and AD (matches her function on 6000 draws). - A3: preflight of logical branches; placeholder not an implementation; reference_only rules listed; 71 not_implemented; cmd_yoga not_implemented_count. - A4: neechabhanga_kendra name/category per her handoff. - 9e971559: Vimshottari AD record lord and native current PD in dasa convergence. - B10: Argala equal count stays strength_comparison_required (no Narayana borrow). - B11: full-reading bhava_bala.reference_relative_points, labelled product_relative_points_not_traditional, no bands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
75 lines
4.2 KiB
Python
75 lines
4.2 KiB
Python
"""Ported from upstream 0266b6ad (astrologer branch d09feab7, 2026-11-07 sync).
|
||
|
||
The year lord is selected by the native Tajika five-fold Panchavargiya; an
|
||
external (PyJHora) score is an observation beside it and cannot change the
|
||
selection, the components, or fill missing native inputs. The annual strength
|
||
table shows the same native score and components.
|
||
|
||
Local divergence: upstream's third test relabels the legacy Sun/Mars/Saturn
|
||
subtraction (`calc_sodhita_av`). That table was removed here (BUG-1209), so the
|
||
test asserts it stays absent and that the product chain is the classical one.
|
||
"""
|
||
from scripts import ashtakavarga, tajika
|
||
from scripts import tajika_year_lord
|
||
|
||
|
||
POSITIONS = {'Sun': 10., 'Moon': 42., 'Mars': 75., 'Mercury': 108.,
|
||
'Jupiter': 141., 'Venus': 174., 'Saturn': 207.}
|
||
|
||
|
||
def test_external_score_cannot_change_year_lord_or_native_components(monkeypatch):
|
||
monkeypatch.setattr(tajika, '_external_pyjhora_panchavargiya_score', lambda *a, **kw: None)
|
||
baseline = tajika.calc_panchadhikari_year_lord(POSITIONS, 0, 10, 25)
|
||
monkeypatch.setattr(tajika, '_external_pyjhora_panchavargiya_score',
|
||
lambda *a, **kw: {'score': 999, 'engine': 'external_fixture', 'components': {}})
|
||
observed = tajika.calc_panchadhikari_year_lord(POSITIONS, 0, 10, 25)
|
||
assert observed['year_lord'] == baseline['year_lord']
|
||
assert observed['panchavargiya_selection_policy'] == 'native_components_external_observation_only'
|
||
native = tajika._calc_native_panchavargiya_bala(POSITIONS)
|
||
for row in observed['candidates']:
|
||
assert row['panchavargiya_score'] == native[row['planet']]['score']
|
||
assert row['panchavargiya_components'] == native[row['planet']]['components']
|
||
assert row['panchavargiya_engine'] == 'tajika_native_five_fold'
|
||
assert row['external_oracle_comparison']['score'] == 999
|
||
assert row['external_oracle_comparison']['comparison_role'] == 'observation_only_not_selection_input'
|
||
|
||
|
||
def test_external_score_cannot_fill_missing_native_inputs(monkeypatch):
|
||
monkeypatch.setattr(tajika, '_external_pyjhora_panchavargiya_score',
|
||
lambda *a, **kw: {'score': 10, 'engine': 'fixture', 'components': {}})
|
||
assert tajika.calc_panchadhikari_year_lord({'Sun': 10., 'Moon': 42.}, 0, 10, 25)['status'] == 'blocked'
|
||
|
||
|
||
def test_year_lord_selection_and_strength_table_show_the_same_native_score():
|
||
selected = tajika.calc_panchadhikari_year_lord(POSITIONS, 0, 10, 25)
|
||
table = tajika.calc_tajika_strength_layers(POSITIONS, 0.0, selected['year_lord'])['panchavargiya_bala']
|
||
listed = tajika_year_lord._candidate_list(selected['candidates'], selected['year_lord'])
|
||
assert listed and any(row['selected'] for row in listed)
|
||
for row in listed:
|
||
shown = table[row['planet']]
|
||
assert row['panchavargiya_score'] == shown['score']
|
||
assert row['panchavargiya_raw_total'] == shown['raw_total']
|
||
assert row['panchavargiya_components'] == shown['components']
|
||
assert set(row['panchavargiya_components']) == {
|
||
'graha_bala', 'uchcha_bala', 'hudda_bala', 'drekkana_bala', 'navamsha_bala'}
|
||
|
||
|
||
def test_legacy_subtraction_table_stays_absent_from_the_product():
|
||
assert not hasattr(ashtakavarga, 'calc_sodhita_av')
|
||
assert not hasattr(ashtakavarga, 'calc_legacy_malefic_subtraction_av')
|
||
planets = {name: {'sign': tajika.SIGNS[int(lon // 30)]} for name, lon in POSITIONS.items()}
|
||
planets.update({'Rahu': {'sign': 'Aries'}, 'Ketu': {'sign': 'Libra'}})
|
||
av = ashtakavarga.calc_ashtakavarga(planets, 0)
|
||
from scripts.ashtakavarga_shodhana import sodhita_chain
|
||
chain = sodhita_chain(av['bav'], planets)
|
||
assert chain['status'] == 'executed'
|
||
assert 'BPHS标准' not in chain['method']
|
||
assert len(chain['sodhita_sav']['assessment']) == 12
|
||
# 新增(原因:占星师 2026-11-07 rulings.md A1):她的 calc_sodhita_av 入口在
|
||
# ashtakavarga_shodhana(ashtakavarga.py 冻结),与标准链逐格相同、不可打分
|
||
from scripts.ashtakavarga_shodhana import calc_sodhita_av
|
||
canonical = calc_sodhita_av(av['bav'], planets, 0)
|
||
assert canonical['sodhita_bav'] == chain['sodhita_bav']
|
||
assert canonical['sodhita_sav']['scores'] == chain['sodhita_sav']['scores']
|
||
assert canonical['prediction_scoring_allowed'] is False
|