bab0718700
Web export now calls the same full pack as the long skill report and caches an owner-only Markdown download. Appendix failure stays unavailable and does not change the main report status. Co-authored-by: Cursor <cursoragent@cursor.com>
652 lines
27 KiB
Python
Executable File
652 lines
27 KiB
Python
Executable File
"""Annual Varshaphala / Tajika report pack contract.
|
|
|
|
The pack normalizes existing annual producers into a stable, audit-friendly
|
|
shape. It does not adjudicate conflicting annual methods yet; that belongs to
|
|
the next conflict-gate layer.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
from types import SimpleNamespace
|
|
from typing import Any
|
|
|
|
try: # pragma: no cover - import path differs under CLI vs pytest
|
|
from calculation_profile_contract import build_calculation_profile
|
|
except ImportError: # pragma: no cover
|
|
from scripts.calculation_profile_contract import build_calculation_profile
|
|
|
|
try: # pragma: no cover - import path differs under CLI vs pytest
|
|
from tajika_named_yoga_authority import build_tajika_named_yoga_authority
|
|
except ImportError: # pragma: no cover
|
|
from scripts.tajika_named_yoga_authority import build_tajika_named_yoga_authority
|
|
|
|
|
|
SCHEMA = "jyotish.annual_tajika_pack.v1"
|
|
|
|
|
|
def build_annual_tajika_pack(
|
|
payload: dict[str, Any],
|
|
*,
|
|
solar_return_report: dict[str, Any] | None = None,
|
|
tajika_report: dict[str, Any] | None = None,
|
|
pyjhora_replay: dict[str, Any] | None = None,
|
|
vedastro_reference: dict[str, Any] | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Build a JSON-safe annual pack for arbitrary birth payloads."""
|
|
|
|
profile = build_calculation_profile(payload)
|
|
args = _args_from_payload(payload)
|
|
|
|
solar_report = solar_return_report if solar_return_report is not None else _safe_solar_return(args)
|
|
tajika_report = tajika_report if tajika_report is not None else _safe_tajika(args)
|
|
|
|
solar_return = _field_from_report(solar_report, "solar_return", "Solar Return")
|
|
annual_chart = _annual_chart_from_solar_report(solar_report)
|
|
muntha = _field_with_conflict_gate("muntha", solar_report, tajika_report)
|
|
year_lord = _field_with_conflict_gate("year_lord", solar_report, tajika_report)
|
|
tajika_yogas = _tajika_yogas_field(solar_report)
|
|
sahams = _field_from_report(solar_report, "sahams", "Sahams")
|
|
mudda_dasha = _dasha_field("Mudda Dasha", solar_report, tajika_report, "mudda_dasha")
|
|
patyayini_dasha = _dasha_field("Patyayini Dasha", solar_report, tajika_report, "patyayini_dasha")
|
|
|
|
pack = {
|
|
"schema": SCHEMA,
|
|
"profile": {
|
|
**profile,
|
|
"target_year": int(payload["target_year"]),
|
|
},
|
|
"solar_return": solar_return,
|
|
"annual_chart": annual_chart,
|
|
"muntha": muntha,
|
|
"year_lord": year_lord,
|
|
"tajika_yogas": tajika_yogas,
|
|
"sahams": sahams,
|
|
"mudda_dasha": mudda_dasha,
|
|
"patyayini_dasha": patyayini_dasha,
|
|
"monthly_windows": _monthly_windows(mudda_dasha),
|
|
"external_engine_comparison": _external_engine_comparison(pyjhora_replay, vedastro_reference),
|
|
"report_sections": _report_sections(
|
|
profile,
|
|
muntha=muntha,
|
|
year_lord=year_lord,
|
|
tajika_yogas=tajika_yogas,
|
|
sahams=sahams,
|
|
),
|
|
"exports": {},
|
|
"audit": _audit(profile, solar_report, tajika_report, pyjhora_replay, vedastro_reference),
|
|
}
|
|
pack["exports"] = _exports(pack)
|
|
return pack
|
|
|
|
|
|
def _args_from_payload(payload: dict[str, Any]) -> SimpleNamespace:
|
|
birth = dict(payload.get("birth") or {})
|
|
settings = dict(payload.get("settings") or {})
|
|
year, month, day = [int(part) for part in str(birth["date"]).split("-")]
|
|
time_parts = [int(part) for part in str(birth.get("time") or "00:00:00").split(":")]
|
|
while len(time_parts) < 3:
|
|
time_parts.append(0)
|
|
age = payload.get("age")
|
|
if age is None and payload.get("target_year") is not None:
|
|
age = int(payload["target_year"]) - year
|
|
return SimpleNamespace(
|
|
year=year,
|
|
month=month,
|
|
day=day,
|
|
hour=time_parts[0],
|
|
minute=time_parts[1],
|
|
second=time_parts[2],
|
|
lat=float(birth["latitude"]),
|
|
lon=float(birth["longitude"]),
|
|
tz=_offset_to_hours(birth.get("utc_offset")),
|
|
target_year=int(payload["target_year"]),
|
|
age=age,
|
|
mode="all",
|
|
ayanamsa=settings.get("ayanamsa", "lahiri"),
|
|
node_mode=settings.get("node_mode", "mean"),
|
|
house_system=settings.get("house_system", "whole_sign"),
|
|
position_mode=settings.get("position_mode", "legacy"),
|
|
dasha_year_days=settings.get("dasha_year_days", 365.25),
|
|
solar_return_location_mode=settings.get("solar_return_location_mode", "birth_place"),
|
|
annual_year_policy=settings.get("annual_year_policy", "solar_return_exact"),
|
|
)
|
|
|
|
|
|
def _offset_to_hours(offset: Any) -> float:
|
|
if offset is None:
|
|
return 0.0
|
|
if isinstance(offset, (int, float)):
|
|
return float(offset)
|
|
text = str(offset).strip()
|
|
sign = -1 if text.startswith("-") else 1
|
|
text = text.lstrip("+-")
|
|
hours, minutes = [int(part) for part in text.split(":")[:2]]
|
|
return sign * (hours + minutes / 60)
|
|
|
|
|
|
def _safe_solar_return(args: SimpleNamespace) -> dict[str, Any]:
|
|
try:
|
|
from scripts.cmd_solar_return import cmd_solar_return
|
|
except ImportError: # pragma: no cover
|
|
from cmd_solar_return import cmd_solar_return
|
|
try:
|
|
result = cmd_solar_return(args)
|
|
return result if isinstance(result, dict) else {"error": "solar_return_non_dict"}
|
|
except Exception as exc: # pragma: no cover - defensive boundary
|
|
return {"error": str(exc)}
|
|
|
|
|
|
def _safe_tajika(args: SimpleNamespace) -> dict[str, Any]:
|
|
try:
|
|
from scripts.jyotish_engine import cmd_tajika
|
|
except ImportError: # pragma: no cover
|
|
from jyotish_engine import cmd_tajika
|
|
try:
|
|
result = cmd_tajika(args)
|
|
return result if isinstance(result, dict) else {"error": "tajika_non_dict"}
|
|
except Exception as exc: # pragma: no cover - defensive boundary
|
|
return {"error": str(exc)}
|
|
|
|
|
|
def _field_from_report(report: dict[str, Any], key: str, label: str) -> dict[str, Any]:
|
|
if not isinstance(report, dict) or report.get("error"):
|
|
return {"status": "blocked", "producer": label, "reason": report.get("error", "producer_failed")}
|
|
value = report.get(key)
|
|
if value is None:
|
|
return {"status": "blocked", "producer": label, "reason": f"{key}_missing"}
|
|
if isinstance(value, dict) and value.get("status") in {"blocked", "conflict", "not_applicable", "parameter_sensitive", "partial_verified", "verified"}:
|
|
normalized = {
|
|
"status": value.get("status"),
|
|
"producer": label,
|
|
"data": value,
|
|
}
|
|
if value.get("reason") is not None:
|
|
normalized["reason"] = value.get("reason")
|
|
return normalized
|
|
return {"status": "partial_verified", "producer": label, "data": value}
|
|
|
|
|
|
def _annual_chart_from_solar_report(report: dict[str, Any]) -> dict[str, Any]:
|
|
field = _field_from_report(report, "sr_chart_info", "Solar Return Annual Chart")
|
|
if field["status"] == "partial_verified":
|
|
field["data_contract"] = "normalized_from_sr_chart_info"
|
|
return field
|
|
|
|
|
|
def _tajika_yogas_field(solar_report: dict[str, Any]) -> dict[str, Any]:
|
|
if not isinstance(solar_report, dict) or solar_report.get("error"):
|
|
return _field_from_report(solar_report, "tajika_yogas", "Tajika Yogas")
|
|
authority = _build_governed_tajika_named_yoga_authority(solar_report)
|
|
if authority is None:
|
|
return _field_from_report(solar_report, "tajika_yogas", "Tajika Yogas")
|
|
return {
|
|
"status": "partial_verified" if authority.get("status") == "authority_ready" else authority.get("status", "blocked"),
|
|
"producer": "Tajika Named Yoga Authority",
|
|
"data": authority,
|
|
"data_contract": "governed_named_yoga_authority_surface",
|
|
}
|
|
|
|
|
|
def _build_governed_tajika_named_yoga_authority(solar_report: dict[str, Any]) -> dict[str, Any] | None:
|
|
planets = _extract_tajika_motion_planets(solar_report)
|
|
if not planets:
|
|
return None
|
|
authority = build_tajika_named_yoga_authority(planets)
|
|
if not isinstance(authority, dict):
|
|
return None
|
|
return authority
|
|
|
|
|
|
def _extract_tajika_motion_planets(solar_report: dict[str, Any]) -> dict[str, dict[str, float]]:
|
|
chart = solar_report.get("chart") if isinstance(solar_report.get("chart"), dict) else {}
|
|
planets = chart.get("planets") if isinstance(chart.get("planets"), dict) else {}
|
|
extracted: dict[str, dict[str, float]] = {}
|
|
for name in ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"):
|
|
payload = planets.get(name)
|
|
if not isinstance(payload, dict):
|
|
continue
|
|
longitude = payload.get("degree_raw", payload.get("degree"))
|
|
speed = payload.get("speed")
|
|
if longitude is None or speed is None:
|
|
continue
|
|
extracted[name] = {"longitude": float(longitude), "speed": float(speed)}
|
|
return extracted
|
|
|
|
|
|
def _first_available_field(label: str, *reports_and_key: Any) -> dict[str, Any]:
|
|
*reports, key = reports_and_key
|
|
producers = []
|
|
for report in reports:
|
|
field = _field_from_report(report, key, label)
|
|
producers.append(field)
|
|
if field["status"] == "partial_verified":
|
|
field["producers_checked"] = producers
|
|
return field
|
|
return {"status": "blocked", "producer": label, "reason": f"{key}_missing", "producers_checked": producers}
|
|
|
|
|
|
def _field_with_conflict_gate(key: str, solar_report: dict[str, Any], tajika_report: dict[str, Any]) -> dict[str, Any]:
|
|
values = []
|
|
for producer, report in (("solar_return", solar_report), ("tajika", tajika_report)):
|
|
if isinstance(report, dict) and report.get(key) is not None and not report.get("error"):
|
|
values.append({"producer": producer, "value": report[key]})
|
|
if len(values) >= 2 and values[0]["value"] != values[1]["value"]:
|
|
return {
|
|
"status": "conflict",
|
|
"field": key,
|
|
"values": values,
|
|
"reason": "same_profile_annual_producers_disagree",
|
|
}
|
|
if values:
|
|
return {
|
|
"status": "partial_verified",
|
|
"producer": values[0]["producer"],
|
|
"data": values[0]["value"],
|
|
"producers_checked": values,
|
|
}
|
|
return {
|
|
"status": "blocked",
|
|
"field": key,
|
|
"reason": f"{key}_missing",
|
|
"producers_checked": values,
|
|
}
|
|
|
|
|
|
def _dasha_field(label: str, solar_report: dict[str, Any], tajika_report: dict[str, Any], key: str) -> dict[str, Any]:
|
|
field = _first_available_field(label, solar_report, tajika_report, key)
|
|
data = field.get("data") if isinstance(field.get("data"), dict) else {}
|
|
periods = data.get("periods") or data.get("dasha_sequence") or []
|
|
field["periods"] = periods if isinstance(periods, list) else []
|
|
return field
|
|
|
|
|
|
def _monthly_windows(mudda_dasha: dict[str, Any]) -> list[dict[str, Any]]:
|
|
windows = []
|
|
for idx, period in enumerate(mudda_dasha.get("periods", []), start=1):
|
|
if not isinstance(period, dict):
|
|
continue
|
|
windows.append(
|
|
{
|
|
"index": idx,
|
|
"source": "mudda_dasha",
|
|
"lord": period.get("lord"),
|
|
"duration_months": period.get("months"),
|
|
"status": "partial_verified",
|
|
}
|
|
)
|
|
return windows
|
|
|
|
|
|
def _report_sections(
|
|
profile: dict[str, Any],
|
|
*,
|
|
muntha: dict[str, Any] | None = None,
|
|
year_lord: dict[str, Any] | None = None,
|
|
tajika_yogas: dict[str, Any] | None = None,
|
|
sahams: dict[str, Any] | None = None,
|
|
) -> dict[str, Any]:
|
|
blocked_fields = [
|
|
name
|
|
for name, field in (("muntha", muntha), ("year_lord", year_lord))
|
|
if isinstance(field, dict) and field.get("status") == "blocked"
|
|
]
|
|
conflict_fields = [
|
|
name
|
|
for name, field in (("muntha", muntha), ("year_lord", year_lord))
|
|
if isinstance(field, dict) and field.get("status") == "conflict"
|
|
]
|
|
all_flagged_fields = [
|
|
name
|
|
for name in (*blocked_fields, *conflict_fields)
|
|
if name
|
|
]
|
|
muntha_brief = _field_brief("Muntha", muntha)
|
|
year_lord_brief = _field_brief("Year Lord", year_lord)
|
|
tajika_brief = _field_brief("Tajika Yogas", tajika_yogas)
|
|
sahams_brief = _field_brief("Sahams", sahams)
|
|
quick_takeaways = [item for item in (muntha_brief, year_lord_brief) if item]
|
|
narrative_preview = [
|
|
"年度层已经有可读壳层,但仍需要带着冲突标签阅读。",
|
|
muntha_brief,
|
|
year_lord_brief,
|
|
]
|
|
if blocked_fields:
|
|
summary_status = "blocked"
|
|
summary_reason = "interpretive annual narrative waits for blocked field closure"
|
|
thematic_status = "blocked"
|
|
thematic_reason = "annual technique closure incomplete"
|
|
elif conflict_fields:
|
|
summary_status = "parameter_sensitive"
|
|
summary_reason = "interpretive annual narrative remains conflict-labeled until producer adjudication closes"
|
|
thematic_status = "parameter_sensitive"
|
|
thematic_reason = "annual technique conflict requires labeled reading"
|
|
else:
|
|
summary_status = "partial_verified"
|
|
summary_reason = "annual shell is readable but still awaits broader external parity closure"
|
|
thematic_status = "partial_verified"
|
|
thematic_reason = "annual technique shell available with current native evidence"
|
|
return {
|
|
"executive_summary": {
|
|
"status": summary_status,
|
|
"reason": summary_reason,
|
|
"blocked_fields": all_flagged_fields,
|
|
"summary_lines": narrative_preview,
|
|
"quick_takeaways": quick_takeaways,
|
|
},
|
|
"thematic_narrative": {
|
|
"status": thematic_status,
|
|
"reason": thematic_reason,
|
|
"highlights": [
|
|
"Solar Return / Tajika annual shell is available.",
|
|
"Muntha and Year Lord are visible, but Year Lord remains producer-disagree sensitive.",
|
|
"The report should read annual structure first, then the evidence appendix.",
|
|
],
|
|
},
|
|
"evidence_appendix": {
|
|
"status": "partial_verified",
|
|
"profile_id": profile["profile_id"],
|
|
"field_briefs": {
|
|
"muntha": muntha_brief,
|
|
"year_lord": year_lord_brief,
|
|
"tajika_yogas": tajika_brief,
|
|
"sahams": sahams_brief,
|
|
},
|
|
"must_not_claim": ["exact_annual_event_prediction"],
|
|
},
|
|
}
|
|
|
|
|
|
def _exports(pack: dict[str, Any]) -> dict[str, Any]:
|
|
exports = {
|
|
"json": {
|
|
"schema": pack["schema"],
|
|
"profile_id": pack["profile"]["profile_id"],
|
|
"field_statuses": {
|
|
key: value.get("status")
|
|
for key, value in pack.items()
|
|
if isinstance(value, dict) and "status" in value
|
|
},
|
|
},
|
|
"markdown": _markdown_summary(pack),
|
|
"ai_evidence_bundle": {
|
|
"schema": "jyotish.annual_tajika_pack.ai_evidence.v1",
|
|
"profile_id": pack["profile"]["profile_id"],
|
|
"allowed_claim_status": "blocked_until_conflict_gate",
|
|
"raw_field_paths": [
|
|
"solar_return",
|
|
"annual_chart",
|
|
"muntha",
|
|
"year_lord",
|
|
"tajika_yogas",
|
|
"sahams",
|
|
"mudda_dasha",
|
|
"patyayini_dasha",
|
|
],
|
|
},
|
|
}
|
|
try: # pragma: no cover - import path differs under CLI vs pytest
|
|
from report_pack_contract import normalize_report_pack_contract
|
|
except ImportError: # pragma: no cover
|
|
from scripts.report_pack_contract import normalize_report_pack_contract
|
|
exports["unified_report_pack_contract"] = normalize_report_pack_contract(
|
|
{**pack, "exports": exports},
|
|
pack_id="annual_tajika_pack",
|
|
)
|
|
return exports
|
|
|
|
|
|
def _markdown_summary(pack: dict[str, Any]) -> str:
|
|
rows = ["| field | status |", "| --- | --- |"]
|
|
for key in (
|
|
"solar_return",
|
|
"annual_chart",
|
|
"muntha",
|
|
"year_lord",
|
|
"tajika_yogas",
|
|
"sahams",
|
|
"mudda_dasha",
|
|
"patyayini_dasha",
|
|
"external_engine_comparison",
|
|
):
|
|
field = pack[key]
|
|
status = field.get('status')
|
|
if key == "year_lord":
|
|
values = field.get("values") or []
|
|
if values:
|
|
first = values[0].get("value") if isinstance(values[0], dict) else {}
|
|
if isinstance(first, dict):
|
|
status = f"{status}: {first.get('year_lord') or first.get('year_lord_sign')}"
|
|
rows.append(f"| {key} | {status} |")
|
|
summary = [
|
|
"",
|
|
"### Annual Reading Preview",
|
|
"",
|
|
f"- blocked fields: {', '.join((pack['report_sections']['executive_summary'].get('blocked_fields') or [])) or 'none'}",
|
|
]
|
|
return "\n".join(rows + summary)
|
|
|
|
|
|
def _external_engine_comparison(
|
|
pyjhora_replay: dict[str, Any] | None,
|
|
vedastro_reference: dict[str, Any] | None,
|
|
) -> dict[str, Any]:
|
|
if not pyjhora_replay and not vedastro_reference:
|
|
return {
|
|
"status": "blocked",
|
|
"reason": "external annual replay not integrated in annual_tajika_pack.v1",
|
|
"engines": [],
|
|
}
|
|
comparison: dict[str, Any] = {"status": "blocked", "engines": []}
|
|
statuses = []
|
|
if pyjhora_replay:
|
|
comparison["engines"].append("PyJHora/JHora")
|
|
pyjhora = dict(pyjhora_replay)
|
|
patyayini = pyjhora.get("patyayini_dasha")
|
|
if isinstance(patyayini, dict):
|
|
patyayini = dict(patyayini)
|
|
patyayini["normalized_rows"] = _normalize_patyayini_replay_rows(patyayini)
|
|
pyjhora["patyayini_dasha"] = patyayini
|
|
comparison["pyjhora"] = pyjhora
|
|
statuses.append(pyjhora_replay.get("status", "blocked"))
|
|
year_lord_replay = pyjhora_replay.get("year_lord_replay")
|
|
if isinstance(year_lord_replay, dict):
|
|
raw_artifact_path = year_lord_replay.get("raw_artifact_path")
|
|
comparison["evidence_scope"] = "pyjhora_behavior_only"
|
|
comparison["parity_status"] = "not_multiengine_parity"
|
|
comparison["raw_evidence_paths"] = [raw_artifact_path] if raw_artifact_path else []
|
|
comparison["raw_evidence_status"] = (
|
|
"archived_artifact" if raw_artifact_path else "runtime_observation_not_archived"
|
|
)
|
|
comparison["year_lord_replay"] = {
|
|
key: year_lord_replay[key]
|
|
for key in (
|
|
"status",
|
|
"reason",
|
|
"callable",
|
|
"pyjhora_version",
|
|
"effective_ayanamsa",
|
|
"request_hash",
|
|
"node_mode",
|
|
)
|
|
if key in year_lord_replay
|
|
}
|
|
if vedastro_reference:
|
|
comparison["engines"].append("VedAstro official")
|
|
comparison["vedastro"] = _sanitize_vedastro_reference(vedastro_reference)
|
|
statuses.append(comparison["vedastro"].get("status", "blocked"))
|
|
comparison["status"] = "partial_verified" if any(str(s).startswith("partial_verified") for s in statuses) else "blocked"
|
|
return comparison
|
|
|
|
|
|
def _normalize_patyayini_replay_rows(field: dict[str, Any]) -> list[dict[str, Any]]:
|
|
"""Expose PyJHora tuple shape without inferring a local Patyayini contract."""
|
|
|
|
raw = field.get("raw") if isinstance(field.get("raw"), dict) else {}
|
|
periods = raw.get("periods") if isinstance(raw.get("periods"), list) else []
|
|
rows = []
|
|
for order, period in enumerate(periods, start=1):
|
|
if not isinstance(period, (list, tuple)) or len(period) != 3:
|
|
continue
|
|
codes, boundary, duration = period
|
|
if not isinstance(codes, (list, tuple)) or len(codes) != 2:
|
|
continue
|
|
if not isinstance(boundary, (list, tuple)) or len(boundary) != 4:
|
|
continue
|
|
try:
|
|
year, month, day = (int(value) for value in boundary[:3])
|
|
hour_decimal = float(boundary[3])
|
|
boundary_display = (datetime(year, month, day) + timedelta(hours=hour_decimal)).strftime("%Y-%m-%d %H:%M:%S")
|
|
except (TypeError, ValueError, OverflowError):
|
|
continue
|
|
rows.append({
|
|
"order": order,
|
|
"main_code": codes[0],
|
|
"sub_code": codes[1],
|
|
"boundary_components": {
|
|
"year": year,
|
|
"month": month,
|
|
"day": day,
|
|
"hour_decimal": hour_decimal,
|
|
},
|
|
"boundary_display": boundary_display,
|
|
"duration_raw": duration,
|
|
"timezone_semantics": "not_returned_by_pyjhora_tuple",
|
|
"boundary_semantics": "unresolved_external_tuple_boundary",
|
|
"evidence_status": "pyjhora_behavior_only / not_multiengine_parity",
|
|
})
|
|
return rows
|
|
|
|
|
|
def _sanitize_vedastro_reference(reference: dict[str, Any]) -> dict[str, Any]:
|
|
allowed = {
|
|
"engine",
|
|
"status",
|
|
"chart_core",
|
|
"dasha_all",
|
|
"varshaphala_status",
|
|
"supported_annual_methods",
|
|
"secret_redaction",
|
|
}
|
|
sanitized = {key: value for key, value in reference.items() if key in allowed}
|
|
sanitized.setdefault("engine", "VedAstro official")
|
|
sanitized.setdefault("status", "blocked")
|
|
sanitized.setdefault("varshaphala_status", "blocked")
|
|
sanitized.setdefault("supported_annual_methods", [])
|
|
sanitized["secret_redaction"] = {"secret_material_included": False}
|
|
return sanitized
|
|
|
|
|
|
def _field_brief(label: str, field: dict[str, Any] | None) -> str:
|
|
if not isinstance(field, dict):
|
|
return f"{label}: unavailable"
|
|
status = field.get("status", "blocked")
|
|
if status == "conflict":
|
|
values = field.get("values") or []
|
|
render_values = []
|
|
for item in values[:2]:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
value = item.get("value")
|
|
if isinstance(value, dict):
|
|
render_values.append(
|
|
", ".join(
|
|
str(part)
|
|
for part in (
|
|
value.get("year_lord"),
|
|
value.get("year_lord_sign"),
|
|
value.get("muntha_sign"),
|
|
value.get("muntha_lord"),
|
|
)
|
|
if part
|
|
)
|
|
)
|
|
if render_values:
|
|
return f"{label}: conflict between { ' vs '.join(render_values) }"
|
|
if status == "partial_verified":
|
|
data = field.get("data") if isinstance(field.get("data"), dict) else {}
|
|
if label == "Muntha":
|
|
return f"{label}: {data.get('muntha_sign') or data.get('muntha_sign_idx')} / {data.get('muntha_lord') or 'unknown'}"
|
|
if label == "Year Lord":
|
|
return f"{label}: {data.get('year_lord') or 'unknown'}"
|
|
if label == "Tajika Yogas":
|
|
authority_status = data.get("status")
|
|
if authority_status == "authority_ready":
|
|
summary = data.get("summary") if isinstance(data.get("summary"), dict) else {}
|
|
row_count = summary.get("row_count")
|
|
supported = data.get("supported_named_yogas") if isinstance(data.get("supported_named_yogas"), list) else []
|
|
supported_text = "/".join(str(item) for item in supported) if supported else "governed named yogas"
|
|
return (
|
|
f"Tajika Yogas: governed authority surface visible for {supported_text}"
|
|
+ (f" ({row_count} rows)" if row_count is not None else "")
|
|
)
|
|
return "Tajika Yogas: annual candidate structures visible"
|
|
if label == "Sahams":
|
|
return "Sahams: annual sensitive points visible"
|
|
return f"{label}: {status}"
|
|
|
|
|
|
def _audit(
|
|
profile: dict[str, Any],
|
|
solar_report: dict[str, Any],
|
|
tajika_report: dict[str, Any],
|
|
pyjhora_replay: dict[str, Any] | None = None,
|
|
vedastro_reference: dict[str, Any] | None = None,
|
|
) -> dict[str, Any]:
|
|
muntha_status = _field_with_conflict_gate("muntha", solar_report, tajika_report).get("status", "blocked")
|
|
year_lord_status = _field_with_conflict_gate("year_lord", solar_report, tajika_report).get("status", "blocked")
|
|
audit = {
|
|
"profile_id": profile["profile_id"],
|
|
"technique_audit": [
|
|
{"technique": "Calculation Profile", "status": "verified", "profile_id": profile["profile_id"]},
|
|
{"technique": "Solar Return", "status": _producer_status(solar_report)},
|
|
{"technique": "Annual Chart", "status": "partial_verified" if solar_report.get("sr_chart_info") else "blocked"},
|
|
{"technique": "Muntha", "status": muntha_status},
|
|
{"technique": "Year Lord", "status": year_lord_status},
|
|
{"technique": "Tajika Yogas", "status": _tajika_yogas_field(solar_report).get("status", "blocked")},
|
|
{"technique": "Sahams", "status": "partial_verified" if solar_report.get("sahams") else "blocked"},
|
|
{"technique": "Mudda Dasha", "status": "partial_verified" if (solar_report.get("mudda_dasha") or tajika_report.get("mudda_dasha")) else "blocked"},
|
|
{"technique": "Patyayini Dasha", "status": "blocked", "reason": "native producer not integrated"},
|
|
{"technique": "External Engine Comparison", "status": "blocked", "reason": "pending Task 5/6"},
|
|
],
|
|
}
|
|
if pyjhora_replay:
|
|
year_lord_replay = pyjhora_replay.get("year_lord_replay")
|
|
audit["technique_audit"].append(
|
|
{
|
|
"technique": "PyJHora Annual Replay",
|
|
"status": pyjhora_replay.get("status", "blocked"),
|
|
"license_boundary": pyjhora_replay.get("license_boundary"),
|
|
**(
|
|
{
|
|
"evidence_scope": "pyjhora_behavior_only",
|
|
"parity_status": "not_multiengine_parity",
|
|
"raw_artifact_path": year_lord_replay.get("raw_artifact_path"),
|
|
"raw_evidence_status": (
|
|
"archived_artifact"
|
|
if year_lord_replay.get("raw_artifact_path")
|
|
else "runtime_observation_not_archived"
|
|
),
|
|
"year_lord_replay_status": year_lord_replay.get("status", "blocked"),
|
|
"node_mode": year_lord_replay.get("node_mode"),
|
|
}
|
|
if isinstance(year_lord_replay, dict)
|
|
else {}
|
|
),
|
|
}
|
|
)
|
|
if vedastro_reference:
|
|
vedastro = _sanitize_vedastro_reference(vedastro_reference)
|
|
audit["technique_audit"].append(
|
|
{
|
|
"technique": "VedAstro Annual Boundary",
|
|
"status": vedastro.get("status", "blocked"),
|
|
"varshaphala_status": vedastro.get("varshaphala_status", "blocked"),
|
|
}
|
|
)
|
|
return audit
|
|
|
|
|
|
def _producer_status(report: dict[str, Any]) -> str:
|
|
return "blocked" if report.get("error") else "partial_verified"
|