From 8f56ad632b4a6e5ef0c18a4586fe323f43b73ad8 Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Fri, 26 Jun 2026 21:49:15 +0800 Subject: [PATCH] feat(skill): add navamsa and drekkana sensitivity markers --- README.md | 8 +++--- references/technique_registry.json | 42 ++++++++++++++++++++++++++++++ scripts/varga.py | 36 +++++++++++++++++++++++++ tests/test_varga_bphs.py | 26 +++++++++++++++++- 4 files changed, 107 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 09c66cb8..17157b4d 100644 --- a/README.md +++ b/README.md @@ -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 | ✅ | ✅ | ✅ | diff --git a/references/technique_registry.json b/references/technique_registry.json index 92b44e7d..550b38ad 100644 --- a/references/technique_registry.json +++ b/references/technique_registry.json @@ -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": [ diff --git a/scripts/varga.py b/scripts/varga.py index a2f1531e..a86e393a 100644 --- a/scripts/varga.py +++ b/scripts/varga.py @@ -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' diff --git a/tests/test_varga_bphs.py b/tests/test_varga_bphs.py index eac0811f..25f81bd8 100644 --- a/tests/test_varga_bphs.py +++ b/tests/test_varga_bphs.py @@ -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