feat(narayana): label the product Narayana as the legacy algorithm (T4, BUG-1215)

Round-4 ruling Q4 / product decision A: scoring and the consultation and
report time axes keep the old Narayana (from the Lagna, always zodiacal) until
the Rath trial is decided; every user-visible Narayana now says so.
narayana_legacy_label adds profile=legacy_reference_only and the note (zh/en)
at the consumers (consultation modules, full reading Step 4.13, CLI), not in
the frozen narayana_dasha.py (ERR-110/115). The card's timing.narayana carries
'algorithm'; the projection allowlist passes algorithm_note; the reference
report's Narayana section and the dasha-family table show '算法:…' (English
twin in the phrase table). The unused narayana-dasha --variant-profile flag,
the one place offering a Chara Dasha author's profile for Narayana, is removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-10-03 16:42:15 +08:00
co-authored by Claude Opus 5.5
parent 7cb332bce6
commit 9eb22f6363
9 changed files with 119 additions and 7 deletions
+3
View File
@@ -56,6 +56,8 @@ def cmd_narayana_dasha(args, chart_data):
current_age=current_age,
birth_year=birth_year,
)
from narayana_legacy_label import label_legacy_narayana # BUG-1215
label_legacy_narayana(result)
# 格式化输出
lines = [
@@ -65,6 +67,7 @@ def cmd_narayana_dasha(args, chart_data):
"",
f"Lagna: {result['lagna_sign']}({result['lagna_sign_idx']})",
f"总周期: {result['total_cycle_years']} 年",
f"算法: {result['algorithm_note']}",
"",
"── 大运序列 ──",
]
+2 -1
View File
@@ -1622,7 +1622,8 @@ def _attach_local_consultation_layers(handler, chart: dict, birth_payload: dict,
birth_year=int(birth_payload.get('year', 0) or 0),
)
if isinstance(narayana_result, dict):
modules['narayana_dasha'] = narayana_result
# BUG-1215: legacy algorithm, labelled until the Rath profile replaces it.
modules['narayana_dasha'] = _load_local_module('narayana_legacy_label').label_legacy_narayana(narayana_result)
except Exception as exc:
diagnostics.append({'layer': 'narayana_dasha', 'status': 'unavailable', 'reason': exc.__class__.__name__})
+7 -4
View File
@@ -65,6 +65,7 @@ except ModuleNotFoundError: # pragma: no cover - minimal environments
lines.extend(" | ".join(str(item) for item in row) for row in rows)
return "\n".join(lines)
from life_stage_hook import generate_life_stage_hooks
from narayana_legacy_label import LEGACY_NOTE_ZH as LEGACY_NARAYANA_NOTE_ZH # BUG-1215
from capability_evidence_pool import build_capability_evidence_pool_summary
from guided_topic_discovery import build_guided_topics
@@ -9447,6 +9448,8 @@ def render_pl9_markdown(packet: dict) -> str:
f"参考对齐状态:`{_md_cell(narayana_topic.get('reference_alignment_status') or 'not_closed')}`。"
'本地年龄轴与 PL9 日期边界/起运序列的字段级 parity 尚未闭环,因此不替代主时间判断。',
'',
f'- 算法:{LEGACY_NARAYANA_NOTE_ZH}', # BUG-1215
'',
'#### Patyayini 年内节奏支持',
'',
f"Patyayini 当前状态为 `{_md_cell(patyayini_topic.get('status') or 'blocked')}`;"
@@ -16111,7 +16114,8 @@ def cmd_full_reading(args):
current_age=current_age,
birth_year=args.year,
)
report['modules']['narayana_dasha'] = narayana_result
from narayana_legacy_label import label_legacy_narayana # BUG-1215
report['modules']['narayana_dasha'] = label_legacy_narayana(narayana_result)
except Exception as e:
report['errors'].append(f"narayana-dasha: {e}")
@@ -18353,9 +18357,8 @@ def main():
p = sub.add_parser('narayana-dasha', help='Narayana Dasha(Rishi Dasha)星座大运分析')
_add_chart_args(p)
p.add_argument('--age', type=float, default=None, help='当前年龄(用于定位大运位置)')
p.add_argument('--variant-profile', default='legacy_local',
choices=['legacy_local', 'kn_rao', 'goel_lagna_start', 'goel_gendered', 'goel_shastri_method2', 'pyjhora_blackbox'],
help='Narayana/Chara式星座大运profile:legacy保持旧输出;kn_rao/goel映射到显式本地规则;pyjhora_blackbox只输出PyJHora黑盒当前路径')
# BUG-1215: the unused --variant-profile flag is removed (it offered a
# Chara Dasha author's name as a profile of this command).
# 21.7 muhurta (v6.0.21新增)
p = sub.add_parser('muhurta', help='Muhurta 择时分析(Panchanga 五要素)')
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
"""Honest label for the product Narayana Dasha (BUG-1215, round-4 ruling Q4).
`narayana_dasha.narayana_dasha_full_report` (consultation, report, CLI) runs
`calc_narayana_mahadasha`: always from the Lagna, always zodiacal. The
astrologer's ruling is Sanjay Rath's Narayana Dasha (stronger of Lagna / 7th,
order by the start sign); until the product switches (product decision after
the trial), every user-visible Narayana carries this label and the data carry
`profile: legacy_reference_only`. Kept outside `narayana_dasha.py`, which is in
the frozen rectification scoring identity (ERR-110 / ERR-115).
"""
from __future__ import annotations
from typing import Any, Dict
LEGACY_PROFILE = "legacy_reference_only"
LEGACY_NOTE_ZH = "旧算法(从上升起、一律顺行),待替换为 Sanjay Rath 版"
LEGACY_NOTE_EN = "Legacy algorithm (starts from the Lagna, always zodiacal); to be replaced by Sanjay Rath's version"
def label_legacy_narayana(result: Any) -> Any:
"""Add the legacy profile and note to a `narayana_dasha_full_report` result."""
if isinstance(result, dict):
result["profile"] = LEGACY_PROFILE
result["algorithm_note"] = LEGACY_NOTE_ZH
result["algorithm_note_en"] = LEGACY_NOTE_EN
return result
+3
View File
@@ -147,6 +147,9 @@ _PHRASES: dict[str, str] = {
"| 要素总数 |": "| Total elements |",
# ── annual labels and values ──
"Muntha 所在星座的守护星(当前本地口径)": "Ruler of the Muntha sign (current local method)",
# BUG-1215: narayana_legacy_label.LEGACY_NOTE_ZH
"旧算法(从上升起、一律顺行),待替换为 Sanjay Rath 版": "Legacy algorithm (starts from the Lagna, always zodiacal); to be replaced by Sanjay Rath's version",
"- 算法:": "- Algorithm: ",
# BUG-1214: tajika_year_lord.selection_basis_text (zh) → its en twin.
"年盘不全,暂用 Muntha 主星": "Annual chart incomplete; Muntha sign lord used for now",
"(Panchavargiya 为本地近似计算)": " (Panchavargiya is a local approximation)",
+8 -2
View File
@@ -23,6 +23,10 @@ for the public reader rather than exposing empty or machine-key rows.
from __future__ import annotations
try: # scripts/ on sys.path
from narayana_legacy_label import LEGACY_NOTE_ZH
except ImportError: # pragma: no cover - package import
from scripts.narayana_legacy_label import LEGACY_NOTE_ZH
import re
SIGNS: list[str] = []
@@ -1652,9 +1656,11 @@ def render_pl9_parity_markdown(packet: dict) -> str:
periods = _list(family.get('periods'))
if not periods:
continue
lines.extend([f'### p{page} {title_text}', ''])
if 'Narayana' in title_text:
# BUG-1215: the product Narayana is the legacy algorithm.
lines.extend([f'- 算法:{LEGACY_NOTE_ZH}', ''])
lines.extend([
f'### p{page} {title_text}',
'',
'| 序号 | 主星/星座 | 起始 | 结束 | 年数 |',
'|------|-----------|------|------|------|',
])