77 lines
3.4 KiB
Python
77 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Read-only spike status for future ephemeris candidate adapters.
|
|
|
|
The script does not load alternate calculation engines. It records whether a
|
|
candidate_backend is executable enough to enter the parity gate defined by
|
|
scripts/ephemeris_adapter_contract.py.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any, Dict
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _exists(*parts: str) -> bool:
|
|
return ROOT.joinpath(*parts).exists()
|
|
|
|
|
|
def build_spike() -> Dict[str, Any]:
|
|
xalen_local_paths = [
|
|
"references/open_source_sources/xalen-ephemeris",
|
|
"references/open_source_sources/xalen",
|
|
]
|
|
xalen_ephemeris_candidate = {
|
|
"candidate_backend": "xalen_ephemeris_candidate",
|
|
"candidate_adapter_spike": "documented_no_local_executable",
|
|
"available": any(_exists(*path.split("/")) for path in xalen_local_paths),
|
|
"evidence": [path for path in xalen_local_paths if _exists(*path.split("/"))] or ["no local xalen mirror detected"],
|
|
"license_gate": "Apache-2.0 candidate from vedika-io/xalen-ephemeris; fetch/build/review before any adapter code is added.",
|
|
"runtime_setting_exposure": "blocked_until_parity_gate_required",
|
|
"parity_gate_required": "Must produce Sun/Moon/Asc/Rahu/Ketu rows compatible with EphemerisAdapterContract.",
|
|
}
|
|
|
|
vedastro_service_adapter_candidate = {
|
|
"candidate_backend": "vedastro_service_adapter_candidate",
|
|
"candidate_adapter_spike": "service_boundary_not_yet_executable",
|
|
"available": True,
|
|
"evidence": [
|
|
"VedAstro/VedAstro tracked in local open-source scans",
|
|
"MIT posture already recorded in research docs",
|
|
"adapter execution is still missing from this Python workspace",
|
|
],
|
|
"license_gate": "VedAstro is MIT, but the C# core must stay behind a reviewed service boundary rather than being mixed into the Python runtime path.",
|
|
"runtime_setting_exposure": "blocked_until_parity_timeout_and_license_gates",
|
|
"parity_gate_required": "Must emit EphemerisAdapterContract rows, enforce timeout handling, and pass longitude parity thresholds before any runtime setting exposure.",
|
|
"service_gate": "Need a documented request schema, response normalization layer, retry/timeout policy, and provenance fields before wiring a real adapter.",
|
|
}
|
|
|
|
return {
|
|
"valid": True,
|
|
"candidate_adapter_spike": True,
|
|
"runtime_setting_exposure": "do_not_expose_non_swisseph_backend_yet",
|
|
"license_gate": {
|
|
"xalen_ephemeris_candidate": xalen_ephemeris_candidate["license_gate"],
|
|
"vedastro_service_adapter_candidate": vedastro_service_adapter_candidate["license_gate"],
|
|
},
|
|
"parity_gate_required": "Run scripts/ephemeris_adapter_contract.py with real candidate rows before settings exposure.",
|
|
"candidate_backends": {
|
|
"xalen_ephemeris_candidate": xalen_ephemeris_candidate,
|
|
"vedastro_service_adapter_candidate": vedastro_service_adapter_candidate,
|
|
},
|
|
"next_step": "Implement an isolated candidate adapter only after local executable assets or a reviewed external service boundary are present.",
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
print(json.dumps(build_spike(), ensure_ascii=False, indent=2, sort_keys=True))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|