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>
106 lines
3.7 KiB
Python
Executable File
106 lines
3.7 KiB
Python
Executable File
"""Governed named-yoga draft built from shared Tajika motion evidence.
|
|
|
|
This module does not promote named yogas into authority. It packages kernel
|
|
candidate relations into a review-ready draft so the remaining closure can be
|
|
resolved under one governed vocabulary.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
try:
|
|
from tajika_kernel import calculate_tajika_interactions
|
|
except ImportError: # pragma: no cover - package import
|
|
from scripts.tajika_kernel import calculate_tajika_interactions
|
|
|
|
|
|
SCHEMA_VERSION = "jyotish.tajika_named_yoga_governed_draft.v1"
|
|
_CANDIDATE_TO_NAMED = {
|
|
"Ithasala_candidate": "Ithasala",
|
|
"Easarapha_candidate": "Easarapha",
|
|
}
|
|
|
|
|
|
def build_tajika_named_yoga_governed_draft(planets: dict[str, dict[str, Any]]) -> dict[str, Any]:
|
|
"""Package Tajika kernel candidate relations as a review-only draft."""
|
|
if not isinstance(planets, dict):
|
|
raise ValueError("planets_required")
|
|
|
|
kernel = calculate_tajika_interactions(planets)
|
|
if kernel.get("status") == "blocked":
|
|
return {
|
|
"schema_version": SCHEMA_VERSION,
|
|
"status": "blocked",
|
|
"authority_ready": False,
|
|
"claim_boundary": "governed_named_yoga_draft_requires_complete_seven_planet_kernel_inputs",
|
|
"reason": kernel.get("reason") or "tajika_kernel_blocked",
|
|
"missing": list(kernel.get("missing") or []),
|
|
"rows": [],
|
|
"summary": {
|
|
"row_count": 0,
|
|
"named_yoga_counts": {},
|
|
"motion_counts": {},
|
|
},
|
|
"limitations": [
|
|
"kernel_input_missing",
|
|
"no_named_yoga_authority",
|
|
"draft_does_not_promote_verdict",
|
|
],
|
|
}
|
|
|
|
rows: list[dict[str, Any]] = []
|
|
for item in kernel.get("candidate_yogas") or []:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
named_yoga = _CANDIDATE_TO_NAMED.get(str(item.get("name") or ""))
|
|
if not named_yoga:
|
|
continue
|
|
rows.append(
|
|
{
|
|
"named_yoga": named_yoga,
|
|
"candidate_name": item.get("name"),
|
|
"planets": list(item.get("planets") or []),
|
|
"aspect": item.get("aspect"),
|
|
"motion": item.get("motion"),
|
|
"average_deeptamsa": item.get("average_deeptamsa"),
|
|
"residual": item.get("residual"),
|
|
"rule_source": item.get("rule_source"),
|
|
"review_status": "governed_seed_resolution_review_required",
|
|
"resolution_state": "governed_seed_resolution_draft",
|
|
"claim_boundary": "candidate_relation_only_no_named_yoga_authority",
|
|
}
|
|
)
|
|
|
|
return {
|
|
"schema_version": SCHEMA_VERSION,
|
|
"status": "draft_only",
|
|
"authority_ready": False,
|
|
"claim_boundary": "governed_named_yoga_draft_only_no_named_yoga_verdict_or_promotion",
|
|
"kernel_status": kernel.get("status"),
|
|
"kernel_boundary": kernel.get("boundary"),
|
|
"rows": rows,
|
|
"summary": {
|
|
"row_count": len(rows),
|
|
"named_yoga_counts": _count(rows, "named_yoga"),
|
|
"motion_counts": _count(rows, "motion"),
|
|
},
|
|
"limitations": [
|
|
"candidate_relations_only",
|
|
"no_named_yoga_authority",
|
|
"no_final_judgment",
|
|
"governed_seed_review_required_before_promotion",
|
|
],
|
|
}
|
|
|
|
|
|
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
|