"""Assembly locks for longform gaps2: no silent skips, audit rows, provenance.""" from __future__ import annotations from types import SimpleNamespace from scripts.jyotish_engine import ( PLANNED_LONGFORM_SECTION_HEADINGS, _annual_series_surface, _attach_report_governance_contracts, _birth_provenance_from_args, _native_dasha_master_families, render_pl9_markdown, sanitize_professional_report_reference, ) from scripts.timing_precision_contract import build_timing_precision_contract from tests.test_report_longform_parity import BEIJING, _producer_packet def test_kp_error_pack_emits_blocked_heading_instead_of_vanishing() -> None: markdown = render_pl9_markdown(_producer_packet({ "advanced_systems": {"kp": {"error": "synthetic_kp_failure", "status": "blocked"}}, })) assert "### KP Lord / Sub 原始表(本地计算)" in markdown assert "kp_lord_sub_unavailable" in markdown assert "#### KP 事业结构小表" in markdown assert "#### KP 事业宫位核对(2 / 6 / 10 / 11 宫)" in markdown assert "#### KP 财务结构小表" in markdown assert "#### KP 关系结构小表" in markdown def test_planned_headings_are_present_or_blocked_on_empty_packet() -> None: markdown = render_pl9_markdown(_producer_packet({})) missing = [heading for heading in PLANNED_LONGFORM_SECTION_HEADINGS if heading not in markdown] assert missing == [], f"planned headings vanished: {missing}" def test_module_execution_audit_survives_raw_strip() -> None: packet = { "raw_full_reading": { "modules": { "kp": {"planets": {"Sun": {}}, "status": "available"}, "dasha": {"current_dasha": {"lord": "Saturn"}}, "shadbala": {"planets": {"Sun": {}}}, }, "ai_prompt_pack": {}, }, "worksheets": {}, } packet = _attach_report_governance_contracts(packet, SimpleNamespace(**BEIJING)) sanitized = sanitize_professional_report_reference(packet) assert "raw_full_reading" not in sanitized assert len(sanitized["module_execution_audit"]) >= 3 assert len(sanitized["technique_audit_table"]) >= 5 assert any(row.get("module_id") == "kp" for row in sanitized["module_execution_audit"]) assert any(row.get("technique") == "KP Lord/Sub" for row in sanitized["technique_audit_table"]) markdown = render_pl9_markdown(_producer_packet({}) | { "module_execution_audit": sanitized["module_execution_audit"], "technique_audit_table": sanitized["technique_audit_table"], "raw_module_index": sanitized["raw_module_index"], }) data_rows = [ line for line in markdown.splitlines() if line.startswith("| `kp`") or line.startswith("| `dasha`") or line.startswith("| `shadbala`") ] assert len(data_rows) >= 3 def test_timing_contract_tiers_do_not_default_all_blocked_when_annual_exists() -> None: contract = build_timing_precision_contract({ "annual_series": {"years": {"2026": {}, "2027": {}, "2028": {}}}, }) assert contract["tiers"]["day"]["status"] == "blocked" assert contract["tiers"]["week"]["status"] == "parameter_sensitive" assert contract["tiers"]["month"]["status"] == "parameter_sensitive" assert contract["tiers"]["year"]["status"] == "partial_verified" assert contract["tiers"]["week"]["allowed_claims"] assert "exact_day_event" in contract["tiers"]["day"]["prohibited_claims"] def test_birth_provenance_reads_optional_args() -> None: packet = _attach_report_governance_contracts( {"worksheets": {}, "raw_full_reading": {"modules": {}}}, SimpleNamespace( **BEIJING, birthplace_label="测试市", coordinate_source="user_reported", coordinate_precision="unverified_user_coordinates", time_source="user_reported", uncertainty_minutes=20, ), ) provenance = packet["birth_provenance"] assert provenance["birthplace_label"] == "测试市" assert provenance["coordinate_source"] == "user_reported" assert provenance["time_source"] == "user_reported" assert provenance["uncertainty_minutes"] == 20 def test_annual_series_surface_keeps_replay_keys() -> None: surface = _annual_series_surface({ "status": "partial_verified", "profile": {"target_year": 2027}, "external_engine_comparison": {"pyjhora": {"patyayini_dasha": {"normalized_rows": [{"order": 1}]}}}, "sahams": {"status": "parameter_sensitive"}, }) assert "external_engine_comparison" in surface assert surface["external_engine_comparison"]["pyjhora"]["patyayini_dasha"]["normalized_rows"] assert surface["sahams"]["status"] == "parameter_sensitive" def test_native_dasha_families_expose_execution_status() -> None: families = _native_dasha_master_families({ "dasha": {"current_dasha": {"lord": "Saturn"}}, "narayana_dasha": {"status": "computed"}, "yogini_dasha": {"major": [{"yogini": "Mangala", "planet": "Moon", "years": 1}]}, "kalachakra_dasha": {"status": "computed", "periods": [{"lord": "Sun"}]}, }) assert families["vimshottari"]["execution_status"] == "executed" assert families["yogini"]["execution_status"] == "executed" assert families["kala_chakra"]["execution_status"] == "executed" def test_auxiliary_dasha_headings_render_from_native_modules() -> None: markdown = render_pl9_markdown(_producer_packet({ "timing_and_predictive_systems": { "narayana_dasha": { "lagna_sign": "Aries", "periods": [{ "sign": "Aries", "lord": "Mars", "start": "0", "end": "1", "years": 1, }], }, "yogini_dasha": { "major": [{ "yogini": "Mangala", "planet": "Moon", "years": 1, "start_date": "1990-01-01", "end_date": "1991-01-01", }], }, "kalachakra_dasha": { "periods": [{ "lord": "Sun", "sign": "Aries", "start": "1990-01-01", "end": "1991-01-01", "years": 1, }], }, }, "strengths_and_scores": { "bhava_bala": { "houses": [{ "house": 1, "sign": "Aries", "lord": "Mars", "score": 1, "components": {"lord_position": 1, "occupant_influence": 0, "aspect_influence": 0}, }], }, }, })) assert "#### Yogini Dasha 周期(本地计算)" in markdown assert "#### Narayana Rashi Dasha" in markdown assert "#### Kala Chakra Dasha(本地原始周期,冲突保留)" in markdown assert "#### Bhava Bala(本地三分量评分)" in markdown def test_quality_gate_runs_this_file() -> None: from scripts.run_quality_gate import CORE_PYTEST_TARGETS assert "tests/test_report_longform_gaps2.py" in CORE_PYTEST_TARGETS assert "tests/test_report_longform_parity.py" in CORE_PYTEST_TARGETS assert "tests/test_timing_precision_contract.py" in CORE_PYTEST_TARGETS assert "tests/test_flexible_birth_time_report_contract.py" in CORE_PYTEST_TARGETS def test_kp_monthly_theme_brief_keeps_heading_when_months_exist() -> None: markdown = render_pl9_markdown(_producer_packet({ "advanced_systems": { "kp_monthly_report": { "months": [ { "month": "2026-01", "theme_support": { "career": {"brief_summary": "career-support", "active_houses": [10]}, "wealth": {"brief_summary": "wealth-support", "active_houses": [2]}, "relationship": {"brief_summary": "relationship-support", "active_houses": [7]}, }, "vimshottari_five_levels": { "levels": { "mahadasha": {"lord": "Saturn"}, "antardasha": {"lord": "Mercury"}, } }, } ] } } })) assert "#### KP 事业逐月 MD/AD 支持" in markdown assert "#### KP 财务逐月 MD/AD 支持" in markdown assert "#### KP 关系逐月 MD/AD 支持" in markdown assert "career-support" in markdown assert markdown.count("#### KP 事业逐月 MD/AD 支持") == 1 assert "kp_monthly_payload_empty" not in markdown assert "planned_section_unavailable" not in markdown.split("#### KP 事业逐月 MD/AD 支持", 1)[-1].split("#### KP 财务逐月 MD/AD 支持", 1)[0] def test_sanitized_packet_keeps_timing_source_labels() -> None: packet = _attach_report_governance_contracts( _producer_packet({}), SimpleNamespace(**BEIJING, birth_time_accuracy="confirmed"), ) sanitized = sanitize_professional_report_reference(packet) markdown = render_pl9_markdown(sanitized) assert "full-reading Dasha module" in markdown assert "full-reading Narayana module" in markdown assert "annual Tajika series" in markdown assert "KP exact cusp oracle status" in markdown assert "raw_full_reading.modules" not in markdown assert "references/oracle" not in markdown def test_birth_provenance_uses_candidate_window_minutes() -> None: provenance = _birth_provenance_from_args(SimpleNamespace( birthplace_label="测试市", coordinate_source="user_reported", coordinate_precision="unverified_user_coordinates", time_source="user_reported", candidate_range={"start_time": "11:50", "end_time": "12:10"}, )) assert provenance["uncertainty_minutes"] == 20 assert provenance["coordinate_source"] == "user_reported" def test_birth_provenance_uses_declared_window_minutes() -> None: provenance = _birth_provenance_from_args(SimpleNamespace( declared_window_start="11:50", declared_window_end="12:10", coordinate_source="user_reported", )) assert provenance["uncertainty_minutes"] == 20 assert provenance["coordinate_source"] == "user_reported"