231 lines
8.4 KiB
Python
231 lines
8.4 KiB
Python
#!/usr/bin/env python3
|
|
"""VedAstro external calculation-method evidence boundary tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from copy import deepcopy
|
|
from pathlib import Path
|
|
|
|
from mcp_server import _collect_strict_evidence
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def test_vedastro_adapter_declares_external_technique_evidence_policy() -> None:
|
|
completed = subprocess.run(
|
|
[sys.executable, "scripts/vedastro_service_adapter.py", "--print-schema"],
|
|
cwd=ROOT,
|
|
text=True,
|
|
capture_output=True,
|
|
timeout=120,
|
|
check=False,
|
|
)
|
|
|
|
assert completed.returncode == 0, completed.stderr or completed.stdout
|
|
schema = json.loads(completed.stdout)
|
|
|
|
assert "external_technique_request_contract" in schema
|
|
assert "method" in schema["external_technique_request_contract"]
|
|
assert "api_endpoint" in schema["external_technique_request_contract"]
|
|
assert schema["external_technique_adjudicator_policy"] == {
|
|
"role": "external_technique_evidence",
|
|
"can_change_score": False,
|
|
"can_set_dominant_label": False,
|
|
"can_set_payout_label": False,
|
|
"allowed_destinations": ["secondary_context", "technique_audit"],
|
|
}
|
|
|
|
|
|
def test_vedastro_adapter_builds_external_technique_preview_without_network() -> None:
|
|
env = os.environ.copy()
|
|
env["VEDASTRO_API_ENDPOINT"] = "https://example.invalid/vedastro"
|
|
env.pop("VEDASTRO_ENABLE_NETWORK", None)
|
|
|
|
completed = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"scripts/vedastro_service_adapter.py",
|
|
"--external-technique",
|
|
"--domain",
|
|
"wealth",
|
|
"--method",
|
|
"CalculateShadbala",
|
|
"--api-endpoint",
|
|
"Calculate/Shadbala",
|
|
"--case",
|
|
"beijing_first_use_demo",
|
|
],
|
|
cwd=ROOT,
|
|
text=True,
|
|
capture_output=True,
|
|
timeout=120,
|
|
check=False,
|
|
env=env,
|
|
)
|
|
|
|
assert completed.returncode == 0, completed.stderr or completed.stdout
|
|
report = json.loads(completed.stdout)
|
|
|
|
assert report["backend"] == "vedastro_service_adapter_candidate"
|
|
assert report["status"] == "network_execution_disabled"
|
|
assert report["request_preview"]["operation"] == "calculation_method"
|
|
assert report["request_preview"]["role"] == "external_technique_evidence"
|
|
assert report["request_preview"]["domain"] == "wealth"
|
|
assert report["request_preview"]["method"] == "CalculateShadbala"
|
|
assert report["request_preview"]["api_endpoint"] == "Calculate/Shadbala"
|
|
assert report["adjudicator_policy"]["can_change_score"] is False
|
|
assert report["adjudicator_policy"]["can_set_dominant_label"] is False
|
|
assert report["adjudicator_policy"]["can_set_payout_label"] is False
|
|
|
|
|
|
def _finance_modules() -> dict:
|
|
return {
|
|
"varga_full": {
|
|
"D2_Hora": {"available": True},
|
|
"D10_Dasamsa": {"available": True},
|
|
},
|
|
"shadbala": {
|
|
"planets": {
|
|
"Jupiter": {
|
|
"sthana_bala": 1,
|
|
"dig_bala": 1,
|
|
"kala_bala": 1,
|
|
"chesta_bala": 1,
|
|
"naisargika_bala": 1,
|
|
"drik_bala": 1,
|
|
}
|
|
}
|
|
},
|
|
"ashtakavarga": {
|
|
"house_scores": {
|
|
"2": 28,
|
|
"11": 29,
|
|
}
|
|
},
|
|
"dasha": {
|
|
"current_dasha": {
|
|
"mahadasha": "Saturn",
|
|
"antardasha": "Mercury",
|
|
}
|
|
},
|
|
"narayana_dasha": {
|
|
"current_dasha": {
|
|
"sign": "Gemini",
|
|
"lord": "Mercury",
|
|
}
|
|
},
|
|
"dasa_convergence": {
|
|
"domain_activations": {
|
|
"wealth_family": {
|
|
"convergence_level": "L1",
|
|
"probability": "+15-20%",
|
|
}
|
|
}
|
|
},
|
|
"chart": {
|
|
"ascendant": {
|
|
"sign": "Leo",
|
|
}
|
|
},
|
|
}
|
|
|
|
|
|
def test_strict_workflow_uses_external_technique_as_context_only() -> None:
|
|
base_result = {"modules": _finance_modules()}
|
|
with_external = {"modules": deepcopy(base_result["modules"])}
|
|
with_external["modules"]["external_technique_evidence"] = {
|
|
"evidence_ledger": [
|
|
{
|
|
"source": "vedastro_service_adapter_candidate",
|
|
"operation": "calculation_method",
|
|
"role": "external_technique_evidence",
|
|
"domain": "wealth",
|
|
"method": "CalculateShadbala",
|
|
"api_endpoint": "Calculate/Shadbala",
|
|
"status": "ok",
|
|
"summary": "VedAstro Shadbala node returned as external evidence.",
|
|
}
|
|
]
|
|
}
|
|
|
|
base = _collect_strict_evidence("finance", base_result)
|
|
strict = _collect_strict_evidence("finance", with_external)
|
|
|
|
base_judgement = base["event_judgement"]
|
|
judgement = strict["event_judgement"]
|
|
|
|
assert strict["present_evidence"]["external_technique_evidence"]["level"] == "context_only"
|
|
assert strict["present_evidence"]["external_technique_evidence"]["methods"] == ["CalculateShadbala"]
|
|
assert "external_technique_evidence" in judgement["secondary_context"]
|
|
assert {
|
|
"technique": "VedAstro EventsAtRange / 596+ Calculator Radar",
|
|
"status": "blocked",
|
|
"role": "required_external_timing_radar",
|
|
"effect": "confidence_boundary_only_no_score_or_label_lift",
|
|
} in strict["technique_audit"]
|
|
assert {
|
|
"technique": "VedAstro External Technique Evidence",
|
|
"status": "used",
|
|
"role": "external_evidence_only",
|
|
"methods": ["CalculateShadbala"],
|
|
"effect": "secondary_context_only_no_score_or_label_lift",
|
|
} in strict["technique_audit"]
|
|
assert judgement["score"] == base_judgement["score"]
|
|
assert judgement["dominant_label"] == base_judgement["dominant_label"]
|
|
assert judgement["payout_label"] == base_judgement["payout_label"]
|
|
|
|
|
|
def test_strict_workflow_requires_vedastro_range_scan_boundary_for_timing_routes() -> None:
|
|
strict = _collect_strict_evidence("finance", {"modules": _finance_modules()})
|
|
|
|
assert strict["present_evidence"]["external_activation"]["level"] == "missing_required_external_radar"
|
|
assert strict["present_evidence"]["external_activation"]["source"] == "vedastro_service_adapter_candidate"
|
|
assert strict["present_evidence"]["external_activation"]["required"] is True
|
|
assert "vedastro_range_scan_missing" in strict["event_judgement"]["secondary_context"]
|
|
assert {
|
|
"technique": "VedAstro EventsAtRange / 596+ Calculator Radar",
|
|
"status": "blocked",
|
|
"role": "required_external_timing_radar",
|
|
"effect": "confidence_boundary_only_no_score_or_label_lift",
|
|
} in strict["technique_audit"]
|
|
|
|
|
|
def test_strict_workflow_marks_vedastro_range_scan_used_without_score_or_label_override() -> None:
|
|
base_result = {"modules": _finance_modules()}
|
|
with_range_scan = {"modules": deepcopy(base_result["modules"])}
|
|
with_range_scan["modules"]["external_activation"] = {
|
|
"evidence_ledger": [
|
|
{
|
|
"source": "vedastro_service_adapter_candidate",
|
|
"operation": "range_scan",
|
|
"domain": "wealth",
|
|
"event_id": "GocharJupiterIn11th",
|
|
"signal_label": "Jupiter in 11th gains window",
|
|
"score": 76,
|
|
"tags": ["wealth", "transit"],
|
|
}
|
|
]
|
|
}
|
|
|
|
base = _collect_strict_evidence("finance", base_result)
|
|
strict = _collect_strict_evidence("finance", with_range_scan)
|
|
|
|
assert strict["present_evidence"]["external_activation"]["level"] == "moderate"
|
|
assert "external_activation_support" in strict["event_judgement"]["secondary_context"]
|
|
assert "vedastro_range_scan_missing" not in strict["event_judgement"]["secondary_context"]
|
|
assert any(
|
|
row["technique"] == "VedAstro EventsAtRange / 596+ Calculator Radar"
|
|
and row["status"] == "used"
|
|
and row["event_count"] == 1
|
|
for row in strict["technique_audit"]
|
|
)
|
|
assert strict["missing_evidence"] == ["wealth_promise_strength"]
|
|
assert strict["event_judgement"]["score"] == base["event_judgement"]["score"]
|
|
assert strict["event_judgement"]["dominant_label"] == base["event_judgement"]["dominant_label"]
|
|
assert strict["event_judgement"]["payout_label"] == base["event_judgement"]["payout_label"]
|