Files
Jyotisha/scripts/mandooka_dasha.py
T
ClaudeandClaude Opus 5.5 ac9be6f88c feat(techniques): port the astrologer upstream skill's missing techniques
Port from yinduzhanxing 5fb8379c (MIT): Naisargika, Kaala, Karaka, Tara,
Lagnamsaka, Yogardha, Mandooka, Paryaaya and Padanadhamsa dashas;
Sarvatobhadra, Kota and Kalanala chakras; Nakshatra Latta; Pachakadi;
Raman Amsayu and Pindayu. Producers and their upstream tests are copied;
scripts/upstream_technique_layers.py feeds them our natal and transit
positions and attaches chart.consultation_native_layers.upstream_techniques.

- dasha_registry: kaala and padanadhamsa keys (35 -> 37); the nine ported
  dashas are served by compute_dasha or fail closed with upstream's reason.
- technique_registry.json: 16 partial entries; README badges follow.
- Evidence lookup section `upstream_techniques` in the consultation tool.
- Boundaries: Kalanala carries no PyJHora (AGPL) grid coordinates;
  Padanadhamsa/Lagnamsaka run on our Narayana engine (no Rath Table 12,
  PVR co-lord variants or second cycle). PyJHora observers and the Amsayu
  worked-example scaffold live in scripts/research (root .py budget).
- PyJHora black-box cross-checks: Naisargika (lords/years) and Kaala
  (seed segment and fraction within 5e-4) on a public chart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-07 14:44:37 +08:00

21 lines
1.2 KiB
Python

"""Mandooka (Manduka) frog-leap Rashi Dasha."""
from typing import Dict, Mapping
def calculate_mandooka_dasha(start_sign_idx: int, *, sequence=None, durations: Mapping[int, float] | None = None) -> Dict[str, object]:
if not 0 <= int(start_sign_idx) < 12:
raise ValueError("start_sign_idx must be in [0, 11]")
if sequence is None:
return {"system": "mandooka_dasha", "status": "blocked", "blockers": ["sequence_profile_required"], "seed_sign_index": int(start_sign_idx)}
periods = [int(s) % 12 for s in sequence]
if len(periods) != 12 or len(set(periods)) != 12:
raise ValueError("frog-leap sequence must cover all twelve signs")
if durations is None:
durations = {s: (7 if s in {0, 2, 5, 6, 8, 11} else 8 if s in {1, 4, 7, 10} else 9) for s in range(12)}
missing = [s for s in periods if s not in durations]
if missing:
raise ValueError(f"missing durations: {missing}")
return {"system": "mandooka_dasha", "status": "executed", "seed_sign_index": int(start_sign_idx),
"periods": [{"sign_index": s, "years": float(durations[s])} for s in periods],
"claim_boundary": "Start-sign convention and duration profile remain explicit."}