婚恋评级改成证据档位,配偶星分数不再写成百分制(BUG-1318,上游 f891a2c1)
五档不再写稳定、离婚、再婚或婚前咨询,并写明这是结构指数。公开盘中英文各锁一条。配偶星证据行改成 0 到 1,不乘 100。pytest tests/test_d9_evidence_bands.py 3 通过。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
co-authored by
Grok (agent loop)
parent
99ef1bbd12
commit
d32ad7b7b1
@@ -17720,3 +17720,18 @@
|
||||
- 复发自:BUG-1306。
|
||||
- 修复版本:分支 `codex/rectification-step0-entry-20261013`,尚未合入 staging。
|
||||
|
||||
## BUG-1318 | 婚恋评级仍写成稳定或婚前咨询,配偶星分数被写成百分制
|
||||
|
||||
- 状态:fixed-pending-verify
|
||||
- 首次发现 / 最近更新:2026-10-14 / 2026-10-14
|
||||
- 来源:issue #56。上游 `f891a2c1`。任务书 `docs/tasks/TASK-upstream-sync7-20261014.md` T1。
|
||||
- 现象:D9 综合评级仍写「婚姻稳定」「强烈建议婚前咨询」。这份文字进全读导出包,模型能读到。配偶星证据行把 0 到 1 的指数写成「婚姻质量 x/100」。
|
||||
- 触发条件:算出婚恋几何指数,或关系时机证据带出配偶星。
|
||||
- 根因:同步第六轮按标题筛提交时,漏了 10-02 到 10-03 的这条措辞修正。分数行把 0 到 1 当成了百分制。
|
||||
- 修复:五档改成证据档位,并写明这是结构指数,不预测婚姻次数、稳定、离婚、伴侣好坏,也不提示婚前咨询。中文报告用中文档位,英文报告用英文档位。证据行改成「婚姻质量指数 x(0到1)」,不乘 100。
|
||||
- 验证:`tests/test_d9_evidence_bands.py` 3 通过。公开盘中英文各一条快照。配偶星行不再出现 `/100`。
|
||||
- 防复发:五档文字不得含「稳定、离婚、再婚、婚前咨询、几段」;快照锁住公开盘的两句。
|
||||
- 相关记录:BUG-1183。
|
||||
- 复发自:无。
|
||||
- 修复版本:分支 `codex/upstream-sync7-20261014`,尚未合入 staging。
|
||||
|
||||
|
||||
@@ -7551,7 +7551,7 @@ class JyotishAPIHandler(BaseHTTPRequestHandler, VedastroEvidenceMixin, SynastryM
|
||||
evidence.append({
|
||||
'label': 'Darakaraka (DK)',
|
||||
'value': f"{dk_planet} · H{darakaraka.get('dk_house', '-')}",
|
||||
'note': f"{darakaraka.get('core_profile') or '配偶象征星'};婚姻质量 {darakaraka.get('marriage_quality_score', '-')}/100",
|
||||
'note': f"{darakaraka.get('core_profile') or '配偶象征星'};婚姻质量指数 {darakaraka.get('marriage_quality_score', '-')}(0到1)",
|
||||
})
|
||||
except Exception as exc:
|
||||
darakaraka = {'error': str(exc), 'dk_planet': dk_planet}
|
||||
|
||||
@@ -21,6 +21,23 @@ from typing import Dict, Optional, List
|
||||
SIGN_CN = ['白羊座','金牛座','双子座','巨蟹座','狮子座','处女座',
|
||||
'天秤座','天蝎座','射手座','摩羯座','水瓶座','双鱼座']
|
||||
|
||||
# D9 结构证据档位(BUG-1318)。中文给报告正文,英文键与英文短句给英文版。
|
||||
# 不写婚姻稳定、离婚、再婚、段数或婚前咨询。
|
||||
D9_CLAIM_BOUNDARY = (
|
||||
'D9 结构证据指数,不预测婚姻次数、稳定、离婚、伴侣好坏,也不提示需要婚前咨询'
|
||||
)
|
||||
D9_CLAIM_BOUNDARY_EN = (
|
||||
'D9 structural evidence index. It does not predict marriage count, stability, '
|
||||
'divorce, or partner quality, and it does not suggest premarital counseling.'
|
||||
)
|
||||
D9_EVIDENCE_BANDS = (
|
||||
('supportive_evidence_stronger', '支持证据较强', 'Stronger supportive evidence'),
|
||||
('supportive_evidence_mixed_positive', '支持证据偏正', 'Mixed supportive evidence'),
|
||||
('mixed_evidence', '证据混杂', 'Mixed evidence'),
|
||||
('pressure_evidence_mixed', '压力证据偏杂', 'Mixed pressure evidence'),
|
||||
('pressure_evidence_stronger', '压力证据较强', 'Stronger pressure evidence'),
|
||||
)
|
||||
|
||||
|
||||
def sign_of(lon: float) -> int:
|
||||
"""从黄道经度计算星座序号 (0-11)"""
|
||||
@@ -348,25 +365,42 @@ def _assess_d9_marriage_quality(
|
||||
quality_points -= 1
|
||||
factors.append("D9 Ketu在7宫 → 关系中的分离倾向")
|
||||
|
||||
# 综合评级
|
||||
# 证据档位,不是婚姻结局(BUG-1318,上游 f891a2c1)。
|
||||
if quality_points >= 4:
|
||||
rating = "高(关系质量好,伴侣支持强,婚姻稳定)"
|
||||
band = D9_EVIDENCE_BANDS[0]
|
||||
elif quality_points >= 1:
|
||||
rating = "中上(关系质量尚可,需经营但基础好)"
|
||||
band = D9_EVIDENCE_BANDS[1]
|
||||
elif quality_points >= 0:
|
||||
rating = "中(关系质量一般,需用心经营)"
|
||||
band = D9_EVIDENCE_BANDS[2]
|
||||
elif quality_points >= -2:
|
||||
rating = "中下(关系有挑战,需提前沟通和调整期望)"
|
||||
band = D9_EVIDENCE_BANDS[3]
|
||||
else:
|
||||
rating = "低(关系质量有重大挑战,强烈建议婚前咨询)"
|
||||
band = D9_EVIDENCE_BANDS[4]
|
||||
|
||||
return {
|
||||
'quality_rating': rating,
|
||||
'quality_band': band[0],
|
||||
'quality_rating': band[1],
|
||||
'quality_rating_en': band[2],
|
||||
'quality_points': quality_points,
|
||||
'factors': factors,
|
||||
'claim_boundary': D9_CLAIM_BOUNDARY,
|
||||
'claim_boundary_en': D9_CLAIM_BOUNDARY_EN,
|
||||
}
|
||||
|
||||
|
||||
def render_d9_evidence_report(quality: Dict, language: str = 'zh') -> str:
|
||||
"""中文报告用证据档位短句;英文版用英文短句。两边都带同一条边界。"""
|
||||
if not isinstance(quality, dict):
|
||||
quality = {}
|
||||
if language == 'en':
|
||||
band = quality.get('quality_rating_en') or quality.get('quality_band') or ''
|
||||
boundary = quality.get('claim_boundary_en') or D9_CLAIM_BOUNDARY_EN
|
||||
return f"D9 evidence band: {band}\n{boundary}"
|
||||
band = quality.get('quality_rating') or ''
|
||||
boundary = quality.get('claim_boundary') or D9_CLAIM_BOUNDARY
|
||||
return f"D9 证据档位:{band}\n{boundary}"
|
||||
|
||||
|
||||
def _marriage_recommendations(base: Dict, d9_quality: Dict) -> List[str]:
|
||||
"""几何指数与伴侣数量、事件断语分开(BUG-1183);不随指数大小给不同结论。"""
|
||||
return [
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
"""BUG-1318: D9 marriage rating is an evidence band, not an outcome claim.
|
||||
|
||||
Upstream f891a2c1. The five bands must not say the relationship is stable,
|
||||
ending, repeated, or in need of premarital counseling. The DK evidence line
|
||||
keeps the 0-1 index and does not print a fake /100 score.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = os.path.join(os.path.dirname(__file__), "..")
|
||||
SCRIPTS = os.path.join(ROOT, "scripts")
|
||||
if SCRIPTS not in sys.path:
|
||||
sys.path.insert(0, SCRIPTS)
|
||||
|
||||
from jyotish_engine import compute_chart_data # noqa: E402
|
||||
|
||||
|
||||
def _api_handler():
|
||||
"""Reuse the existing unbound handler helper. Do not add another forgery site."""
|
||||
path = os.path.join(os.path.dirname(__file__), "test_api_server_security.py")
|
||||
spec = importlib.util.spec_from_file_location("_api_security_helpers", path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module._handler()
|
||||
from marriage_counting import ( # noqa: E402
|
||||
D9_CLAIM_BOUNDARY,
|
||||
D9_EVIDENCE_BANDS,
|
||||
_assess_d9_marriage_quality,
|
||||
marriage_counting_full_analysis,
|
||||
render_d9_evidence_report,
|
||||
)
|
||||
from varga import calc_varga # noqa: E402
|
||||
|
||||
BANNED = re.compile(r"稳定|离婚|再婚|婚前咨询|几段")
|
||||
|
||||
|
||||
def _quality(points_chart: dict) -> dict:
|
||||
return _assess_d9_marriage_quality(points_chart, None)
|
||||
|
||||
|
||||
def test_five_bands_have_no_outcome_claims_and_keep_the_boundary() -> None:
|
||||
samples = {
|
||||
"supportive_evidence_stronger": {"Venus": 331.0, "Mars": 271.0, "Jupiter": 91.0},
|
||||
"supportive_evidence_mixed_positive": {"Venus": 31.0},
|
||||
"mixed_evidence": {"Venus": 10.0},
|
||||
"pressure_evidence_mixed": {"Venus": 151.0},
|
||||
"pressure_evidence_stronger": {"Venus": 151.0, "Mars": 91.0, "Jupiter": 271.0},
|
||||
}
|
||||
seen = []
|
||||
for key, chart in samples.items():
|
||||
quality = _quality(chart)
|
||||
assert quality["quality_band"] == key
|
||||
assert quality["claim_boundary"] == D9_CLAIM_BOUNDARY
|
||||
assert quality["claim_boundary_en"]
|
||||
assert not BANNED.search(quality["quality_rating"])
|
||||
assert not BANNED.search(quality["quality_rating_en"])
|
||||
seen.append(quality["quality_band"])
|
||||
assert seen == [band[0] for band in D9_EVIDENCE_BANDS]
|
||||
|
||||
|
||||
def test_public_chart_report_snapshots_in_both_languages() -> None:
|
||||
cases = json.loads(
|
||||
Path(ROOT, "references/real_case_calibration/minute_rectification_development_v1.json").read_text(encoding="utf-8")
|
||||
)["cases"]
|
||||
birth = next(case for case in cases if case["case_id"] == "steve_jobs_1955_development")["birth"]
|
||||
assert birth["source"]["rodden_rating"] == "AA"
|
||||
year, month, day = (int(part) for part in birth["date"].split("-"))
|
||||
hour, minute = (int(part) for part in birth["time"].split(":"))
|
||||
chart, *_ = compute_chart_data(
|
||||
year, month, day, hour, minute,
|
||||
birth["latitude"], birth["longitude"], birth["timezone_offset"],
|
||||
ayanamsa_name="raman",
|
||||
)
|
||||
longitudes = {name: row["degree_raw"] for name, row in chart["planets"].items()}
|
||||
d9 = {}
|
||||
for name, lon in longitudes.items():
|
||||
divisional = calc_varga(lon, 9)
|
||||
d9[name] = divisional["sign_idx"] * 30 + divisional["degree_in_sign"]
|
||||
result = marriage_counting_full_analysis(chart["houses"]["house_7"]["lord"], longitudes, d9)
|
||||
quality = result["d9_marriage_quality"]
|
||||
assert quality["quality_band"] == "mixed_evidence"
|
||||
assert quality["quality_points"] == 0
|
||||
chinese = render_d9_evidence_report(quality, "zh")
|
||||
english = render_d9_evidence_report(quality, "en")
|
||||
assert chinese == (
|
||||
"D9 证据档位:证据混杂\n"
|
||||
"D9 结构证据指数,不预测婚姻次数、稳定、离婚、伴侣好坏,也不提示需要婚前咨询"
|
||||
)
|
||||
assert english == (
|
||||
"D9 evidence band: Mixed evidence\n"
|
||||
"D9 structural evidence index. It does not predict marriage count, stability, "
|
||||
"divorce, or partner quality, and it does not suggest premarital counseling."
|
||||
)
|
||||
assert "/100" not in chinese
|
||||
assert "/100" not in english
|
||||
|
||||
|
||||
def test_dk_evidence_line_prints_the_zero_to_one_index() -> None:
|
||||
cases = json.loads(
|
||||
Path(ROOT, "references/real_case_calibration/minute_rectification_development_v1.json").read_text(encoding="utf-8")
|
||||
)["cases"]
|
||||
birth = next(case for case in cases if case["case_id"] == "steve_jobs_1955_development")["birth"]
|
||||
year, month, day = (int(part) for part in birth["date"].split("-"))
|
||||
hour, minute = (int(part) for part in birth["time"].split(":"))
|
||||
chart, asc_idx, *_ = compute_chart_data(
|
||||
year, month, day, hour, minute,
|
||||
birth["latitude"], birth["longitude"], birth["timezone_offset"],
|
||||
ayanamsa_name="raman",
|
||||
)
|
||||
longitudes = {name: row["degree_raw"] for name, row in chart["planets"].items()}
|
||||
handler = _api_handler()
|
||||
evidence = handler._compute_relationship_timing_evidence(
|
||||
{},
|
||||
chart["planets"],
|
||||
longitudes,
|
||||
asc_idx,
|
||||
chart["ascendant"]["sign"],
|
||||
)
|
||||
notes = [row["note"] for row in evidence["evidence"] if row.get("label") == "Darakaraka (DK)"]
|
||||
assert len(notes) == 1
|
||||
assert "/100" not in notes[0]
|
||||
assert "婚姻质量指数" in notes[0]
|
||||
assert "(0到1)" in notes[0]
|
||||
score = evidence["darakaraka"]["marriage_quality_score"]
|
||||
assert isinstance(score, float)
|
||||
assert 0.0 <= score <= 1.0
|
||||
assert str(score) in notes[0]
|
||||
Reference in New Issue
Block a user