Subsystem: moira/jaimini.py
Computational Domain: Jaimini Chara Karakas
Constitutional Phase: 11 — Architecture Freeze and Validation Codex
Status: Constitutional
A Chara Karaka (Sanskrit: variable significator) is a Jaimini technique in which the seven classical planets (and optionally Rahu) are ranked by the degree each planet occupies within its sidereal sign. The planet holding the highest degree is assigned the Atmakaraka role (soul significator). Successive planets take successive roles down to the Darakaraka (spouse significator).
The authoritative engine is jaimini_karakas(sidereal_longitudes, scheme). It accepts
a dict of planet name → sidereal longitude and an optional JaiminiPolicy, and returns
a JaiminiKarakaResult containing the full ranked assignment.
The karaka pool:
| Scheme | Planets |
|---|---|
| 7-karaka | Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn |
| 8-karaka | Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn, Rahu |
Ketu is never included in either scheme.
Karaka roles — 7-karaka scheme (KARAKA_NAMES_7):
| Rank | Role | Abbreviation | Signification |
|---|---|---|---|
| 1 | Atmakaraka | AK | Soul |
| 2 | Amatyakaraka | AmK | Career / minister |
| 3 | Bhratrikaraka | BK | Siblings |
| 4 | Matrikaraka | MaK | Mother |
| 5 | Pitrikaraka | PiK | Father |
| 6 | Gnatikaraka | GK | Community / disputes |
| 7 | Darakaraka | DK | Spouse |
Karaka roles — 8-karaka scheme (KARAKA_NAMES_8):
Ranks 1–5 are identical to the 7-karaka scheme. Then:
| Rank | Role | Abbreviation | Signification |
|---|---|---|---|
| 6 | Putrakaraka | PuK | Children |
| 7 | Gnatikaraka | GK | Community / disputes |
| 8 | Darakaraka | DK | Spouse |
Effective degree:
Each planet’s sort key is its degree within its sidereal sign, computed as
sidereal_longitude % 30. Rahu is an exception: because Rahu moves retrograde, its
effective degree is inverted: 30 − (sidereal_longitude % 30). This inversion is
stored in KarakaAssignment.is_rahu_inverted.
Tiebreaker:
When two planets occupy exactly the same effective degree, the tie is flagged in
JaiminiKarakaResult.tie_warnings as a (planet_A, planet_B) pair. A deterministic
tiebreaker is applied (pool-index ordering) so the output is always a complete ranked
sequence. The result is indeterminate in the astronomical sense; the tie_warnings
flag preserves that fact.
Planet types (KarakaPlanetType):
| Value | Planets |
|---|---|
LUMINARY |
Sun, Moon |
INNER |
Mercury, Venus, Mars |
OUTER |
Jupiter, Saturn |
NODE |
Rahu (8-scheme only) |
Planet type is a structural classification based on astronomical category. It is not a dignity or condition assessment.
The Jaimini subsystem is organized into ten layers, each building on the prior according to the constitutional dependency graph.
| Layer | Phase | Vessel / Function |
|---|---|---|
| 0 | Core | jaimini_karakas() |
| 1 | Truth Preservation | KarakaAssignment, JaiminiKarakaResult |
| 2 | Classification | KarakaRole, KarakaPlanetType |
| 3 | Inspectability | by_planet(), by_karaka(), darakaraka, has_ties |
| 4 | Policy | JaiminiPolicy, scheme parameter |
| 5–6 | (Relational) | Not applicable at this domain scale |
| 7 | Integrated Local Condition | KarakaConditionProfile, karaka_condition_profile() |
| 8 | Aggregate Intelligence | JaiminiChartProfile, jaimini_chart_profile() |
| 9 | Network Intelligence | KarakaPair, karaka_pair() |
| 10 | Hardening | validate_jaimini_output() |
Note: Phases 5–6 (Relational Formalization and Relational Hardening) do not apply to the Jaimini domain at its current scale. The subsystem has no temporal structure or containment relationship that requires relational vessels.
The Jaimini subsystem does not compute the following. Callers are responsible for supplying correct values.
moira.sidereal).'Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus',
'Saturn', 'Rahu').The doctrinal choices made by the Jaimini subsystem are explicit and located.
| Choice | Location | Default |
|---|---|---|
| Karaka pool — 7-scheme | _POOL_7 module constant |
Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn |
| Karaka pool — 8-scheme | _POOL_8 module constant |
_POOL_7 + Rahu |
| Karaka role names | KARAKA_NAMES_7, KARAKA_NAMES_8 module constants |
Canonical per Jaimini Sutras |
| Rahu degree inversion | _effective_degree() internal function |
30 − (lon % 30) |
| Tiebreaker | jaimini_karakas() sort key |
Pool-index ordering (deterministic) |
| Scheme selection | JaiminiPolicy.scheme or scheme arg |
7 |
| Ayanamsa acknowledgement | JaiminiPolicy.ayanamsa_system field |
'Lahiri' (informational only) |
The following are the constitutional public vessels of the Jaimini subsystem.
Classification constants:
KarakaRole — string constants for the eight karaka role namesKarakaPlanetType — structural category constants: LUMINARY, INNER, OUTER, NODEPolicy:
JaiminiPolicy — frozen dataclass encoding scheme and ayanamsa acknowledgementName tables:
KARAKA_NAMES_7 — ordered list of karaka role names for the 7-schemeKARAKA_NAMES_8 — ordered list of karaka role names for the 8-schemeTruth-preservation vessels:
KarakaAssignment — immutable vessel for one planet’s karaka role assignmentJaiminiKarakaResult — immutable vessel for the complete ranked computationCondition vessels:
KarakaConditionProfile — integrated local condition for one KarakaAssignmentAggregate vessels:
JaiminiChartProfile — chart-wide aggregate over a full JaiminiKarakaResultNetwork vessels:
KarakaPair — structural edge connecting two karaka rolesComputational functions:
jaimini_karakas(sidereal_longitudes, scheme, policy) — core Chara Karaka engineatmakaraka(sidereal_longitudes, scheme) — convenience accessor for the AK planetkaraka_condition_profile(assignment, scheme) — build a condition profilejaimini_chart_profile(result) — build a chart-wide aggregate profilekaraka_pair(result, role_a, role_b) — build a network pair from two named rolesvalidate_jaimini_output(result) — invariant guard for a JaiminiKarakaResultThe following terms carry specific meanings within this subsystem and must not be used loosely.
| Term | Normative Meaning |
|---|---|
| Chara Karaka | One of the seven (or eight) variable significators computed by Jaimini’s degree-rank method |
| Atmakaraka | The planet with the highest effective degree in its sign; the soul significator; karaka_rank == 1 |
| Darakaraka | The planet with the lowest effective degree; the spouse significator; karaka_rank == scheme |
| effective degree | The sort key for a planet: lon % 30 for most planets; 30 − (lon % 30) for Rahu |
| scheme | The integer 7 or 8 selecting which planet pool and role table to use |
| degree inversion | Rahu’s exclusive transformation — its effective degree is 30 − actual_degree because it moves retrograde |
| tie | A pair of planets with exactly equal effective degrees; flagged in tie_warnings |
| tiebreaker | The deterministic pool-index ordering applied when two planets share an effective degree |
| planet type | The KarakaPlanetType structural category of a planet (LUMINARY / INNER / OUTER / NODE) |
| karaka rank | The 1-based integer position in the ranked sequence (1 = AK, scheme value = DK) |
| karaka role | The string role name assigned to a rank (e.g. 'Atmakaraka', 'Darakaraka') |
| condition profile | A flat doctrinal summary of one KarakaAssignment, integrating rank and type |
| chart profile | A chart-wide aggregate across all karaka assignments in a JaiminiKarakaResult |
| karaka pair | A KarakaPair; a structural edge between any two named karaka roles |
The following pairs must not be equated.
KarakaAssignment and KarakaConditionProfile
KarakaAssignment is the raw truth-preservation vessel from the engine. A
KarakaConditionProfile is a derived doctrinal summary augmenting it with typed
classification. One is the source; the other is a projection.
degree_in_sign and zodiacal longitude
degree_in_sign is the effective sort key (inverted for Rahu). The actual sidereal
longitude within the sign is sidereal_longitude % 30. These differ for Rahu.
karaka_rank and karaka_name
karaka_rank is an integer (1–8). karaka_name is a string role label. They are
correlated but must not be treated as interchangeable. Use KarakaRole constants
to reference a role by name; use karaka_rank for numeric comparisons.
sidereal_longitude and degree_in_sign
sidereal_longitude is the full sidereal position in [0, 360). degree_in_sign is
the effective degree within the sign used for sorting, in [0, 30] (30.0 possible for
Rahu at exactly 0° in sign).
tie_warnings and indeterminism
A non-empty tie_warnings signals an astronomically improbable but technically valid
degenerate case. It does not mean the output is invalid — a complete ranked sequence
is always returned.
scheme and pool size
scheme is the integer 7 or 8 and also the expected length of assignments. The
scheme value is the length of the pool and also controls which role names are used.
They are derived from the same integer but represent different things.
JaiminiChartProfile and JaiminiKarakaResult
JaiminiKarakaResult is the primary truth-preservation vessel from the engine.
JaiminiChartProfile is a derived aggregate summary. One is the source; the other
is a projection for downstream doctrinal use.
KarakaPair and JaiminiChartProfile
KarakaPair is a two-node network edge between two specific roles. JaiminiChartProfile
is a chart-wide summary across all seven or eight roles. One is local and relational;
the other is global.
KarakaAssignment:
karaka_rank ∈ [1, 8]planet is a non-empty stringdegree_in_sign ∈ [0.0, 30.0] (closed interval — 30.0 is permitted for Rahu at 0° in sign)sidereal_longitude ∈ [0.0, 360.0) (half-open — 360.0 is forbidden)JaiminiKarakaResult:
scheme ∈ {7, 8}len(assignments) == schemeassignments[i].karaka_rank == i + 1 for all i (consecutive from 1)assignments are distinctatmakaraka == assignments[0].planetKarakaConditionProfile:
karaka_rank ∈ [1, 8]planet_type is a valid KarakaPlanetType valueis_atmakaraka is True if and only if karaka_rank == 1is_darakaraka is True if and only if karaka_rank == schemeJaiminiChartProfile:
scheme ∈ {7, 8}len(profiles) == schemehas_ties == True if and only if tie_count >= 1has_ties == False if and only if tie_count == 0KarakaPair:
planet_a != planet_binvolves_node is True if and only if either type_a or type_b is NODEboth_are_nodes is True if and only if both type_a and type_b are NODEboth_are_nodes implies involves_nodeKARAKA_NAMES_7 and KARAKA_NAMES_8 are immutable. No function modifies or
overrides them at runtime._POOL_7 and _POOL_8 are immutable tuples. Pool membership defines which planets
are valid in a given scheme.KarakaAssignment.sidereal_longitude always stores the original pre-inversion
longitude normalised to [0, 360), even for Rahu.KarakaAssignment.degree_in_sign always stores the effective sort key (inverted
for Rahu, un-inverted for all others).JaiminiChartProfile:
atmakaraka_planet equals profiles[0].planetdarakaraka_planet equals profiles[-1].planethas_node_atmakaraka is True if and only if profiles[0].planet_type == KarakaPlanetType.NODEhas_node_darakaraka is True if and only if profiles[-1].planet_type == KarakaPlanetType.NODEprofiles are distinctKarakaPair:
both_are_nodes implies involves_node; involves_node does not imply both_are_nodeskaraka_pair() raises ValueError if either role name is absent from the result
(e.g. requesting Putrakaraka from a 7-scheme result)scheme outside {7, 8} to jaimini_karakas() raises ValueError.JaiminiPolicy with scheme outside {7, 8} raises ValueError.'Rahu' in sidereal_longitudes raises
KeyError.KeyError.KarakaAssignment with karaka_rank outside [1, 8] raises ValueError.KarakaAssignment with an empty planet string raises ValueError.KarakaAssignment with degree_in_sign outside [0.0, 30.0] raises
ValueError.KarakaAssignment with sidereal_longitude outside [0.0, 360.0)
raises ValueError.KarakaPair with the same planet in both roles raises ValueError.KarakaPair with involves_node inconsistent with the supplied
planet types raises ValueError.karaka_pair() with a role name absent from the result raises ValueError.This subsystem does not perform iterative search. All computation is a single sort over at most 8 values. There is no search exhaustion failure mode.
validate_jaimini_output() raises ValueError with a descriptive message if:
scheme is not 7 or 8len(assignments) does not equal schemekaraka_rank is not in consecutive order beginning at 1karaka_name does not match the canonical name list at its indexatmakaraka does not equal assignments[0].planettie_warnings entry references a self-pair or a planet outside the poolJaiminiKarakaResult.__post_init__ raises ValueError on construction if scheme,
assignment count, rank sequence, planet uniqueness, or atmakaraka-field consistency
are violated.JaiminiChartProfile.__post_init__ raises ValueError on construction if scheme,
profile count, or has_ties/tie_count consistency are violated.jaimini_karakas() is fully deterministic: given the same sidereal_longitudes
dict and scheme, the output is identical in every call with no dependency on
external state.karaka_condition_profile(), jaimini_chart_profile(), karaka_pair(), and
validate_jaimini_output() are pure functions with no side effects.The following command must pass without error on any constitutionally correct installation of this subsystem:
python -m pytest tests/unit/test_jaimini.py -v
All tests in test_jaimini.py must pass. The test suite validates:
KARAKA_NAMES_7 and KARAKA_NAMES_8 structure and no-duplicate invariantsjaimini_karakas() 7-scheme: rank order, atmakaraka, karaka name assignment,
degree_in_sign computation, is_rahu_inverted, no spurious tie_warningsjaimini_karakas() 8-scheme: Rahu inclusion, 8-karaka names, Ketu exclusionatmakaraka() convenience function correctnessJaiminiKarakaResult and KarakaAssignment frozen/slot constraintsKarakaRole and KarakaPlanetType classification constantsJaiminiPolicy construction, scheme validation, policy override in jaimini_karakas()JaiminiKarakaResult inspectability: by_planet(), by_karaka(), darakaraka,
has_tiesKarakaAssignment.__post_init__ guard behavior for all guard conditionsJaiminiKarakaResult.__post_init__ guard behavior: bad scheme, wrong count,
duplicate planet, atmakaraka mismatch, out-of-sequence rankkaraka_condition_profile(): is_atmakaraka, is_darakaraka, planet_type,
is_rahu_inverted flagsjaimini_chart_profile(): scheme, atmakaraka_planet, darakaraka_planet, profile
count, has_node_atmakaraka, has_ties, tie_countJaiminiChartProfile.__post_init__ guard behavior: has_ties/tie_count consistencykaraka_pair(): role correctness, planet correctness, involves_node, both_are_nodesKarakaPair.__post_init__ guard behavior: same-planet, inconsistent involves_nodevalidate_jaimini_output(): valid result accepted, wrong karaka_name detected,
planet outside pool detected, self-pair tie_warning detectedAny validation suite for this subsystem must demonstrate the following:
sidereal_longitude stores the pre-inversion value.JaiminiPolicy.scheme overrides the scheme positional
argument.KarakaAssignment and
JaiminiKarakaResult is covered by at least one rejection test.karaka_condition_profile() sets
is_atmakaraka only for rank 1 and is_darakaraka only for the last rank of
the scheme.jaimini_chart_profile() has_ties and tie_count
are consistent with the source result’s tie_warnings.karaka_pair() raises for an absent role; KarakaPair
raiseswhen planet_a == planet_b or when involves_node is inconsistent with
the supplied planet types.