Add Rangacharya comparison variant
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
SCRIPTS = os.path.join(os.path.dirname(__file__), "..", "scripts")
|
||||
if SCRIPTS not in sys.path:
|
||||
sys.path.insert(0, SCRIPTS)
|
||||
|
||||
from jyotish_api_server import JyotishAPIHandler # noqa: E402
|
||||
|
||||
|
||||
def _handler() -> JyotishAPIHandler:
|
||||
return JyotishAPIHandler.__new__(JyotishAPIHandler)
|
||||
|
||||
|
||||
def _planets():
|
||||
return {
|
||||
"Sun": {"lon": 10.0},
|
||||
"Moon": {"lon": 45.0},
|
||||
"Mars": {"lon": 80.0},
|
||||
"Mercury": {"lon": 110.0},
|
||||
"Jupiter": {"lon": 145.0},
|
||||
"Venus": {"lon": 200.0},
|
||||
"Saturn": {"lon": 250.0},
|
||||
"Rahu": {"lon": 300.0},
|
||||
"Ketu": {"lon": 120.0},
|
||||
}
|
||||
|
||||
|
||||
def test_jaimini_default_does_not_include_rangacharya():
|
||||
result = _handler()._compute_jaimini({
|
||||
"mode": "arudha",
|
||||
"ascendant": {"lon": 0.0},
|
||||
"planets": _planets(),
|
||||
})
|
||||
assert "rangacharya" not in result["result"]
|
||||
assert "rangacharya_diff" not in result["result"]
|
||||
|
||||
|
||||
def test_jaimini_variant_all_includes_current_variant_and_diff():
|
||||
result = _handler()._compute_jaimini({
|
||||
"mode": "arudha",
|
||||
"variant": "all",
|
||||
"ascendant": {"lon": 0.0},
|
||||
"planets": _planets(),
|
||||
})
|
||||
assert result["result"]["rangacharya"]["adjudication_enabled"] is False
|
||||
assert result["result"]["rangacharya_diff"]["adjudication_enabled"] is False
|
||||
assert result["result"]["rangacharya"]["arudha_padas"]["AL"]["source_card_status"] == "transcribed"
|
||||
assert result["result"]["rangacharya"]["active_lagna"]["source_card_id"] == "active_effective_lagna"
|
||||
@@ -0,0 +1,16 @@
|
||||
import pytest
|
||||
|
||||
from scripts import rangacharya
|
||||
|
||||
|
||||
def test_assert_adjudication_allowed_rejects_default_variant():
|
||||
result = rangacharya.calc_rangacharya_variant(0, {"Sun": 10.0})
|
||||
with pytest.raises(rangacharya.RangacharyaValidationError):
|
||||
rangacharya.assert_adjudication_allowed(result)
|
||||
|
||||
|
||||
def test_validation_summary_lists_blocking_rules():
|
||||
result = rangacharya.calc_rangacharya_variant(0, {"Sun": 10.0})
|
||||
summary = rangacharya.validation_summary(result)
|
||||
assert summary["adjudication_enabled"] is False
|
||||
assert summary["blocking_statuses"]
|
||||
@@ -0,0 +1,14 @@
|
||||
from scripts import rangacharya_readiness
|
||||
|
||||
|
||||
def test_readiness_reports_blocked_until_no_adjudication_cards():
|
||||
report = rangacharya_readiness.build_report()
|
||||
assert report["scope"] == "rangacharya_readiness"
|
||||
assert report["adjudication_enabled"] is False
|
||||
assert report["blocked_count"] >= 1
|
||||
assert "rangacharya_core_arudha" in report["cards"]
|
||||
|
||||
|
||||
def test_readiness_does_not_expose_secrets():
|
||||
report = rangacharya_readiness.build_report()
|
||||
assert "sk_live_" not in str(report)
|
||||
@@ -0,0 +1,17 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
REGISTRY = ROOT / "references" / "technique_registry.json"
|
||||
|
||||
|
||||
def test_rangacharya_variant_registered_as_comparison_only():
|
||||
techniques = json.loads(REGISTRY.read_text(encoding="utf-8"))["techniques"]
|
||||
entry = techniques["rangacharya_jaimini_variant"]
|
||||
assert entry["status"] == "comparison-only"
|
||||
assert entry["verification_level"]["calculation"] == "experimental"
|
||||
assert entry["verification_level"]["prediction"] == "blocked"
|
||||
assert entry["conclusion_policy"] == "Display current-vs-variant differences only; do not use for verdicts or timing."
|
||||
assert entry["evidence_role"] == "comparison_only"
|
||||
assert "references/rangacharya_source_cards.json" in entry["knowledge_refs"]
|
||||
@@ -0,0 +1,50 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
CARDS = Path("references/rangacharya_source_cards.json")
|
||||
|
||||
|
||||
REQUIRED_CARD_IDS = {
|
||||
"rangacharya_core_arudha",
|
||||
"active_effective_lagna",
|
||||
"prakriti_sanmukha",
|
||||
"rangacharya_special_mappings",
|
||||
"rangacharya_named_yogas",
|
||||
"rangacharya_ul_family_rules",
|
||||
"article_warehouse_future_tracks",
|
||||
}
|
||||
|
||||
|
||||
def _cards():
|
||||
return json.loads(CARDS.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def test_source_cards_exist_with_required_schema():
|
||||
data = _cards()
|
||||
assert data["schema_version"] == 1
|
||||
assert isinstance(data["cards"], list)
|
||||
for card in data["cards"]:
|
||||
assert card["id"]
|
||||
assert card["status"] in {
|
||||
"transcribed",
|
||||
"source_verified",
|
||||
"golden_verified",
|
||||
"engine_cross_checked",
|
||||
"case_calibrated",
|
||||
"blocked",
|
||||
}
|
||||
assert card["adjudication_enabled"] is False
|
||||
assert "evidence" in card
|
||||
|
||||
|
||||
def test_source_cards_cover_phase2_rule_groups():
|
||||
data = _cards()
|
||||
found = {card["id"] for card in data["cards"]}
|
||||
assert REQUIRED_CARD_IDS <= found
|
||||
|
||||
|
||||
def test_source_cards_do_not_contain_secrets():
|
||||
text = CARDS.read_text(encoding="utf-8")
|
||||
assert "sk_live_" not in text
|
||||
assert "VEDASTRO_API_KEY" not in text
|
||||
@@ -0,0 +1,50 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MANIFEST = Path("references/rangacharya_source_manifest.json")
|
||||
|
||||
|
||||
def test_manifest_exists_and_has_required_sections():
|
||||
data = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
||||
assert data["schema_version"] == 1
|
||||
assert "sources" in data
|
||||
assert "rules" in data
|
||||
assert "validation_ladder" in data
|
||||
|
||||
|
||||
def test_manifest_does_not_contain_secrets():
|
||||
text = MANIFEST.read_text(encoding="utf-8")
|
||||
assert "sk_live_" not in text
|
||||
assert "api_key" not in text.lower()
|
||||
|
||||
|
||||
def test_rules_default_below_adjudication():
|
||||
data = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
||||
for rule in data["rules"]:
|
||||
assert rule["status"] in {
|
||||
"transcribed",
|
||||
"source_verified",
|
||||
"golden_verified",
|
||||
"engine_cross_checked",
|
||||
"case_calibrated",
|
||||
"blocked",
|
||||
}
|
||||
assert rule["status"] != "adjudication_enabled"
|
||||
assert rule["adjudication_enabled"] is False
|
||||
|
||||
|
||||
def test_screenshot_source_paths_are_located_and_hashed():
|
||||
data = json.loads(MANIFEST.read_text(encoding="utf-8"))
|
||||
source = next(item for item in data["sources"] if item["id"] == "uploaded_screenshots_20260716")
|
||||
assert source["extraction_status"] == "located_and_hashed_ocr_blocked_tesseract_missing"
|
||||
assert len(source["paths"]) == 6
|
||||
assert all("/文件仓库/印度占星文章/260716/" in path for path in source["paths"])
|
||||
assert set(source["sha256"]) == {
|
||||
"IMG_3502.PNG",
|
||||
"IMG_3503.PNG",
|
||||
"IMG_3504.PNG",
|
||||
"IMG_3505.PNG",
|
||||
"IMG_3506.PNG",
|
||||
"IMG_3507.PNG",
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
from scripts import rangacharya
|
||||
|
||||
|
||||
SAMPLE_LONGS = {
|
||||
"Sun": 10.0,
|
||||
"Moon": 45.0,
|
||||
"Mars": 80.0,
|
||||
"Mercury": 110.0,
|
||||
"Jupiter": 145.0,
|
||||
"Venus": 200.0,
|
||||
"Saturn": 250.0,
|
||||
"Rahu": 300.0,
|
||||
"Ketu": 120.0,
|
||||
}
|
||||
|
||||
|
||||
def test_variant_result_is_experimental_and_not_for_adjudication():
|
||||
result = rangacharya.calc_rangacharya_variant(0, SAMPLE_LONGS)
|
||||
assert result["variant"] == "rangacharya"
|
||||
assert result["adjudication_enabled"] is False
|
||||
assert result["status"] == "experimental_not_for_adjudication"
|
||||
|
||||
|
||||
def test_variant_includes_core_sections():
|
||||
result = rangacharya.calc_rangacharya_variant(0, SAMPLE_LONGS)
|
||||
assert "source_status" in result
|
||||
assert "arudha_padas" in result
|
||||
assert "active_lagna" in result
|
||||
assert "effective_lagna" in result
|
||||
assert result["arudha_padas"]["AL"]["source_card_id"] == "rangacharya_core_arudha"
|
||||
assert result["arudha_padas"]["AL"]["source_card_status"] == "transcribed"
|
||||
assert result["active_lagna"]["source_card_id"] == "active_effective_lagna"
|
||||
assert result["effective_lagna"]["source_card_id"] == "active_effective_lagna"
|
||||
|
||||
|
||||
def test_diff_marks_algorithm_names():
|
||||
current = {"AL": {"sign": "Aries"}}
|
||||
variant = {"arudha_padas": {"AL": {"sign": "Taurus"}}}
|
||||
diff = rangacharya.diff_current_vs_rangacharya(current, variant)
|
||||
assert diff["current_algorithm"] == "current_jaimini"
|
||||
assert diff["variant_algorithm"] == "rangacharya"
|
||||
assert diff["differences"][0]["key"] == "AL.sign"
|
||||
Reference in New Issue
Block a user