"""Governed authority builder for auditable Tajika named yogas. This module promotes only the two named yogas whose full rule chain already shares one vocabulary with the seven-planet Tajika kernel: Ithasala and Easarapha. It does not infer broader Tajika event verdicts or unsupported named-yoga chains. """ from __future__ import annotations from typing import Any try: from tajika_named_yoga_governed_draft import build_tajika_named_yoga_governed_draft except ImportError: # pragma: no cover - package import from scripts.tajika_named_yoga_governed_draft import build_tajika_named_yoga_governed_draft SCHEMA_VERSION = "jyotish.tajika_named_yoga_authority.v1" SUPPORTED_NAMED_YOGAS = ("Ithasala", "Easarapha") def build_tajika_named_yoga_authority(planets: dict[str, dict[str, Any]]) -> dict[str, Any]: """Promote governed Tajika draft rows into a narrow authority layer.""" draft = build_tajika_named_yoga_governed_draft(planets) if draft.get("status") == "blocked": return { "schema_version": SCHEMA_VERSION, "status": "blocked", "authority_ready": False, "supported_named_yogas": list(SUPPORTED_NAMED_YOGAS), "rows": [], "reason": draft.get("reason") or "tajika_named_yoga_draft_blocked", "missing": list(draft.get("missing") or []), "claim_boundary": "named_yoga_authority_requires_complete_governed_draft_inputs", "limitations": [ "kernel_input_missing", "no_event_verdict", "unsupported_named_yogas_remain_blocked", ], } rows = [] for item in draft.get("rows") or []: if not isinstance(item, dict): continue named_yoga = item.get("named_yoga") if named_yoga not in SUPPORTED_NAMED_YOGAS: continue rows.append( { **item, "review_status": "governed_authority_ready", "resolution_state": "authority_promoted_from_shared_motion_contract", "authority_status": "supported", "claim_boundary": "named_yoga_present_absent_only_no_event_verdict", } ) return { "schema_version": SCHEMA_VERSION, "status": "authority_ready", "authority_ready": True, "supported_named_yogas": list(SUPPORTED_NAMED_YOGAS), "blocked_named_yogas": ["Nakta", "Yamaya", "Manahoo", "Kamboola"], "kernel_status": draft.get("kernel_status"), "kernel_boundary": draft.get("kernel_boundary"), "rows": rows, "summary": { "row_count": len(rows), "named_yoga_counts": _count(rows, "named_yoga"), "motion_counts": _count(rows, "motion"), }, "claim_boundary": "governed_named_yoga_authority_limited_to_present_absent_rows_for_ithasala_easarapha", "limitations": [ "no_event_verdict", "unsupported_named_yogas_remain_blocked", "annual_product_surface_not_promoted_here", ], } def _count(rows: list[dict[str, Any]], key: str) -> dict[str, int]: counts: dict[str, int] = {} for row in rows: value = row.get(key) if value in (None, ""): continue value = str(value) counts[value] = counts.get(value, 0) + 1 return counts