feat(skill): add navamsa and drekkana sensitivity markers

This commit is contained in:
732642856
2026-06-26 21:49:15 +08:00
parent 235c44bcd1
commit 8f56ad632b
4 changed files with 107 additions and 5 deletions
+4 -4
View File
@@ -4,8 +4,8 @@
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue)](https://www.python.org/)
[![Techniques](https://img.shields.io/badge/techniques-75-blueviolet)](references/technique_registry.json)
[![Covered](https://img.shields.io/badge/covered-66-green)](references/technique_registry.json)
[![Techniques](https://img.shields.io/badge/techniques-77-blueviolet)](references/technique_registry.json)
[![Covered](https://img.shields.io/badge/covered-68-green)](references/technique_registry.json)
[![Complete](https://img.shields.io/badge/complete-9-brightgreen)](references/technique_registry.json)
[![Partial](https://img.shields.io/badge/partial-0-lightgrey)](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** 75 registered techniques (Dashas, Yogas, Shadbala, Ashtakavarga, Transits...)
2. **Runs** 77 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 | ✅ | ❌ | ❌ | ❌ |
| 75 techniques registered | ✅ | ✅ (50+) | ✅ (200+) | ✅ |
| 77 techniques registered | ✅ | ✅ (50+) | ✅ (200+) | ✅ |
| Traditional algorithm benchmarked | ✅ mixed depth | ✅ | ✅ | ✅ |
| Docker / MCP Server | ✅ | ❌ | ✅ | ❌ |
| English docs / PyPI package | ✅ in progress | ✅ | ✅ | ✅ |
+42
View File
@@ -512,6 +512,48 @@
"audit_label": "Pushkara",
"missing_impact": "D9 grace/support layer may be undercounted."
},
"navamsa_64th": {
"name": "64th Navamsa / Chatushashti Navamsa",
"domains": [
"varga",
"nakshatra",
"crisis",
"timing"
],
"status": "covered",
"knowledge_refs": [
"references/navamsa-d9-interpretation-template.md"
],
"commands": [
"scripts/varga.py"
],
"output_paths": [
"scripts.varga.calc_64th_navamsa"
],
"audit_label": "64th Navamsa",
"missing_impact": "A classical stress-sensitive Navamsa trigger is unavailable, weakening vulnerability and event-pressure analysis."
},
"drekkana_22nd": {
"name": "22nd Drekkana",
"domains": [
"varga",
"d30",
"crisis",
"timing"
],
"status": "covered",
"knowledge_refs": [
"references/varga-system-quick-reference.md"
],
"commands": [
"scripts/varga.py"
],
"output_paths": [
"scripts.varga.calc_22nd_drekkana"
],
"audit_label": "22nd Drekkana",
"missing_impact": "A classical danger-sensitive Drekkana trigger is absent, weakening accident and adversity screening."
},
"bhava_chalit": {
"name": "Bhava Chalit",
"domains": [
+36
View File
@@ -90,6 +90,42 @@ def calc_varga(lon, div):
if div==9: r['pada']=pi+1
return r
def calc_64th_navamsa(moon_lon: float) -> Dict:
"""Compute the 64th Navamsa from the Moon's Navamsa position.
Traditional counting is inclusive, so the 64th point is +63 signs from the
Moon's Navamsa anchor.
"""
base = calc_varga(moon_lon, 9)
sign_idx = (base['sign_idx'] + 63) % 12
return {
'base_navamsa_sign_idx': base['sign_idx'],
'base_navamsa_sign': base['sign'],
'offset_from_moon_navamsa': 64,
'sign_idx': sign_idx,
'sign': _sn(sign_idx),
'lord': SIGN_LORDS.get(_sn(sign_idx), ''),
}
def calc_22nd_drekkana(lagna_lon: float) -> Dict:
"""Compute the 22nd Drekkana from the Lagna's Drekkana position.
Traditional counting is inclusive, so the 22nd point is +21 signs from the
Lagna Drekkana anchor.
"""
base = calc_varga(lagna_lon, 3)
sign_idx = (base['sign_idx'] + 21) % 12
return {
'base_drekkana_sign_idx': base['sign_idx'],
'base_drekkana_sign': base['sign'],
'offset_from_lagna_drekkana': 22,
'sign_idx': sign_idx,
'sign': _sn(sign_idx),
'lord': SIGN_LORDS.get(_sn(sign_idx), ''),
}
def dignity(planet, sign_idx):
if planet in EXALT_SIGN and sign_idx==EXALT_SIGN[planet]: return 'Exalted'
if planet in DEBIL_SIGN and sign_idx==DEBIL_SIGN[planet]: return 'Debilitated'
+25 -1
View File
@@ -5,7 +5,13 @@ from __future__ import annotations
from hypothesis import given
from hypothesis import strategies as st
from varga import SIGNS, calc_varga, varga_map
from varga import (
SIGNS,
calc_22nd_drekkana,
calc_64th_navamsa,
calc_varga,
varga_map,
)
def navamsa_ref(lon: float) -> int:
@@ -82,3 +88,21 @@ def test_navamsa_matches_user_jhora_pdf_reference_chart() -> None:
}
for longitude, expected_sign in expected.items():
assert calc_varga(longitude, 9)["sign"] == expected_sign
def test_64th_navamsa_counts_forward_from_moon_navamsa() -> None:
moon_lon = 42.3
result = calc_64th_navamsa(moon_lon)
expected_sign_idx = (navamsa_ref(moon_lon) + 63) % 12
assert result["sign_idx"] == expected_sign_idx
assert result["sign"] == SIGNS[expected_sign_idx]
assert result["offset_from_moon_navamsa"] == 64
def test_22nd_drekkana_counts_forward_from_lagna_drekkana() -> None:
asc_lon = 25.5
result = calc_22nd_drekkana(asc_lon)
expected_sign_idx = (drekkana_ref(asc_lon) + 21) % 12
assert result["sign_idx"] == expected_sign_idx
assert result["sign"] == SIGNS[expected_sign_idx]
assert result["offset_from_lagna_drekkana"] == 22