diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 3f5f0f82..e91c9e59 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -17014,3 +17014,19 @@ - 相关记录:BUG-1265 - 复发自:无 - 修复版本:本分支待发布 + +## BUG-1266 | 木星相对月亮的增长宫被记成车格局 + +- 状态:resolved +- 首次发现:2026-10-07 +- 最近更新:2026-10-07 +- 影响面:`references/yoga_rules.json` 规则 `jupiter_upachaya_from_moon`;读这条规则名称或类别的瑜伽卡和报告 +- 用户现象:木星落在月亮的第 2、5、8 或 11 宫时被标成车格局,类别是 durbhaga +- 触发条件:用规则表判断木星相对月亮的位置 +- 根因:这条规则的中文名写成「车格局(从月亮)」,类别写成 durbhaga,并挂了 Shakata-2。表达式看的是第 2、5、8、11 宫,还排除了与月亮成 1、4、7、10 的间距。增长宫是从月亮数的第 3、6、10、11 宫,只是几何配置,不是名为 Shakata 的格局。生成器里另一条 `shakata_yoga`(车格局)是不同规则,未改 +- 修复:中文名改为「木星位于月亮增长宫」,英文名不带 Yoga。类别改为 configuration。表达式改为 `(house_of('Jupiter') - house_of('Moon')) % 12 + 1` 落在 3、6、10、11。解释只陈述几何关系。卡片把未知类别收成 other,标签不再把这条叫成格局 +- 验证:`tests/test_yoga_upachaya_configuration.py`;`tests/test_yoga_rules_integrity.py`;`tests/test_report_english_dictionary.py` +- 防复发:上述测试锁住名称、类别和四宫 +- 相关记录:无 +- 复发自:无 +- 修复版本:本分支待发布 diff --git a/references/yoga_rules.json b/references/yoga_rules.json index 61dbaafb..e0bd3b82 100644 --- a/references/yoga_rules.json +++ b/references/yoga_rules.json @@ -3741,26 +3741,23 @@ { "id": "jupiter_upachaya_from_moon", "name": "Jupiter in Upachaya from Moon", - "name_cn": "车格局(从月亮)", - "category": "durbhaga", - "source": "BPHS", - "bvr_id": "Shakata-2", + "name_cn": "木星位于月亮增长宫", + "category": "configuration", + "source": "Moon-relative Upachaya geometry (houses 3, 6, 10, 11); not a named yoga", "logic": { "type": "and", "conditions": [ { "type": "custom", - "expr": "'Jupiter' in planets and 'Moon' in planets and house_of('Jupiter') in [2,5,8,11] and abs(house_of('Jupiter') - house_of('Moon')) not in [0,3,6,9]" + "expr": "'Jupiter' in planets and 'Moon' in planets and (house_of('Jupiter') - house_of('Moon')) % 12 + 1 in [3,6,10,11]" } ] }, "effects": [ - "财富波动", - "精神压力" + "木星相对月亮位于第3、6、10或11宫;只记录几何关系" ], "effects_en": [ - "Fluctuating wealth", - "Mental stress" + "Jupiter occupies house 3, 6, 10, or 11 counted from the Moon; geometry only" ], "strength": "弱", "strength_en": "weak", diff --git a/tests/test_yoga_upachaya_configuration.py b/tests/test_yoga_upachaya_configuration.py new file mode 100644 index 00000000..fc4cbcce --- /dev/null +++ b/tests/test_yoga_upachaya_configuration.py @@ -0,0 +1,47 @@ +"""Jupiter in the Moon's upachaya houses is a configuration, not Shakata (BUG-1266).""" + +from __future__ import annotations + +import json +from pathlib import Path + +from scripts.yoga_engine import YogaEngine + +ROOT = Path(__file__).resolve().parents[1] +RULES = ROOT / "references" / "yoga_rules.json" + + +def _rule() -> dict: + rules = json.loads(RULES.read_text(encoding="utf-8"))["rules"] + return next(rule for rule in rules if rule["id"] == "jupiter_upachaya_from_moon") + + +def _hits(moon_house: int, jupiter_house: int) -> list[dict]: + planets = { + "Moon": {"sign": "Aries", "house": moon_house, "degree": 10.0}, + "Jupiter": {"sign": "Leo", "house": jupiter_house, "degree": 10.0}, + } + return [row for row in YogaEngine(str(RULES)).detect(planets, "Aries") if row.get("rule_id") == "jupiter_upachaya_from_moon"] + + +def test_rule_names_the_geometry_and_not_shakata() -> None: + rule = _rule() + assert rule["name_cn"] == "木星位于月亮增长宫" + assert rule["category"] == "configuration" + assert "bvr_id" not in rule + assert "Shakata" not in json.dumps(rule, ensure_ascii=False) + assert "瑜伽" not in rule["name_cn"] and "Yoga" not in rule["name"] + assert "3,6,10,11" in rule["logic"]["conditions"][0]["expr"] + + +def test_relative_houses_3_6_10_11_match_and_5_does_not() -> None: + # Moon in house 1. House 3 is the 3rd from the Moon. House 5 is not an upachaya. + assert _hits(1, 3) + assert _hits(1, 6) + assert _hits(1, 10) + assert _hits(1, 11) + assert _hits(1, 5) == [] + hit = _hits(1, 3)[0] + assert hit["category"] == "configuration" + assert hit["name_cn"] == "木星位于月亮增长宫" + assert hit["bvr_id"] is None