Files
Jyotisha/tests/test_oracle_evidence_validator.py
2026-07-08 17:03:04 +08:00

579 lines
22 KiB
Python

#!/usr/bin/env python3
"""Regression tests for external oracle evidence packet validation."""
from __future__ import annotations
import json
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SHADBALA_PLANETS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"]
SHADBALA_COMPONENTS = ["sthana", "dig", "kala", "chesta", "naisargika", "drik"]
def complete_shadbala_components() -> dict[str, dict[str, float]]:
result = {}
for planet_index, planet in enumerate(SHADBALA_PLANETS):
row = {
component: round(0.1 + planet_index * 0.01 + component_index * 0.02, 4)
for component_index, component in enumerate(SHADBALA_COMPONENTS)
}
row["total_rupa"] = round(sum(row[component] for component in SHADBALA_COMPONENTS), 4)
result[planet] = row
return result
def build_queue() -> dict:
completed = subprocess.run(
[
sys.executable,
"scripts/oracle_collection_queue.py",
"--oracle-file",
"references/oracle/dasha_shadbala_oracle_cases.json",
"--format",
"json",
],
cwd=ROOT,
text=True,
capture_output=True,
timeout=30,
check=True,
)
return json.loads(completed.stdout)
def build_queue_from_file(oracle_file: Path) -> dict:
completed = subprocess.run(
[
sys.executable,
"scripts/oracle_collection_queue.py",
"--oracle-file",
str(oracle_file),
"--format",
"json",
],
cwd=ROOT,
text=True,
capture_output=True,
timeout=30,
check=True,
)
return json.loads(completed.stdout)
def run_validator(input_path: Path) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[
sys.executable,
"scripts/oracle_evidence_validator.py",
"--queue-file",
str(input_path),
],
cwd=ROOT,
text=True,
capture_output=True,
timeout=30,
check=False,
)
def test_validator_accepts_current_external_packets_but_rejects_remaining_drafts(tmp_path: Path) -> None:
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(build_queue(), ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
assert report["scope"] == "external_oracle_evidence_validation"
assert report["summary"]["total_packets"] == 4
assert report["summary"]["valid_packets"] == 3
assert report["summary"]["ready_for_calibration"] == 3
assert report["summary"]["all_packets_external_verified"] is False
first = report["packets"][0]
assert first["capture_id"] == "external_template_steve_jobs_dasha_lahiri"
assert first["valid"] is True
assert first["problems"] == []
remaining_invalid = [packet for packet in report["packets"] if not packet["valid"]]
assert remaining_invalid
assert remaining_invalid == [
{
"task_id": "collect_template_bv_raman_vimshottari_boundary_series",
"case_id": "template_bv_raman_vimshottari_boundary_series",
"capture_id": "external_template_bv_raman_vimshottari_boundary_series",
"status": "draft",
"valid": False,
"ready_for_calibration": False,
"problems": [
"missing_metadata:tool_name",
"missing_metadata:tool_version_or_url",
"missing_metadata:capture_date",
"missing_metadata:operator_note",
"missing_external_artifact",
"status_not_external_verified:draft",
],
}
]
def test_validator_accepts_filled_external_packet_but_not_whole_queue(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
metadata = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["metadata"] = metadata
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": complete_shadbala_components(),
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
assert report["summary"]["valid_packets"] == 3
assert report["summary"]["ready_for_calibration"] == 3
assert report["summary"]["all_packets_external_verified"] is False
first = report["packets"][0]
assert first["valid"] is True
assert first["problems"] == []
def test_validator_rejects_incomplete_shadbala_component_rows(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
packet["metadata"] = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_jhora_public_sample.png",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": {
"Sun": {
"sthana": 100.0,
"dig": 50.0,
}
},
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "missing_shadbala_component:Sun.kala" in first["problems"]
assert "missing_shadbala_component:Sun.chesta" in first["problems"]
assert "missing_shadbala_component:Sun.naisargika" in first["problems"]
assert "missing_shadbala_component:Sun.drik" in first["problems"]
assert "missing_shadbala_component:Moon" in first["problems"]
def test_validator_rejects_non_numeric_or_negative_shadbala_components(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
shadbala["Sun"]["sthana"] = "100"
shadbala["Moon"]["kala"] = -1.0
packet["metadata"] = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_jhora_public_sample.png",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "invalid_shadbala_component_type:Sun.sthana" in first["problems"]
assert "invalid_shadbala_component_negative:Moon.kala" in first["problems"]
def test_validator_accepts_negative_drik_bala_when_component_sum_matches(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
shadbala["Sun"]["drik"] = -0.25
shadbala["Sun"]["total_rupa"] = round(sum(shadbala["Sun"][component] for component in SHADBALA_COMPONENTS), 4)
packet["metadata"] = {
"tool_name": "PyJHora",
"tool_version_or_url": "PyJHora 4.8.7 isolated /tmp black-box run",
"capture_date": "2026-06-27",
"source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt",
"ayanamsa": "raman",
"node_mode": "PyJHora default",
"timezone": "UTC+08:00",
"operator_note": "Black-box external stdout; Drik Bala can be negative.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is True
assert first["problems"] == []
def test_validator_accepts_pyjhora_negative_dig_and_drik_values(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
for component in SHADBALA_COMPONENTS:
shadbala["Moon"][component] = 1.0
shadbala["Moon"]["dig"] = -0.5255
shadbala["Moon"]["drik"] = -0.0947
shadbala["Moon"]["total_rupa"] = round(sum(shadbala["Moon"][component] for component in SHADBALA_COMPONENTS), 4)
shadbala["Jupiter"]["drik"] = -0.0692
shadbala["Jupiter"]["total_rupa"] = round(sum(shadbala["Jupiter"][component] for component in SHADBALA_COMPONENTS), 4)
packet["metadata"] = {
"tool_name": "PyJHora",
"tool_version_or_url": "PyJHora 4.8.7 isolated /tmp black-box run",
"capture_date": "2026-06-27",
"source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt",
"ayanamsa": "lahiri",
"node_mode": "PyJHora default",
"timezone": "UTC+08:00",
"operator_note": "Black-box external stdout; PyJHora can emit negative Dig and Drik Bala values.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-25",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is True
assert first["problems"] == []
def test_validator_rejects_missing_shadbala_total_rupa(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
del shadbala["Sun"]["total_rupa"]
packet["metadata"] = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_jhora_public_sample.png",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "missing_shadbala_total_rupa:Sun" in first["problems"]
def test_validator_rejects_shadbala_component_values_above_20_rupas(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
shadbala["Sun"]["sthana"] = 20.01
shadbala["Sun"]["total_rupa"] = round(sum(shadbala["Sun"][component] for component in SHADBALA_COMPONENTS), 4)
packet["metadata"] = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_jhora_public_sample.png",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "invalid_shadbala_component_range:Sun.sthana" in first["problems"]
def test_validator_rejects_shadbala_total_rupa_sum_mismatch(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
shadbala = complete_shadbala_components()
shadbala["Sun"]["total_rupa"] = round(shadbala["Sun"]["total_rupa"] + 0.06, 4)
packet["metadata"] = {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_jhora_public_sample.png",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
}
packet["target_placeholders"] = {
"target.vimshottari_start_date": "1986-05-18",
"target.shadbala_components": shadbala,
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "shadbala_total_rupa_sum_mismatch:Sun" in first["problems"]
def test_validator_rejects_invalid_ashtakoot_score_ranges(tmp_path: Path) -> None:
queue = build_queue_from_file(ROOT / "references/oracle/ashtakoot_oracle_cases.json")
packet = queue["tasks"][0]["evidence_packet"]
packet["metadata"] = {
"tool_name": "VedAstro",
"tool_version_or_url": "https://vedastro.org/API",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_ashtakoot_case_01.png",
"ayanamsa": "lahiri",
"node_mode": "true",
"timezone": "UTC-08:00",
"operator_note": "External compatibility calculator screenshot.",
}
packet["target_placeholders"] = {
"target.total_score": 99.0,
"target.varna": 1.0,
"target.vashya": 2.0,
"target.tara": 3.0,
"target.yoni": 4.0,
"target.graha_maitri": 5.0,
"target.gana": 6.0,
"target.bhakoot": 7.0,
"target.nadi": 99.0,
"target.kuja_status": "",
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "invalid_ashtakoot_score_range:target.total_score" in first["problems"]
assert "invalid_ashtakoot_score_range:target.nadi" in first["problems"]
assert "placeholder_unfilled:target.kuja_status" in first["problems"]
def test_validator_rejects_ashtakoot_score_sum_mismatch(tmp_path: Path) -> None:
queue = build_queue_from_file(ROOT / "references/oracle/ashtakoot_oracle_cases.json")
packet = queue["tasks"][0]["evidence_packet"]
packet["metadata"] = {
"tool_name": "VedAstro",
"tool_version_or_url": "https://vedastro.org/API",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_ashtakoot_case_01.png",
"ayanamsa": "lahiri",
"node_mode": "true",
"timezone": "UTC-08:00",
"operator_note": "External compatibility calculator screenshot.",
}
packet["target_placeholders"] = {
"target.total_score": 20.0,
"target.varna": 1.0,
"target.vashya": 2.0,
"target.tara": 3.0,
"target.yoni": 4.0,
"target.graha_maitri": 5.0,
"target.gana": 6.0,
"target.bhakoot": 7.0,
"target.nadi": 8.0,
"target.kuja_status": "no_dosha",
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "ashtakoot_score_sum_mismatch" in first["problems"]
def test_validator_accepts_valid_ashtakoot_external_packet(tmp_path: Path) -> None:
queue = build_queue_from_file(ROOT / "references/oracle/ashtakoot_oracle_cases.json")
packet = queue["tasks"][0]["evidence_packet"]
packet["metadata"] = {
"tool_name": "VedAstro",
"tool_version_or_url": "https://vedastro.org/API",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/manual_ashtakoot_case_01.png",
"ayanamsa": "lahiri",
"node_mode": "true",
"timezone": "UTC-08:00",
"operator_note": "External compatibility calculator screenshot.",
}
packet["target_placeholders"] = {
"target.total_score": 18.0,
"target.varna": 1.0,
"target.vashya": 1.0,
"target.tara": 2.0,
"target.yoni": 3.0,
"target.graha_maitri": 4.0,
"target.gana": 2.0,
"target.bhakoot": 3.0,
"target.nadi": 2.0,
"target.kuja_status": "no_dosha",
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is True
assert first["problems"] == []
def test_validator_rejects_local_engine_artifact(tmp_path: Path) -> None:
queue = build_queue()
packet = queue["tasks"][0]["evidence_packet"]
packet["metadata"] = {
"tool_name": "Local Engine",
"tool_version_or_url": "this-repo",
"capture_date": "2026-06-25",
"source_artifact": "scripts/jyotish_engine.py output",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Local run",
}
packet["target_placeholders"] = {
key: 1 for key in packet["target_placeholders"]
}
packet["status"] = "external_verified"
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
first = report["packets"][0]
assert first["valid"] is False
assert "local_engine_artifact_rejected" in first["problems"]
def test_validator_accepts_external_verified_packet_generated_from_oracle_file(tmp_path: Path) -> None:
oracle = json.loads((ROOT / "references/oracle/dasha_shadbala_oracle_cases.json").read_text(encoding="utf-8"))
case = oracle["template_cases"][0]
case["status"] = "external_verified"
case["target"] = {
"moon_sidereal_longitude_deg": 311.7897,
"vimshottari_start_date": "1986-05-18",
"shadbala_components": complete_shadbala_components(),
}
case["evidence_packet"] = {
"status": "external_verified",
"metadata": {
"tool_name": "JHora",
"tool_version_or_url": "manual-screenshot-v1",
"capture_date": "2026-06-25",
"source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt",
"ayanamsa": "lahiri",
"node_mode": "mean",
"timezone": "UTC+08:00",
"operator_note": "Manual external screenshot; values typed from JHora screen.",
},
}
oracle_path = tmp_path / "oracle.json"
oracle_path.write_text(json.dumps(oracle, ensure_ascii=False), encoding="utf-8")
queue = build_queue_from_file(oracle_path)
queue_path = tmp_path / "queue.json"
queue_path.write_text(json.dumps(queue, ensure_ascii=False), encoding="utf-8")
completed = run_validator(queue_path)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
assert report["summary"]["valid_packets"] == 3
assert report["summary"]["ready_for_calibration"] == 3
assert report["summary"]["production_tuning_allowed"] is False
assert report["packets"][0]["valid"] is True
assert report["packets"][0]["problems"] == []