feat: add rectification input evidence contract
This commit is contained in:
@@ -25,3 +25,6 @@ def test_scanner_reports_real_divisional_transitions(monkeypatch):
|
||||
assert report["transitions"]
|
||||
assert report["pending_layers"] == ["UL", "A7", "A10", "KP_cusp"]
|
||||
assert report["rows"][0]["divisional_ascendants"]["D9"] in {"Aries", "Taurus"}
|
||||
assert report["input_contract"]["center_input_fingerprint"]
|
||||
assert report["rows"][0]["input_fingerprint"] != report["rows"][1]["input_fingerprint"]
|
||||
assert report["stability_contract"]["minute_confirmation_allowed"] is False
|
||||
|
||||
@@ -1,21 +1,38 @@
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from scripts import jyotishganit_vs_local_field_comparison as comparison
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json"
|
||||
|
||||
|
||||
def test_jyotishganit_vs_local_comparison_outputs_sign_rows_and_hash():
|
||||
out = subprocess.check_output(["python3", "scripts/jyotishganit_vs_local_field_comparison.py"], cwd=ROOT, text=True)
|
||||
data = json.loads(out)
|
||||
def test_jyotishganit_vs_local_comparison_outputs_sign_rows_and_hash(monkeypatch):
|
||||
def fake_local(_):
|
||||
return {code: {"Sun": {"sign": "Aries"}, "Moon": {"sign": "Taurus"}} for code in comparison.TARGETS["D2"] + comparison.TARGETS["D4"] + comparison.TARGETS["D9"] + comparison.TARGETS["D10"]}
|
||||
|
||||
def fake_jyotishganit(_):
|
||||
return {
|
||||
"divisionalCharts": {
|
||||
code.lower(): {"houses": [{"occupants": [{"celestialBody": "Sun", "sign": "Aries"}, {"celestialBody": "Moon", "sign": "Taurus"}]}]}
|
||||
for code in comparison.TARGETS
|
||||
},
|
||||
"panchanga": {},
|
||||
"ashtakavarga": {"sav": {}},
|
||||
}
|
||||
|
||||
monkeypatch.setattr(comparison, "local_varga", fake_local)
|
||||
monkeypatch.setattr(comparison, "jyotishganit_raw", fake_jyotishganit)
|
||||
data = comparison.build(comparison.build_parser().parse_args([]))
|
||||
assert data["scope"] == "jyotishganit_vs_local_field_comparison"
|
||||
assert data["claim_status"] == "observation_only"
|
||||
assert data["production_tuning_allowed"] is False
|
||||
assert data["truth_matrix_allowed"] is False
|
||||
assert data["summary"]["row_count"] >= 32
|
||||
assert data["summary"]["row_count"] == 8
|
||||
assert data["comparison_hash"]
|
||||
assert data["request"]["latitude"] == 37.7749
|
||||
assert data["request"]["longitude"] == -122.4194
|
||||
assert {row["section"] for row in data["rows"]} == {"D2", "D4", "D9", "D10"}
|
||||
assert data["coverage"]["panchanga_jyotishganit"] is True
|
||||
assert data["coverage"]["BAV_SAV_jyotishganit"] is True
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
from scripts.rectification_input_contract import (
|
||||
candidate_input_fingerprint,
|
||||
canonical_birth_input,
|
||||
semantic_evidence_hash,
|
||||
stability_probe_contract,
|
||||
)
|
||||
|
||||
|
||||
CASE = {
|
||||
"year": 1955,
|
||||
"month": 2,
|
||||
"day": 24,
|
||||
"hour": 19,
|
||||
"minute": 15,
|
||||
"lat": 37.7749,
|
||||
"lon": -122.4194,
|
||||
"tz": -8,
|
||||
}
|
||||
|
||||
|
||||
def test_canonical_birth_input_is_order_independent_and_explicit_about_settings():
|
||||
reordered = {key: CASE[key] for key in reversed(CASE)}
|
||||
|
||||
first = canonical_birth_input(CASE)
|
||||
second = canonical_birth_input(reordered)
|
||||
|
||||
assert first == second
|
||||
assert first["ayanamsa"] == "lahiri"
|
||||
assert first["node_mode"] == "true"
|
||||
assert candidate_input_fingerprint(CASE) == candidate_input_fingerprint(reordered)
|
||||
|
||||
|
||||
def test_candidate_fingerprint_changes_when_only_the_minute_changes():
|
||||
next_minute = {**CASE, "minute": 16}
|
||||
|
||||
assert candidate_input_fingerprint(CASE) != candidate_input_fingerprint(next_minute)
|
||||
|
||||
|
||||
def test_stability_probes_are_explicit_but_do_not_claim_minute_confirmation():
|
||||
contract = stability_probe_contract(CASE)
|
||||
|
||||
assert contract["status"] == "pending_score_comparison"
|
||||
assert [probe["offset_minutes"] for probe in contract["probes"]] == [-5, -2, -1, 1, 2, 5]
|
||||
assert contract["minute_confirmation_allowed"] is False
|
||||
assert contract["blocker"] == "public_blind_minute_holdout_not_closed"
|
||||
assert all("input_fingerprint" in probe for probe in contract["probes"])
|
||||
|
||||
|
||||
def test_semantic_evidence_hash_ignores_known_order_insensitive_aspect_lists_only():
|
||||
left = {"aspects": {"gives": ["Mars", "Saturn"], "receives": ["Moon", "Sun"]}, "value": [2, 1]}
|
||||
right = {"value": [2, 1], "aspects": {"receives": ["Sun", "Moon"], "gives": ["Saturn", "Mars"]}}
|
||||
changed = {"value": [1, 2], "aspects": {"receives": ["Sun", "Moon"], "gives": ["Saturn", "Mars"]}}
|
||||
|
||||
assert semantic_evidence_hash(left) == semantic_evidence_hash(right)
|
||||
assert semantic_evidence_hash(left) != semantic_evidence_hash(changed)
|
||||
@@ -8,6 +8,22 @@ SCRIPTS = Path(__file__).resolve().parents[1] / "scripts"
|
||||
if str(SCRIPTS) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS))
|
||||
|
||||
from rectification_three_engine_packet import build_packet, case_hash
|
||||
|
||||
CASE = {"year": 1990, "month": 1, "day": 1, "hour": 12, "minute": 0, "lat": 0.0, "lon": 0.0, "tz": 0.0}
|
||||
|
||||
def test_packet_is_private_and_never_confirms(monkeypatch) -> None:
|
||||
import rectification_three_engine_packet as module
|
||||
monkeypatch.setattr(module, "_local_d1", lambda _: {"Sun": "Aries"})
|
||||
monkeypatch.setattr(module, "_pyjhora_d1", lambda _: {"Sun": "Aries"})
|
||||
monkeypatch.setattr(module, "_jyotishganit_d1", lambda _: {"Sun": "Aries"})
|
||||
packet = build_packet(CASE)
|
||||
assert packet["case_hash"] == case_hash(CASE)
|
||||
assert packet["input_contract_hash"]
|
||||
assert packet["stability_contract"]["minute_confirmation_allowed"] is False
|
||||
assert "year" not in str(packet)
|
||||
assert packet["can_confirm"] is False
|
||||
assert packet["vedastro"]["status"] == "requires_gateway_raw_archive"
|
||||
|
||||
def test_packet_queues_a_privacy_safe_vedastro_receipt(monkeypatch) -> None:
|
||||
import rectification_three_engine_packet as packet
|
||||
|
||||
Reference in New Issue
Block a user