Extend Shadbala component cap to core routes

This commit is contained in:
732642856
2026-06-28 15:34:17 +08:00
parent e492cb7034
commit 73d89586ca
4 changed files with 175 additions and 2 deletions
@@ -0,0 +1,61 @@
# Shadbala Component Cap Across Core Routes
Date: 2026-06-28
## Scope
This pass extends the Shadbala six-component completeness cap beyond finance into the three core strict adjudication routes:
- career
- relationship
- finance
## Route Boundary
Finance still requires `shadbala.planets`.
Career and relationship do not make Shadbala a hard route requirement in v1. Instead:
- if Shadbala is absent, the existing route continues unchanged;
- if Shadbala is present, its six-component completeness is audited;
- incomplete Shadbala lowers `confidence_cap` to `low`.
This prevents a partial strength packet from inflating high-rigor readings while preserving backward compatibility for career and relationship routes.
## Required Components
- `sthana`
- `dig`
- `kala`
- `chesta`
- `naisargika`
- `drik`
Accepted layouts:
- `planet.components.<component>`
- direct `planet.<component>`
## Adjudication Effect
When the component audit is `blocked` or `incomplete`:
- `confidence_cap = "low"`
- `secondary_context += ["shadbala_component_gap"]`
When complete:
- no confidence penalty
- no gap context
## Anti-Overclaim Rule
This is not Shadbala absolute calibration. It only enforces component completeness.
Still open:
- absolute Rupa comparison against JHora/PyJHora/VedAstro
- six-component value tolerance tests
- route-specific Shadbala planet selection and score weighting
- public benchmark history for Shadbala drift
+16 -2
View File
@@ -734,6 +734,9 @@ def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[s
secondary_context.append("amk_active")
if present.get("karakamsha"):
secondary_context.append("karakamsha_context")
shadbala_component_audit = present.get("shadbala_component_audit") or {}
if shadbala_component_audit.get("status") in {"blocked", "incomplete"}:
secondary_context.append("shadbala_component_gap")
if argala_support.get("level") == "supportive":
secondary_context.append("argala_support")
elif argala_support.get("level") == "obstructive":
@@ -810,6 +813,9 @@ def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[s
secondary_context.append("jaimini_support")
if present.get("upapada_lagna"):
secondary_context.append("ul_support")
shadbala_component_audit = present.get("shadbala_component_audit") or {}
if shadbala_component_audit.get("status") in {"blocked", "incomplete"}:
secondary_context.append("shadbala_component_gap")
if argala_support.get("level") == "supportive":
secondary_context.append("argala_support")
elif argala_support.get("level") == "obstructive":
@@ -996,15 +1002,19 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
"narayana_current": _safe_get(modules, "narayana_dasha", "current_dasha"),
"career_convergence": domain_activations.get("career_status"),
}
present["shadbala"] = _safe_get(modules, "shadbala", "planets")
present["shadbala_component_audit"] = _derive_shadbala_component_audit(present["shadbala"]) if present["shadbala"] else None
present["argala_support"] = _derive_argala_support(modules, 10)
present["external_activation"] = _derive_external_activation_support(modules, "career")
missing = [key for key, value in present.items() if key not in {
"external_activation", "argala_support"
"external_activation", "argala_support", "shadbala", "shadbala_component_audit"
} and value in (None, {}, [], "")]
convergence = present["career_convergence"] or {}
confidence_cap = "medium"
if missing:
confidence_cap = "low"
elif (present.get("shadbala_component_audit") or {}).get("status") in {"blocked", "incomplete"}:
confidence_cap = "low"
elif convergence.get("convergence_level") in {"L4", "L5"}:
confidence_cap = "medium-high"
elif convergence.get("convergence_level") == "L3":
@@ -1046,6 +1056,8 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
"narayana_current": _safe_get(modules, "narayana_dasha", "current_dasha"),
"marriage_convergence": domain_activations.get("marriage_partnership"),
}
present["shadbala"] = _safe_get(modules, "shadbala", "planets")
present["shadbala_component_audit"] = _derive_shadbala_component_audit(present["shadbala"]) if present["shadbala"] else None
present["jaimini_timing_support"] = _safe_get(modules, "jaimini", "marriage_timing_support")
present["jaimini_marriage_support"] = _derive_jaimini_marriage_support(present)
present["argala_support"] = _derive_argala_support(modules, 7)
@@ -1053,7 +1065,7 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
present["dignity_guardrail"] = _derive_dignity_guardrail(route, present)
missing = [
key for key, value in present.items()
if key not in {"chart", "external_activation", "dignity_guardrail", "jaimini_marriage_support", "jaimini_timing_support", "argala_support"}
if key not in {"chart", "external_activation", "dignity_guardrail", "jaimini_marriage_support", "jaimini_timing_support", "argala_support", "shadbala", "shadbala_component_audit"}
and value in (None, {}, [], "")
]
convergence = present["marriage_convergence"] or {}
@@ -1062,6 +1074,8 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
confidence_cap = "low"
elif present["dignity_guardrail"].get("status") == "conflict":
confidence_cap = "low"
elif (present.get("shadbala_component_audit") or {}).get("status") in {"blocked", "incomplete"}:
confidence_cap = "low"
elif convergence.get("convergence_level") in {"L4", "L5"}:
confidence_cap = "medium-high"
elif convergence.get("convergence_level") == "L3":
+49
View File
@@ -94,3 +94,52 @@ def test_career_argala_bridge_uses_tenth_house_as_modifier_only() -> None:
}
assert strict["event_judgement"]["dominant_label"] == "career_status"
assert "argala_support" in strict["event_judgement"]["secondary_context"]
def test_career_caps_confidence_when_provided_shadbala_components_are_incomplete() -> None:
result = _base_career_result()
result["modules"]["dasa_convergence"]["domain_activations"]["career_status"] = {
"convergence_level": "L4",
"probability": "70-85%",
}
result["modules"]["shadbala"] = {"planets": {"Mercury": {"total_rupa": 7.5}}}
strict = _collect_strict_evidence("career", result)
assert strict["present_evidence"]["shadbala_component_audit"] == {
"status": "incomplete",
"source": "shadbala.planets",
"required_components": ["sthana", "dig", "kala", "chesta", "naisargika", "drik"],
"missing": {"Mercury": ["sthana", "dig", "kala", "chesta", "naisargika", "drik"]},
}
assert strict["confidence_cap"] == "low"
assert "shadbala_component_gap" in strict["event_judgement"]["secondary_context"]
def test_career_accepts_complete_shadbala_components_without_cap_penalty() -> None:
result = _base_career_result()
result["modules"]["dasa_convergence"]["domain_activations"]["career_status"] = {
"convergence_level": "L4",
"probability": "70-85%",
}
result["modules"]["shadbala"] = {
"planets": {
"Mercury": {
"components": {
"sthana": 1.0,
"dig": 0.8,
"kala": 1.2,
"chesta": 0.7,
"naisargika": 0.5,
"drik": 0.3,
},
"total_rupa": 4.5,
}
}
}
strict = _collect_strict_evidence("career", result)
assert strict["present_evidence"]["shadbala_component_audit"]["status"] == "complete"
assert strict["confidence_cap"] == "medium-high"
assert "shadbala_component_gap" not in strict["event_judgement"]["secondary_context"]
@@ -149,3 +149,52 @@ def test_relationship_dignity_guardrail_uses_relevant_planets_only() -> None:
assert strict["present_evidence"]["dignity_guardrail"]["score_delta"] == 5
assert "dignity_supportive_recovery" in strict["event_judgement"]["secondary_context"]
def test_relationship_caps_confidence_when_provided_shadbala_components_are_incomplete() -> None:
result = _base_relationship_result()
result["modules"]["dasa_convergence"]["domain_activations"]["marriage_partnership"] = {
"convergence_level": "L4",
"probability": "70-85%",
}
result["modules"]["shadbala"] = {"planets": {"Venus": {"total_rupa": 8.2}}}
strict = _collect_strict_evidence("relationship", result)
assert strict["present_evidence"]["shadbala_component_audit"] == {
"status": "incomplete",
"source": "shadbala.planets",
"required_components": ["sthana", "dig", "kala", "chesta", "naisargika", "drik"],
"missing": {"Venus": ["sthana", "dig", "kala", "chesta", "naisargika", "drik"]},
}
assert strict["confidence_cap"] == "low"
assert "shadbala_component_gap" in strict["event_judgement"]["secondary_context"]
def test_relationship_accepts_complete_shadbala_components_without_cap_penalty() -> None:
result = _base_relationship_result()
result["modules"]["dasa_convergence"]["domain_activations"]["marriage_partnership"] = {
"convergence_level": "L4",
"probability": "70-85%",
}
result["modules"]["shadbala"] = {
"planets": {
"Venus": {
"components": {
"sthana": 1.0,
"dig": 0.8,
"kala": 1.2,
"chesta": 0.7,
"naisargika": 0.5,
"drik": 0.3,
},
"total_rupa": 4.5,
}
}
}
strict = _collect_strict_evidence("relationship", result)
assert strict["present_evidence"]["shadbala_component_audit"]["status"] == "complete"
assert strict["confidence_cap"] == "medium-high"
assert "shadbala_component_gap" not in strict["event_judgement"]["secondary_context"]