Add Jaimini marriage label bridge

This commit is contained in:
732642856
2026-06-28 12:10:07 +08:00
parent 657bccd2f4
commit 4a46b5faad
3 changed files with 203 additions and 1 deletions
@@ -0,0 +1,68 @@
# Marriage Adjudicator Jaimini Bridge v1 Audit (2026-06-28)
## Scope
This pass adds the smallest Jaimini bridge to the relationship strict workflow.
It fixes only `label-lift failure` for legal-marriage cases.
## Implemented Behavior
The relationship event judgement now preserves legacy fields:
- `score`
- `verdict`
- `primary_drivers`
and adds:
- `dominant_label`
- `secondary_context`
## Boundary
v1 may lift only:
- `legal_marriage`
v1 does not lift:
- `relationship_formation`
- `public_formalization`
## Jaimini Bridge
`present_evidence.jaimini_marriage_support` has:
- `level`: `none`, `weak`, or `moderate`
- `signals`
- `source`: `jaimini_bridge_v1`
`strong` is intentionally not available in v1.
## Hard Gates
`dominant_label = legal_marriage` requires:
- D9 present
- UL present
- Vimshottari present
- Narayana present
- Vivah Saham or marriage convergence present
- moderate Jaimini support
If a hard gate is missing, Jaimini evidence remains context-only.
## Verification
Commands:
```bash
python3 -m pytest tests/test_mcp_strict_workflow_relationship.py -q
python3 -m pytest tests/test_mcp_strict_workflow_finance.py -q
```
Observed:
- relationship: `2 passed`
- finance: `16 passed`
+73 -1
View File
@@ -372,6 +372,45 @@ def _check_external_avayogi_risk(result: Dict[str, Any]) -> Optional[Dict[str, A
}
def _derive_jaimini_marriage_support(present: Dict[str, Any]) -> Dict[str, Any]:
signals: List[str] = []
darakaraka = present.get("darakaraka")
upapada_lagna = present.get("upapada_lagna")
if darakaraka:
signals.append("darakaraka_active")
if isinstance(darakaraka, dict):
if darakaraka.get("house") == 7 or darakaraka.get("house_from_lagna") == 7:
signals.append("dk_7h_link")
if darakaraka.get("ul_link") or darakaraka.get("linked_to_ul"):
signals.append("dk_ul_link")
if isinstance(upapada_lagna, dict) and isinstance(darakaraka, dict):
dk_sign = darakaraka.get("sign")
ul_sign = upapada_lagna.get("sign")
if dk_sign and ul_sign and dk_sign == ul_sign and "dk_ul_link" not in signals:
signals.append("dk_ul_link")
if present.get("jaimini_timing_support"):
signals.append("jaimini_dasha_support")
if not signals:
level = "none"
elif len(signals) == 1:
level = "weak"
elif "darakaraka_active" in signals:
level = "moderate"
else:
level = "weak"
return {
"level": level,
"signals": signals,
"source": "jaimini_bridge_v1",
}
def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[str]) -> Dict[str, Any]:
if route == "relationship":
score = 0
@@ -395,10 +434,37 @@ def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[s
verdict = "weak_window_needs_confirmation"
else:
verdict = "insufficient_evidence"
jaimini_support = present.get("jaimini_marriage_support") or {}
secondary_context: List[str] = []
if present.get("darakaraka"):
secondary_context.append("darakaraka_active")
if jaimini_support.get("level") == "moderate":
secondary_context.append("jaimini_support")
if present.get("upapada_lagna"):
secondary_context.append("ul_support")
hard_gate_missing = any(
key in missing for key in (
"d9_navamsa",
"upapada_lagna",
"vimshottari_current",
"narayana_current",
)
)
label_support_present = bool(present.get("vivah_saham") or present.get("marriage_convergence"))
dominant_label = None
if (
not hard_gate_missing
and label_support_present
and jaimini_support.get("level") == "moderate"
):
dominant_label = "legal_marriage"
return {
"event_family": "relationship",
"score": score,
"verdict": verdict,
"dominant_label": dominant_label,
"secondary_context": secondary_context,
"primary_drivers": [
key for key in (
"marriage_convergence",
@@ -525,7 +591,13 @@ 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"),
}
missing = [key for key, value in present.items() if value in (None, {}, [], "")]
present["jaimini_timing_support"] = _safe_get(modules, "jaimini", "marriage_timing_support")
present["jaimini_marriage_support"] = _derive_jaimini_marriage_support(present)
missing = [
key for key, value in present.items()
if key not in {"jaimini_marriage_support", "jaimini_timing_support"}
and value in (None, {}, [], "")
]
convergence = present["marriage_convergence"] or {}
confidence_cap = "medium"
if missing:
@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""Regression tests for MCP relationship event adjudication."""
from __future__ import annotations
from mcp_server import _collect_strict_evidence
def _base_relationship_result() -> dict:
return {
"modules": {
"varga_full": {"D9_Navamsa": {"summary": "ok"}},
"special_lagnas": {"Upapada_Lagna": {"sign": "Libra", "lord": "Venus"}},
"jaimini": {
"darakaraka": {"planet": "Venus", "house": 7},
"marriage_support": {"dk_7h_link": True},
},
"vivah_saham": {"sign": "Taurus", "house": 7},
"dasha": {"current_dasha": {"mahadasha": "Venus", "antardasha": "Moon"}},
"narayana_dasha": {"current_dasha": {"sign": "Libra", "lord": "Venus"}},
"dasa_convergence": {
"domain_activations": {
"marriage_partnership": {"convergence_level": "L1", "probability": "+15-20%"}
}
},
}
}
def test_relationship_jaimini_bridge_lifts_legal_marriage_label() -> None:
strict = _collect_strict_evidence("relationship", _base_relationship_result())
assert strict["present_evidence"]["jaimini_marriage_support"] == {
"level": "moderate",
"signals": ["darakaraka_active", "dk_7h_link"],
"source": "jaimini_bridge_v1",
}
assert strict["event_judgement"]["dominant_label"] == "legal_marriage"
assert strict["event_judgement"]["secondary_context"] == [
"darakaraka_active",
"jaimini_support",
"ul_support",
]
def test_relationship_jaimini_bridge_stays_context_only_when_d9_missing() -> None:
result = _base_relationship_result()
del result["modules"]["varga_full"]["D9_Navamsa"]
strict = _collect_strict_evidence("relationship", result)
assert strict["present_evidence"]["jaimini_marriage_support"] == {
"level": "moderate",
"signals": ["darakaraka_active", "dk_7h_link"],
"source": "jaimini_bridge_v1",
}
assert strict["event_judgement"]["dominant_label"] is None
assert strict["event_judgement"]["secondary_context"] == [
"darakaraka_active",
"jaimini_support",
"ul_support",
]