feat(tajika): annual strength layer uses the Tajika five-fold Panchavargiya (BUG-1222)
Product decision 2026-10-03: the annual Harsha / Panchavargiya strength layer's Panchavargiya column is the same `_calc_native_panchavargiya_bala` score the year-lord selection compares (BUG-1217): five components, score out of 20, labelled 「Tajika 五分力量」 / "Tajika five-fold strength". The unreachable dignity-proxy block is removed; Harsha Bala unchanged; the combined figure stays blocked (not ruled). 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
11225171ee
commit
a6cf8f8f7a
@@ -0,0 +1,68 @@
|
||||
"""BUG-1222: the annual strength layer and the year-lord selection use one score.
|
||||
|
||||
Product 2026-10-03 (TASK-astrologer-rulings-batch4-20261003 T2): the annual
|
||||
「Harsha / Panchavargiya」 strength layer's Panchavargiya column is the Tajika
|
||||
five-fold strength (`_calc_native_panchavargiya_bala`) the year-lord
|
||||
selection compares (BUG-1217), not the D1/D2/D3/D9/D12 dignity proxy.
|
||||
Fictional birth data only.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path[:0] = [ROOT, os.path.join(ROOT, "scripts")]
|
||||
|
||||
import solar_return # noqa: E402
|
||||
|
||||
pytest.importorskip("swisseph")
|
||||
|
||||
# Fictional births (no real person); several target years so the shortlist
|
||||
# branches differ.
|
||||
BIRTHS = (
|
||||
(1990, 6, 15, 12, 0, 28.6, 77.2, 5.5),
|
||||
(1975, 11, 2, 4, 30, 40.7, -74.0, -5.0),
|
||||
(2001, 2, 20, 21, 10, 51.5, -0.1, 0.0),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("birth", BIRTHS)
|
||||
@pytest.mark.parametrize("target_year", (2025, 2026))
|
||||
def test_strength_table_and_year_lord_share_the_five_fold_score(birth, target_year):
|
||||
report = solar_return.solar_return_full_report(*birth, target_year, ayanamsa_name="raman")
|
||||
strength = report["tajika_strength"]
|
||||
year_lord = report["year_lord"]
|
||||
candidates = year_lord.get("candidates") or []
|
||||
assert candidates, year_lord
|
||||
assert year_lord["panchavargiya_engine"] == "tajika_native_five_fold"
|
||||
for candidate in candidates:
|
||||
row = strength["panchavargiya_bala"][candidate["planet"]]
|
||||
assert row["status"] == "usable"
|
||||
assert row["engine"] == "tajika_native_five_fold"
|
||||
assert row["score"] == candidate["panchavargiya_score"], candidate["planet"]
|
||||
assert row["raw_total"] == candidate["panchavargiya_raw_total"], candidate["planet"]
|
||||
assert row["components"] == candidate["panchavargiya_components"], candidate["planet"]
|
||||
lord = year_lord["year_lord"]
|
||||
chosen = next(item for item in candidates if item["planet"] == lord)
|
||||
assert strength["panchavargiya_bala"][lord]["score"] == chosen["panchavargiya_score"]
|
||||
|
||||
|
||||
def test_strength_layer_has_no_dignity_proxy_fields():
|
||||
report = solar_return.solar_return_full_report(*BIRTHS[0], 2026, ayanamsa_name="raman")
|
||||
strength = report["tajika_strength"]
|
||||
assert strength["panchavargiya_method"] == "Tajika 五分力量"
|
||||
assert strength["panchavargiya_method_en"] == "Tajika five-fold strength"
|
||||
for row in strength["panchavargiya_bala"].values():
|
||||
# The proxy's D-chart components (rasi / hora / dwadasamsa …) are gone.
|
||||
assert set(row["components"]) == {"graha_bala", "uchcha_bala", "hudda_bala", "drekkana_bala", "navamsha_bala"}
|
||||
assert row["max_score"] == 20.0
|
||||
assert 0 <= row["score"] <= 20.0
|
||||
assert row["score"] == pytest.approx(row["raw_total"] / 4, abs=0.01)
|
||||
# Harsha Bala keeps its own shape and scale.
|
||||
for row in strength["harsha_bala"].values():
|
||||
assert row["status"] == "usable"
|
||||
assert row["max_score"] == 15.0
|
||||
@@ -3244,7 +3244,11 @@ def test_annual_endpoint_returns_varshaphala_report() -> None:
|
||||
strength = result['report']['tajika_strength']
|
||||
assert strength['status'] == 'partial'
|
||||
assert strength['method'] == 'Tajika Harsha/Panchavargiya Bala'
|
||||
assert strength['usable_layers'] == ['Harsha Bala']
|
||||
# 原值: strength['usable_layers'] == ['Harsha Bala']
|
||||
# 新值: ['Harsha Bala', 'Panchavargiya Bala'],Panchavargiya 为 Tajika 五分力量
|
||||
# 原因: 产品 2026-10-03 决定年运强度表统一用 Tajika 正式五分法(BUG-1222)
|
||||
assert strength['usable_layers'] == ['Harsha Bala', 'Panchavargiya Bala']
|
||||
assert strength['panchavargiya_method'] == 'Tajika 五分力量'
|
||||
assert 'harsha_bala' in strength
|
||||
assert 'panchavargiya_bala' in strength
|
||||
assert 'strongest_planets' not in strength['summary']
|
||||
|
||||
+42
-4
@@ -13,6 +13,7 @@ from tajika import (
|
||||
calc_muntha, calc_year_lord, calc_mudda_dasha,
|
||||
calc_tri_pataka, calc_tajika_yogas, detect_tajika_yogas,
|
||||
detect_vedha, calc_all_sahams, calc_tajika_strength_layers, _is_faster,
|
||||
_calc_native_panchavargiya_bala,
|
||||
SAHAM_RULES_PATH,
|
||||
SIGNS, SIGN_LORDS,
|
||||
)
|
||||
@@ -109,6 +110,10 @@ class TestTriPataka:
|
||||
# ── Harsha / Panchavargiya Bala Tests ─────────────────────────────
|
||||
|
||||
class TestTajikaStrengthLayers:
|
||||
# 原值: Panchavargiya 列 blocked('Panchavargiya Bala' in blocked_layers;usable_layers == ['Harsha Bala'];每星 status == 'blocked')
|
||||
# 新值: Panchavargiya 列由 Tajika 五分力量驱动(usable_layers == ['Harsha Bala', 'Panchavargiya Bala'];每星 status == 'usable'、
|
||||
# 分数等于 _calc_native_panchavargiya_bala、满分 20、五个分量、中英标签);合成强度仍 blocked
|
||||
# 原因: 产品 2026-10-03 决定年运强度表统一用 Tajika 正式五分法(BUG-1222,关联 BUG-1217)
|
||||
def test_harsha_and_panchavargiya_strength_layers(self):
|
||||
planet_lons = {
|
||||
'Sun': 10.0,
|
||||
@@ -124,18 +129,51 @@ class TestTajikaStrengthLayers:
|
||||
|
||||
assert result['status'] == 'partial'
|
||||
assert result['method'] == 'Tajika Harsha/Panchavargiya Bala'
|
||||
assert 'Panchavargiya Bala' in result['blocked_layers']
|
||||
assert result['usable_layers'] == ['Harsha Bala']
|
||||
assert result['blocked_layers'] == ['combined Tajika strength']
|
||||
assert result['usable_layers'] == ['Harsha Bala', 'Panchavargiya Bala']
|
||||
assert result['panchavargiya_method'] == 'Tajika 五分力量'
|
||||
assert result['panchavargiya_method_en'] == 'Tajika five-fold strength'
|
||||
assert result['summary']['next_action']
|
||||
|
||||
native = _calc_native_panchavargiya_bala(planet_lons)
|
||||
for planet in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn'):
|
||||
assert planet in result['harsha_bala']
|
||||
assert result['harsha_bala'][planet]['status'] == 'usable'
|
||||
assert planet in result['panchavargiya_bala']
|
||||
assert result['panchavargiya_bala'][planet]['status'] == 'blocked'
|
||||
row = result['panchavargiya_bala'][planet]
|
||||
assert row['status'] == 'usable'
|
||||
assert row['engine'] == 'tajika_native_five_fold'
|
||||
assert (row['label'], row['label_en']) == ('Tajika 五分力量', 'Tajika five-fold strength')
|
||||
assert row['score'] == native[planet]['score']
|
||||
assert row['raw_total'] == native[planet]['raw_total']
|
||||
assert row['max_score'] == 20.0 and row['raw_max_score'] == 80.0
|
||||
assert set(row['components']) == {'graha_bala', 'uchcha_bala', 'hudda_bala', 'drekkana_bala', 'navamsha_bala'}
|
||||
assert row['components'] == native[planet]['components']
|
||||
assert 0 <= row['score'] <= 20.0
|
||||
assert result['combined_strength'][planet]['status'] == 'blocked'
|
||||
assert result['combined_strength'][planet]['max_score'] > 0
|
||||
|
||||
def test_dignity_proxy_is_not_on_the_strength_layer(self, monkeypatch):
|
||||
"""BUG-1222: the D1/D2/D3/D9/D12 dignity proxy is never called for the table."""
|
||||
import tajika as tajika_module
|
||||
|
||||
def boom(*_args, **_kwargs):
|
||||
raise AssertionError('dignity proxy called')
|
||||
|
||||
monkeypatch.setattr(tajika_module, '_calc_panchavargiya_bala_for_planet', boom)
|
||||
planet_lons = {'Sun': 10.0, 'Moon': 45.0, 'Mars': 92.0, 'Mercury': 152.0,
|
||||
'Jupiter': 244.0, 'Venus': 330.0, 'Saturn': 300.0}
|
||||
result = tajika_module.calc_tajika_strength_layers(planet_lons, asc_lon=15.0, year_lord='Jupiter')
|
||||
assert all(row['status'] == 'usable' for row in result['panchavargiya_bala'].values())
|
||||
|
||||
def test_missing_planet_blocks_the_five_fold_column(self):
|
||||
planet_lons = {'Sun': 10.0, 'Moon': 45.0, 'Mars': 92.0}
|
||||
result = calc_tajika_strength_layers(planet_lons, asc_lon=15.0)
|
||||
assert 'Panchavargiya Bala' in result['blocked_layers']
|
||||
assert result['usable_layers'] == ['Harsha Bala']
|
||||
for row in result['panchavargiya_bala'].values():
|
||||
assert row['status'] == 'blocked'
|
||||
assert 'score' not in row
|
||||
|
||||
|
||||
# ── Tajika Yogas Tests ─────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user