feat(tajika): year lord by the Panchadhikari rule, ported from upstream c7117f92 (BUG-1214)

Round-4 astrologer ruling Q3. tajika.calc_panchadhikari_year_lord and its
missing pieces (Tri-Rasi tables, planet index maps, ayanamsa-aware PyJHora
lookups) plus references/tajika_panchavargiya_rules.json (blob e8c15ac3) are
ported verbatim from yinduzhanxing c7117f92, with one keyword added
(muntha_sign_idx): upstream builds the Muntha-lord candidate from the annual
Lagna + years; ours stays natal Lagna + completed years (BUG-1212).

Both annual producers (solar_return_full_report, cmd_tajika) call the new
tajika_year_lord.select_annual_year_lord, so the pack conflict gate compares
the same rule. Output carries candidates / candidate_list with Panchavargiya
score and engine, aspect flags, selection_basis and a one-sentence basis
(zh/en). The product path always uses the native proxy (PyJHora is AGPL, absent
from the API image and CI); JYOTISH_YEAR_LORD_PYJHORA_REFERENCE=1 restores the
upstream PyJHora lookup for research. Card varshesha_basis and the report
'Selection basis' rows show the sentence; the BUG-1212 stand-in label is gone.
Mudda Dasha and Tri-Pataka follow the selected year lord.

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:
Jesse_Chen
2026-10-03 16:30:28 +08:00
co-authored by Claude Opus 5.5
parent bc03bba26b
commit 0afcc2d9a3
11 changed files with 633 additions and 45 deletions
+16 -4
View File
@@ -234,9 +234,12 @@ def test_real_annual_producers_agree_without_identical_metadata(reader_packet) -
field = annual["year_lord"]
assert field["status"] == "partial_verified"
left, right = [item["value"] for item in field["producers_checked"]]
assert "year_lord_sign" in left
assert "year_lord_sign" not in right
# 原值:左(太阳返照)有 year_lord_sign、右(Tajika)没有——元数据不同仍判一致
# 新值:两个生产者共用 tajika_year_lord,键相同;断言选出的年主、候选与依据一致
# 原因:BUG-1214 两个生产者改为同一 Panchadhikari 选法(任务书 T2)
assert left["year_lord"] == right["year_lord"]
assert left["candidates"] == right["candidates"]
assert left["selection_basis"] == right["selection_basis"]
assert field["data"] == left
sections = annual["report_sections"]
assert "冲突" not in repr(sections["executive_summary"]["summary_lines"])
@@ -252,7 +255,12 @@ def test_reader_annual_cells_use_real_distinct_years_and_keep_return_dates(reade
assert "-" not in lords + signs
assert len(set(lords)) >= 2
assert len(set(signs)) >= 2
assert "| Selection basis | Muntha 所在星座的守护星(当前本地口径) |" in reader
# 原值:「| Selection basis | Muntha 所在星座的守护星(当前本地口径) |」(开工基线即已失败:
# BUG-1212 把该文案改成了「暂用 Muntha 主星…」,本条未跟改)
# 新值:每个年度都有 Panchadhikari 选法依据一句话
# 原因:BUG-1214(任务书 T2)
bases = re.findall(r"^\| Selection basis \| ([^|]+) \|$", reader, re.M)
assert len(bases) == len(lords) and all("年盘上升" in basis for basis in bases)
assert "| Annual ascendant sign | - |" not in reader
timing = reader_packet["worksheets"]["timing_and_predictive_systems"]
for year in ("2027", "2028"):
@@ -274,7 +282,11 @@ def test_reader_annual_conflict_keeps_both_real_producer_values(reader_packet) -
)
assert annual["year_lord"]["status"] == "conflict"
reader = _pl9_export_markdown_for_edition(packet, "reader_main")
assert "| Varshesha | 太阳返照:火星;Tajika:金星(两者不同) |" in reader
# 原值:「太阳返照:火星;Tajika:金星(两者不同)」(当年 / 次年的 Muntha 主星)
# 新值:「太阳返照:火星;Tajika:月亮(两者不同)」(当年 / 次年按 Panchadhikari 选出的年主)
# 原因:BUG-1214 年主改为 Panchadhikari 选法(任务书 T2);本用例只测冲突两值都保留
assert (current["year_lord"], later["year_lord"]) == ("Mars", "Moon")
assert "| Varshesha | 太阳返照:火星;Tajika:月亮(两者不同) |" in reader
assert "两种计算口径给出的年主不同,暂不合并" in reader
assert "| Muntha sign | 白羊座 |" in reader
assert _leak_hits(reader) == []