Files
Jyotisha/scripts/flexible_birth_time_full_report_projection.py
T
2026-09-04 02:11:57 +08:00

54 lines
2.5 KiB
Python

"""Build the report-facing projection of birth-time sensitivity evidence."""
from __future__ import annotations
from copy import deepcopy
from hashlib import sha256
import json
from typing import Any, Mapping
try:
from flexible_birth_time_profile import _candidate_window_authority_violation
except ImportError: # pragma: no cover - package import
from scripts.flexible_birth_time_profile import _candidate_window_authority_violation
SCHEMA_VERSION = "jyotish.flexible_birth_time_full_report_projection.v1"
SUPPORT_SCHEMA_VERSION = "jyotish.flexible_birth_time_report_support.v1"
class FlexibleBirthTimeFullReportProjectionError(ValueError):
"""Raised when report support cannot be projected safely."""
def build_flexible_birth_time_full_report_projection(support: Mapping[str, Any]) -> dict[str, Any]:
packet = _validate_support(support)
window = deepcopy(dict(packet.get("birth_time_window") or {}))
return {
"schema_version": SCHEMA_VERSION,
"projection_id": _digest_id(str(packet.get("support_id")), json.dumps(window, sort_keys=True, separators=(",", ":"))),
"report_section_type": "birth_time_sensitivity",
"window": window,
"stable_structure_section": deepcopy(dict(packet.get("stable_report_evidence") or {})),
"minute_sensitive_section": deepcopy(dict(packet.get("sensitive_report_evidence") or {})),
"theme_sensitivity": deepcopy(dict(packet.get("theme_sensitivity") or {})),
"trace": deepcopy(list(packet.get("trace") or [])),
"status": "candidate_window_only",
"claim_boundary": str(packet.get("claim_boundary") or "Sensitivity remains conditional."),
}
def _validate_support(value: Mapping[str, Any]) -> dict[str, Any]:
violation = _candidate_window_authority_violation(value)
if violation:
raise FlexibleBirthTimeFullReportProjectionError(f"candidate_window_authority_forbidden:{violation}")
if not isinstance(value, Mapping) or value.get("schema_version") != SUPPORT_SCHEMA_VERSION:
raise FlexibleBirthTimeFullReportProjectionError("flexible_birth_time_report_support_schema_invalid")
if value.get("status") != "candidate_window_only":
raise FlexibleBirthTimeFullReportProjectionError("support_must_remain_candidate_window_only")
return dict(value)
def _digest_id(*parts: str) -> str:
payload = json.dumps(parts, ensure_ascii=True, separators=(",", ":"))
return f"flex-report-projection://{sha256(payload.encode('utf-8')).hexdigest()[:24]}"