Add career adjudicator A10 AmK Karakamsha bridge

This commit is contained in:
732642856
2026-06-28 14:41:45 +08:00
parent 7390ff1b6f
commit ac6f4ed85f
3 changed files with 245 additions and 0 deletions
@@ -0,0 +1,64 @@
# Advanced Technique Adjudicator ROI Queue - 2026-06-28
## Audit Basis
The capability registry validates 89 techniques. A stricter static pass over
advanced Vedic/Jyotish techniques found 76 high-value advanced techniques, of
which roughly 22 are directly consumed by the current MCP strict workflows or
their evidence contracts. Around 54 remain useful but under-used by the
adjudicators.
`covered` means the project can compute or expose the technique. It does not
mean the technique is already weighted in relationship, finance, career, or
event adjudication.
## First ROI Queue
1. `A10 / AmK / Karakamsha` into career adjudication.
- Status: implemented in this pass.
- Reason: highest value for career timing and status manifestation.
2. `Argala / Virodhargala` into career and relationship conflict handling.
- Reason: distinguishes support from obstruction.
3. `Ashtakavarga PAV / Sodhita / Kakshya` into finance and transit timing.
- Reason: already computed but not deeply weighted.
4. `Shadbala six components` into finance/career/relationship confidence caps.
- Reason: total strength exists; component-level use is still shallow.
5. `Yogini / Ashtottari / Kalachakra` as secondary dasha convergence.
- Reason: already available in full-reading but not adjudicator-weighted.
6. `D7 / D12 / D24 / D30 / D60` domain-specific varga gates.
- Reason: needed for child, family, education, crisis, and ultra-sensitive
rectification contexts.
7. `Tajika / Sahams` annual event adjudication.
- Reason: annual closure has begun but is not yet a general verdict layer.
8. `KP ruling planets / Prashna workflow` for specific yes/no event questions.
- Reason: high value but requires stricter question-time input boundaries.
## Implemented This Pass
Career strict workflow now requires and scores:
- `varga_full.D10_Dasamsa`
- `special_lagnas.A10_Karma_Pada`
- `jaimini.karakas.Amatyakaraka`
- `jaimini.karakamsha`
- `dasha.current_dasha`
- `narayana_dasha.current_dasha`
- `dasa_convergence.domain_activations.career_status`
It emits:
- `dominant_label = "career_status"` only when hard gates are present and score
reaches the moderated threshold.
- `secondary_context` values: `a10_active`, `amk_active`,
`karakamsha_context`, and optional `external_activation_support`.
## Verification
- `python3 -m pytest tests/test_mcp_strict_workflow_career.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_finance.py tests/test_vedastro_service_adapter_executor.py -q`
- Result: `37 passed`
## Boundary
This is not a full career prediction engine. The new workflow only converts
already-computed A10/AmK/Karakamsha assets into auditable strict evidence. It
does not claim external oracle closure for career event timing.
+116
View File
@@ -574,6 +574,74 @@ def _derive_dignity_guardrail(route: str, present: Dict[str, Any]) -> Dict[str,
def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[str]) -> Dict[str, Any]:
if route == "career":
score = 0
score += 20 if present.get("d10_dasamsa") else 0
score += 15 if present.get("a10_karma_pada") else 0
score += 15 if present.get("amatyakaraka") else 0
score += 10 if present.get("karakamsha") else 0
score += 10 if present.get("vimshottari_current") else 0
score += 10 if present.get("narayana_current") else 0
score += _convergence_score(present.get("career_convergence"))
external_activation = present.get("external_activation") or {}
if external_activation.get("level") == "moderate":
score += 5
if missing:
score = min(score, 35)
score = min(score, 100)
if missing:
verdict = "insufficient_evidence"
elif score >= 80:
verdict = "high_probability_window"
elif score >= 60:
verdict = "moderate_probability_window"
elif score >= 40:
verdict = "weak_window_needs_confirmation"
else:
verdict = "insufficient_evidence"
secondary_context: List[str] = []
if present.get("a10_karma_pada"):
secondary_context.append("a10_active")
if present.get("amatyakaraka"):
secondary_context.append("amk_active")
if present.get("karakamsha"):
secondary_context.append("karakamsha_context")
if external_activation.get("level") == "moderate":
secondary_context.append("external_activation_support")
hard_gate_missing = any(
key in missing for key in (
"d10_dasamsa",
"a10_karma_pada",
"vimshottari_current",
"narayana_current",
)
)
dominant_label = None
if not hard_gate_missing and present.get("career_convergence") and score >= 60:
dominant_label = "career_status"
return {
"event_family": "career",
"score": score,
"verdict": verdict,
"dominant_label": dominant_label,
"secondary_context": secondary_context,
"primary_drivers": [
key for key in (
"career_convergence",
"vimshottari_current",
"narayana_current",
"a10_karma_pada",
"amatyakaraka",
"karakamsha",
)
if present.get(key)
],
}
if route == "relationship":
score = 0
score += 15 if present.get("d9_navamsa") else 0
@@ -756,6 +824,54 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
modules = result.get("modules", {}) if isinstance(result, dict) else {}
domain_activations = _safe_get(modules, "dasa_convergence", "domain_activations") or {}
if route == "career":
required = [
"varga_full.D10_Dasamsa",
"special_lagnas.A10_Karma_Pada",
"jaimini.karakas.Amatyakaraka",
"jaimini.karakamsha",
"dasha.current_dasha",
"narayana_dasha.current_dasha",
"dasa_convergence.domain_activations.career_status",
]
present = {
"d10_dasamsa": _safe_get(modules, "varga_full", "D10_Dasamsa"),
"a10_karma_pada": _safe_get(modules, "special_lagnas", "A10_Karma_Pada"),
"amatyakaraka": _safe_get(modules, "jaimini", "karakas", "Amatyakaraka"),
"karakamsha": _safe_get(modules, "jaimini", "karakamsha"),
"vimshottari_current": _safe_get(modules, "dasha", "current_dasha"),
"narayana_current": _safe_get(modules, "narayana_dasha", "current_dasha"),
"career_convergence": domain_activations.get("career_status"),
}
present["external_activation"] = _derive_external_activation_support(modules, "career")
missing = [key for key, value in present.items() if key not in {
"external_activation"
} and value in (None, {}, [], "")]
convergence = present["career_convergence"] or {}
confidence_cap = "medium"
if missing:
confidence_cap = "low"
elif convergence.get("convergence_level") in {"L4", "L5"}:
confidence_cap = "medium-high"
elif convergence.get("convergence_level") == "L3":
confidence_cap = "medium"
else:
confidence_cap = "medium-low"
event_judgement = _derive_event_judgement(route, present, missing)
return {
"question_type": route,
"required_evidence": required,
"present_evidence": present,
"missing_evidence": missing,
"confidence_cap": confidence_cap,
"blocked": bool(missing),
"event_judgement": event_judgement,
"reason": (
"Career timing requires D10 + A10/Karma Pada + AmK/Karakamsha "
"plus dual dasha and career convergence support."
),
}
if route == "relationship":
required = [
"varga_full.D9_Navamsa",
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
"""Regression tests for MCP career event adjudication."""
from __future__ import annotations
from mcp_server import _collect_strict_evidence
def _base_career_result() -> dict:
return {
"modules": {
"varga_full": {"D10_Dasamsa": {"summary": "career varga present"}},
"special_lagnas": {"A10_Karma_Pada": {"sign": "Capricorn", "lord": "Saturn"}},
"jaimini": {
"karakas": {
"Amatyakaraka": {"planet": "Mercury"},
"Atmakaraka": {"planet": "Sun"},
},
"karakamsha": {"karakamsha_sign": "Leo", "karakamsha_lord": "Sun"},
},
"dasha": {"current_dasha": {"mahadasha": "Mercury", "antardasha": "Sun"}},
"narayana_dasha": {"current_dasha": {"sign": "Capricorn", "lord": "Saturn"}},
"dasa_convergence": {
"domain_activations": {
"career_status": {"convergence_level": "L2", "probability": "35-50%"}
}
},
}
}
def test_career_collects_a10_amk_karakamsha_as_strict_evidence() -> None:
strict = _collect_strict_evidence("career", _base_career_result())
assert strict["question_type"] == "career"
assert strict["present_evidence"]["d10_dasamsa"] == {"summary": "career varga present"}
assert strict["present_evidence"]["a10_karma_pada"] == {"sign": "Capricorn", "lord": "Saturn"}
assert strict["present_evidence"]["amatyakaraka"] == {"planet": "Mercury"}
assert strict["present_evidence"]["karakamsha"] == {
"karakamsha_sign": "Leo",
"karakamsha_lord": "Sun",
}
assert strict["event_judgement"]["event_family"] == "career"
assert strict["event_judgement"]["dominant_label"] == "career_status"
assert strict["event_judgement"]["secondary_context"] == [
"a10_active",
"amk_active",
"karakamsha_context",
]
def test_career_blocks_label_when_d10_is_missing_but_preserves_jaimini_context() -> None:
result = _base_career_result()
del result["modules"]["varga_full"]["D10_Dasamsa"]
strict = _collect_strict_evidence("career", result)
assert "d10_dasamsa" in strict["missing_evidence"]
assert strict["blocked"] is True
assert strict["event_judgement"]["dominant_label"] is None
assert strict["event_judgement"]["secondary_context"] == [
"a10_active",
"amk_active",
"karakamsha_context",
]