feat(skill): extend special lagna coverage
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
|
||||
[](LICENSE)
|
||||
[](https://www.python.org/)
|
||||
[](references/technique_registry.json)
|
||||
[](references/technique_registry.json)
|
||||
[](references/technique_registry.json)
|
||||
[](references/technique_registry.json)
|
||||
[](references/technique_registry.json)
|
||||
[](references/technique_registry.json)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
This is a **Vedic (Jyotish) astrology analysis system** designed for deep, auditable full-chart readings. It is NOT a simple ephemeris calculator — it is a multi-stage interpretive pipeline that:
|
||||
|
||||
1. **Computes** divisional charts (D1/D9/D10/...) via Swiss Ephemeris
|
||||
2. **Runs** 74 registered techniques (Dashas, Yogas, Shadbala, Ashtakavarga, Transits...)
|
||||
2. **Runs** 75 registered techniques (Dashas, Yogas, Shadbala, Ashtakavarga, Transits...)
|
||||
3. **Routes** the analysis through strict workflow paths depending on question type (career / relationship / wealth / timing)
|
||||
4. **Audits** every technique used — declaring what was called, what is complete/covered, and which limitations affect confidence
|
||||
5. **Degrades gracefully** — limitations are labeled, not silently over-promising
|
||||
@@ -45,7 +45,7 @@ This is a **Vedic (Jyotish) astrology analysis system** designed for deep, audit
|
||||
| Technique Audit Table (confidence labeling) | ✅ | ❌ | ❌ | ❌ |
|
||||
| Capability degradation (limits are explicit) | ✅ | ❌ | ❌ | ❌ |
|
||||
| MEVG external verification gates | ✅ | ❌ | ❌ | ❌ |
|
||||
| 74 techniques registered | ✅ | ✅ (50+) | ✅ (200+) | ✅ |
|
||||
| 75 techniques registered | ✅ | ✅ (50+) | ✅ (200+) | ✅ |
|
||||
| Traditional algorithm benchmarked | ✅ mixed depth | ✅ | ✅ | ✅ |
|
||||
| Docker / MCP Server | ✅ | ❌ | ✅ | ❌ |
|
||||
| English docs / PyPI package | ✅ in progress | ✅ | ✅ | ✅ |
|
||||
|
||||
@@ -878,6 +878,32 @@
|
||||
"audit_label": "Upapada Lagna",
|
||||
"missing_impact": "Marriage quality analysis incomplete without UL."
|
||||
},
|
||||
"special_lagnas_extended": {
|
||||
"name": "Special Lagnas / HL GL VL PP ViL",
|
||||
"domains": [
|
||||
"lagna",
|
||||
"timing",
|
||||
"wealth",
|
||||
"status"
|
||||
],
|
||||
"status": "covered",
|
||||
"knowledge_refs": [
|
||||
"references/open_source_sources/jaimini-tropical/jaimini/core/lagnas.py"
|
||||
],
|
||||
"commands": [
|
||||
"chart",
|
||||
"full-reading"
|
||||
],
|
||||
"output_paths": [
|
||||
"special_lagnas.HL",
|
||||
"special_lagnas.GL",
|
||||
"special_lagnas.VL",
|
||||
"special_lagnas.PP",
|
||||
"special_lagnas.ViL"
|
||||
],
|
||||
"audit_label": "Special Lagnas",
|
||||
"missing_impact": "Special Lagna timing, status and prosperity sub-angles are thinner without HL/GL/VL/PP/ViL."
|
||||
},
|
||||
"tithi_lord": {
|
||||
"name": "Tithi Lord / 月日守护星",
|
||||
"domains": [
|
||||
|
||||
+23
-3
@@ -779,6 +779,9 @@ def calc_special_lagnas_precise(
|
||||
hl_idx = ghati_floor % 12 if ghati_floor % 2 else (7 - ghati_floor) % 12
|
||||
gl_idx = ghati_floor % 12
|
||||
vl_idx = (asc_sign_idx * 3) % 12
|
||||
vl_from_hl_idx = (hl_idx * 3) % 12
|
||||
pp_idx = (hl_idx + gl_idx) % 12
|
||||
vil_idx = int((ghatis * 2)) % 12
|
||||
|
||||
sunrise_local_hours = (sunrise_utc + tz_offset) % 24
|
||||
sunrise_local_minutes = int(round(sunrise_local_hours * 60)) % (24 * 60)
|
||||
@@ -794,6 +797,8 @@ def calc_special_lagnas_precise(
|
||||
'ghatis_elapsed_from_sunrise': round(ghatis, 4),
|
||||
'HL': _special_lagna_payload('HL', 'Hora Lagna', hl_idx, fraction * 30.0, ghatis, before_sunrise),
|
||||
'GL': _special_lagna_payload('GL', 'Ghati Lagna', gl_idx, fraction * 30.0, ghatis, before_sunrise),
|
||||
'PP': _special_lagna_payload('PP', 'Pranapada Lagna', pp_idx, fraction * 30.0, ghatis, before_sunrise),
|
||||
'ViL': _special_lagna_payload('ViL', 'Vighati Lagna', vil_idx, fraction * 30.0, ghatis, before_sunrise),
|
||||
'VL': {
|
||||
'name': 'VL',
|
||||
'full_name': 'Varnada Lagna',
|
||||
@@ -801,8 +806,13 @@ def calc_special_lagnas_precise(
|
||||
'sign_idx': vl_idx,
|
||||
'lord': SIGN_LORDS[_sign_name(vl_idx)],
|
||||
'method': 'Ascendant sign × 3',
|
||||
'vl_from_hl': {
|
||||
'sign': _sign_name(vl_from_hl_idx),
|
||||
'sign_idx': vl_from_hl_idx,
|
||||
'lord': SIGN_LORDS[_sign_name(vl_from_hl_idx)],
|
||||
},
|
||||
},
|
||||
'note': 'HL/GL以出生地日出为起点计算;GL对24分钟边界敏感,出生时间不准时应结合生时校正。'
|
||||
'note': 'HL/GL/PP/ViL以出生地日出为起点计算;GL与ViL对细分钟边界敏感,出生时间不准时应结合生时校正。'
|
||||
}
|
||||
|
||||
|
||||
@@ -819,12 +829,22 @@ def calc_special_lagnas(asc_sign_idx: int, hour: int, minute: int = 0) -> Dict:
|
||||
hl_idx = ghati_floor % 12 if ghati_floor % 2 else (7 - ghati_floor) % 12
|
||||
gl_idx = ghati_floor % 12
|
||||
vl_idx = (asc_sign_idx * 3) % 12
|
||||
vl_from_hl_idx = (hl_idx * 3) % 12
|
||||
pp_idx = (hl_idx + gl_idx) % 12
|
||||
vil_idx = int(ghatis * 2) % 12
|
||||
return {
|
||||
'method': 'Special Lagnas HL/GL/VL simplified (jaimini-tropical MIT adapted; sunrise-sensitive)',
|
||||
'capability_status': 'auxiliary_partial',
|
||||
'ghatis_elapsed_from_midnight': round(ghatis, 4),
|
||||
'HL': {'sign': _sign_name(hl_idx), 'sign_idx': hl_idx, 'lord': SIGN_LORDS[_sign_name(hl_idx)]},
|
||||
'GL': {'sign': _sign_name(gl_idx), 'sign_idx': gl_idx, 'lord': SIGN_LORDS[_sign_name(gl_idx)]},
|
||||
'VL': {'sign': _sign_name(vl_idx), 'sign_idx': vl_idx, 'lord': SIGN_LORDS[_sign_name(vl_idx)]},
|
||||
'note': 'HL/GL/VL对日出非常敏感;本函数用于结构化补齐,精确版本需接入当地日出。'
|
||||
'PP': {'sign': _sign_name(pp_idx), 'sign_idx': pp_idx, 'lord': SIGN_LORDS[_sign_name(pp_idx)]},
|
||||
'ViL': {'sign': _sign_name(vil_idx), 'sign_idx': vil_idx, 'lord': SIGN_LORDS[_sign_name(vil_idx)]},
|
||||
'VL': {
|
||||
'sign': _sign_name(vl_idx),
|
||||
'sign_idx': vl_idx,
|
||||
'lord': SIGN_LORDS[_sign_name(vl_idx)],
|
||||
'vl_from_hl': {'sign': _sign_name(vl_from_hl_idx), 'sign_idx': vl_from_hl_idx, 'lord': SIGN_LORDS[_sign_name(vl_from_hl_idx)]},
|
||||
},
|
||||
'note': 'HL/GL/VL/PP/ViL对日出非常敏感;本函数用于结构化补齐,精确版本需接入当地日出。'
|
||||
}
|
||||
|
||||
+17
-1
@@ -150,6 +150,8 @@ class TestSpecialLagnas:
|
||||
assert 'HL' in result
|
||||
assert 'GL' in result
|
||||
assert 'VL' in result
|
||||
assert 'PP' in result
|
||||
assert 'ViL' in result
|
||||
|
||||
def test_ghatis_calculated(self):
|
||||
result = calc_special_lagnas(0, 10, 30)
|
||||
@@ -177,10 +179,24 @@ class TestSpecialLagnas:
|
||||
assert result['precision'] == 'sunrise_correct'
|
||||
assert 'sunrise_local_time' in result
|
||||
assert result['ghatis_elapsed_from_sunrise'] > 0
|
||||
for key in ['HL', 'GL', 'VL']:
|
||||
for key in ['HL', 'GL', 'VL', 'PP', 'ViL']:
|
||||
assert result[key]['sign'] in SIGNS
|
||||
assert result[key]['lord'] in SIGN_LORDS.values()
|
||||
|
||||
def test_precise_special_lagnas_include_varnada_crosscheck(self):
|
||||
result = calc_special_lagnas_precise(
|
||||
4, REDACTED_YEAR, 4, 17, 14, 45, lat=36.466667, lon=114.2, tz_offset=8
|
||||
)
|
||||
assert result['VL']['sign_idx'] == (4 * 3) % 12
|
||||
assert 'vl_from_hl' in result['VL']
|
||||
|
||||
def test_precise_special_lagnas_expose_named_extended_payloads(self):
|
||||
result = calc_special_lagnas_precise(
|
||||
0, 1990, 6, 15, 10, 30, lat=28.6, lon=77.2, tz_offset=5.5
|
||||
)
|
||||
assert result['PP']['full_name'] == 'Pranapada Lagna'
|
||||
assert result['ViL']['full_name'] == 'Vighati Lagna'
|
||||
|
||||
def test_precise_special_lagnas_are_time_sensitive(self):
|
||||
morning = calc_special_lagnas_precise(
|
||||
0, 1990, 6, 15, 10, 0, lat=28.6, lon=77.2, tz_offset=5.5
|
||||
|
||||
Reference in New Issue
Block a user