Files
Jyotisha/scripts/synastry_full_dossier.py
T
jesse-uxGrok (agent loop)Cursor
cf063834ca feat(synastry): store the upstream seven-item marriage match
Move the bde5d615 engine and full-synastry skill in unchanged, save both profiles without billing or a page, and retire the old synastry module.

Checked targeted pytest, tsc 0, lint 0 errors, service tests 6/6, and test:db 73 pass / 13 fail matching the Windows known list.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 16:44:05 +08:00

71 lines
2.2 KiB
Python

"""Glue around the upstream full-synastry skill.
Two birth payloads become two native full-readings, then the untouched
``build_full_synastry_dossier``. Raman is applied to the snapshots the skill
already extracted. This module does not edit those upstream files.
"""
from __future__ import annotations
import importlib.util
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from typing import Any, Callable
from marriage_match import build_marriage_match_dossier
ROOT = Path(__file__).resolve().parents[1]
DOSSIER_SCRIPT = (
ROOT
/ "skills"
/ "jyotish-full-synastry-reading"
/ "scripts"
/ "build_full_synastry_dossier.py"
)
RULES_VERSION = "bde5d615:marriage_match_product_v1"
RAMAN_PROFILE = "raman_muhurtha_v1"
ReadingFn = Callable[[dict[str, Any]], dict[str, Any]]
def _dossier_builder():
spec = importlib.util.spec_from_file_location(
"build_full_synastry_dossier",
DOSSIER_SCRIPT,
)
if spec is None or spec.loader is None:
raise RuntimeError("full synastry dossier script is missing")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module.build_full_synastry_dossier
def build_synastry_full_dossier(
handler: Any,
person_a: dict[str, Any],
person_b: dict[str, Any],
*,
read_chart: ReadingFn | None = None,
) -> dict[str, Any]:
"""Run two full-readings in parallel, then both marriage-match profiles."""
read = read_chart or handler._compute_full_reading_for_thematic
with ThreadPoolExecutor(max_workers=2) as pool:
future_a = pool.submit(read, person_a)
future_b = pool.submit(read, person_b)
reading_a = future_a.result()
reading_b = future_b.result()
dossier = _dossier_builder()(reading_a, reading_b)
snapshots = dossier.get("chart_snapshots") if isinstance(dossier, dict) else {}
snapshots = snapshots if isinstance(snapshots, dict) else {}
raman = build_marriage_match_dossier(
snapshots.get("person_a") or {},
snapshots.get("person_b") or {},
profile_id=RAMAN_PROFILE,
)
return {
"rules_version": RULES_VERSION,
"dossier": dossier,
"raman_marriage_match": raman,
}