64 lines
2.6 KiB
Python
64 lines
2.6 KiB
Python
"""Render a bounded birth-time sensitivity appendix section."""
|
||
|
||
from __future__ import annotations
|
||
|
||
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"
|
||
|
||
|
||
class FlexibleBirthTimeReportSectionError(ValueError):
|
||
"""Raised when a sensitivity projection cannot be rendered safely."""
|
||
|
||
|
||
def render_flexible_birth_time_report_section(projection: Mapping[str, Any]) -> str:
|
||
packet = _validate_projection(projection)
|
||
window = packet.get("window") or {}
|
||
stable = packet.get("stable_structure_section") or {}
|
||
sensitive = packet.get("minute_sensitive_section") or {}
|
||
lines = [
|
||
"### 出生时间敏感度",
|
||
"",
|
||
f"- 可信区间:{window.get('start_time')}–{window.get('end_time')}",
|
||
f"- 代表分钟:{window.get('representative_time')}",
|
||
f"- 候选分钟数:{window.get('candidate_count')}",
|
||
"",
|
||
"#### 窗口内稳定层",
|
||
]
|
||
for key in stable.get("evidence_keys") or []:
|
||
lines.append(f"- `{key}`:{_render_value((stable.get('layers') or {}).get(key))}")
|
||
lines.extend(["", "#### 窗口内敏感层"])
|
||
for key in sensitive.get("evidence_keys") or []:
|
||
lines.append(f"- `{key}`:{_render_value((sensitive.get('layers') or {}).get(key))}")
|
||
lines.extend([
|
||
"",
|
||
"#### 使用边界",
|
||
"",
|
||
"- 被标记为敏感的主题只能作条件性解读,不能据此认定唯一出生分钟。",
|
||
])
|
||
return "\n".join(lines).rstrip() + "\n"
|
||
|
||
|
||
def _validate_projection(value: Mapping[str, Any]) -> dict[str, Any]:
|
||
violation = _candidate_window_authority_violation(value)
|
||
if violation:
|
||
raise FlexibleBirthTimeReportSectionError(f"candidate_window_authority_forbidden:{violation}")
|
||
if not isinstance(value, Mapping) or value.get("schema_version") != SCHEMA_VERSION:
|
||
raise FlexibleBirthTimeReportSectionError("flexible_birth_time_full_report_projection_schema_invalid")
|
||
if value.get("status") != "candidate_window_only":
|
||
raise FlexibleBirthTimeReportSectionError("projection_must_remain_candidate_window_only")
|
||
return dict(value)
|
||
|
||
|
||
def _render_value(value: Any) -> str:
|
||
if isinstance(value, Mapping):
|
||
return " / ".join(f"{key}={_render_value(item)}" for key, item in value.items())
|
||
if isinstance(value, list):
|
||
return " / ".join(_render_value(item) for item in value)
|
||
return str(value)
|