feat(product): present consult and rectification in local skill form
Default ayanamsa to Raman with true_pushya support, attach governed Raman packets, restore Path C questionnaires and eight-method verification copy, and keep unique-minute confirmation blocked. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
"""Server-owned P0/P1 refinement packet for birth-time rectification.
|
||||
|
||||
Produces candidate-narrowing structure only. Never grants a unique minute,
|
||||
never emits D9/D10 type labels, and never copies raw scores into public copy.
|
||||
Produces candidate-narrowing structure only. Never grants a unique minute
|
||||
and never copies raw scores into public copy. D9/D10 sign names are method
|
||||
contrast for the skill verification report, not unique-minute proof.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -76,6 +77,18 @@ def _features(built: dict[str, Any]) -> list[dict[str, Any]]:
|
||||
return rows
|
||||
|
||||
|
||||
def _sign_names(indices: set[int]) -> list[str]:
|
||||
names: list[str] = []
|
||||
for idx in sorted(indices):
|
||||
if isinstance(idx, int) and 0 <= idx <= 11:
|
||||
names.append(SIGNS_CN[SIGNS[idx]])
|
||||
return names
|
||||
|
||||
|
||||
def _has_gochara(rule_ids: Sequence[str]) -> bool:
|
||||
return any("controlled_transit" in str(item) or str(item).startswith("gochara") for item in rule_ids)
|
||||
|
||||
|
||||
def match_level(rule_ids: Sequence[str]) -> str:
|
||||
ids = [str(item) for item in rule_ids]
|
||||
if not ids or ids == ["no_domain_activation"]:
|
||||
@@ -92,6 +105,8 @@ def match_level(rule_ids: Sequence[str]) -> str:
|
||||
return "medium"
|
||||
if any(item.startswith("vim_") or item.startswith("narayana_") for item in ids):
|
||||
return "weak"
|
||||
if _has_gochara(ids):
|
||||
return "medium"
|
||||
return "none"
|
||||
|
||||
|
||||
@@ -101,6 +116,8 @@ def _tracks(rule_ids: Sequence[str]) -> list[str]:
|
||||
tracks.append("vimshottari")
|
||||
if any(str(item).startswith("narayana_") for item in rule_ids):
|
||||
tracks.append("narayana")
|
||||
if _has_gochara(rule_ids):
|
||||
tracks.append("gochara")
|
||||
return tracks
|
||||
|
||||
|
||||
@@ -196,6 +213,8 @@ def window_scan(built: dict[str, Any]) -> dict[str, Any]:
|
||||
for layer in _LAYER_LABEL:
|
||||
payload[f"{layer}_lagna_count" if layer.startswith("d") else f"{layer}_count"] = len(counts[layer])
|
||||
payload[f"{layer}_candidates_differ"] = len(counts[layer]) > 1
|
||||
payload["d9_sign_names"] = _sign_names(counts["d9"])
|
||||
payload["d10_sign_names"] = _sign_names(counts["d10"])
|
||||
return payload
|
||||
|
||||
|
||||
@@ -219,18 +238,58 @@ def event_dasha_ledger(
|
||||
summary = str(event.get("summary") or "").strip() or "这条经历"
|
||||
tracks = _tracks(rule_ids)
|
||||
track_text = "、".join(
|
||||
"主限" if track == "vimshottari" else "分盘大运" for track in tracks
|
||||
"主限" if track == "vimshottari" else "分盘大运" if track == "narayana" else "受控行运"
|
||||
for track in tracks
|
||||
) or "现有大运层"
|
||||
gochara_hit = _has_gochara(rule_ids)
|
||||
rows.append({
|
||||
"summary": summary[:80],
|
||||
"match": level,
|
||||
"match_label": MATCH_LABELS[level],
|
||||
"tracks": tracks,
|
||||
"user_meaning": f"{summary[:40]}:{MATCH_LABELS[level]}({track_text})",
|
||||
"gochara": "activated" if gochara_hit else "not_seen",
|
||||
"user_meaning": (
|
||||
f"{summary[:40]}:{MATCH_LABELS[level]}({track_text}"
|
||||
f"{';Gochara 激活相关宫' if gochara_hit else ';Gochara 未见对应'})"
|
||||
),
|
||||
})
|
||||
return rows
|
||||
|
||||
|
||||
def event_fit_rate(rows: Sequence[dict[str, Any]]) -> dict[str, Any]:
|
||||
total = len(rows)
|
||||
matched = sum(1 for row in rows if row.get("match") in {"strong", "medium"})
|
||||
if total == 0:
|
||||
return {
|
||||
"matched": 0,
|
||||
"total": 0,
|
||||
"percent": None,
|
||||
"band": "insufficient",
|
||||
"label": "事件不足,无法计算吻合率",
|
||||
"unique_minute_claim": False,
|
||||
"user_meaning": "事件–Dasha–Gochara 表还没有可评分行。这不是唯一分钟确认。",
|
||||
}
|
||||
percent = round(100 * matched / total)
|
||||
band = "high" if percent >= 80 else "medium" if percent >= 60 else "low"
|
||||
label = (
|
||||
"高度吻合(事件吻合率 ≥80%)" if band == "high"
|
||||
else "中度吻合(事件吻合率 60–80%)" if band == "medium"
|
||||
else "低度吻合(事件吻合率 <60%)"
|
||||
)
|
||||
return {
|
||||
"matched": matched,
|
||||
"total": total,
|
||||
"percent": percent,
|
||||
"band": band,
|
||||
"label": label,
|
||||
"unique_minute_claim": False,
|
||||
"user_meaning": (
|
||||
f"当前窗 {matched}/{total} 件已确认事件与 Dasha/Gochara 吻合,{label}。"
|
||||
"这是相对拟合,不是已确认唯一出生分钟。"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def dasha_agreement(built: dict[str, Any], candidate_times: Sequence[str]) -> dict[str, Any]:
|
||||
times = [str(item)[:5] for item in candidate_times if isinstance(item, str) and len(str(item)) >= 5]
|
||||
if not times:
|
||||
@@ -324,7 +383,7 @@ def lagna_contrast(built: dict[str, Any]) -> dict[str, Any] | None:
|
||||
"user_meaning": (
|
||||
f"窗口里出现两段本命上升:{left['start']}-{left['end']} 为{left['lagna']},"
|
||||
f"{right['start']}-{right['end']} 为{right['lagna']}。"
|
||||
"只比较宫主结构,不给性格或类型标签。"
|
||||
"可并列 D9/D10 类型表作校时方法,不是命运承诺,也不能确认唯一分钟。"
|
||||
),
|
||||
"unique_minute_claim": False,
|
||||
}
|
||||
@@ -399,7 +458,7 @@ def precision_stage(scan: dict[str, Any], event_count: int) -> dict[str, Any]:
|
||||
meaning = "事业盘已较稳,居所盘仍会换升。可再补一件记得时间的搬家或住处变化。"
|
||||
elif scan.get("d5_candidates_differ") or scan.get("d24_candidates_differ"):
|
||||
current = "d5_refine"
|
||||
meaning = "居所盘已较稳,成就盘或学业盘仍会换升。可再补一件记得时间的学业、考试或被委以责任的变化;不要贴类型标签。"
|
||||
meaning = "居所盘已较稳,成就盘或学业盘仍会换升。可再补一件记得时间的学业、考试或被委以责任的变化。"
|
||||
else:
|
||||
current = "ready_to_adopt"
|
||||
meaning = "核心分盘已不再换升。可以采用代表性时间看盘,也可以再补主题经历。"
|
||||
@@ -441,10 +500,12 @@ def build_refinement_packet(
|
||||
candidate_times: Sequence[str],
|
||||
) -> dict[str, Any]:
|
||||
scan = window_scan(built)
|
||||
ledger = event_dasha_ledger(request, built, representative_time)
|
||||
agreement = dasha_agreement(built, candidate_times)
|
||||
return {
|
||||
"window_scan": scan,
|
||||
"event_dasha_ledger": event_dasha_ledger(request, built, representative_time),
|
||||
"event_dasha_ledger": ledger,
|
||||
"event_fit_rate": event_fit_rate(ledger),
|
||||
"dasha_agreement": agreement,
|
||||
"lagna_contrast": lagna_contrast(built),
|
||||
"nakshatra_boundary": nakshatra_boundary(built, representative_time),
|
||||
|
||||
Reference in New Issue
Block a user