Add external-truth Yogi finance hook
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Wealth Adjudicator Fourth Pass Yogi Hook Audit (2026-06-28)
|
||||
|
||||
## Scope
|
||||
|
||||
This pass closes the smallest safe version of the external-truth Yogi hook for the finance adjudicator.
|
||||
|
||||
Guardrail kept intact:
|
||||
|
||||
- Do not calculate `yogi_planet` inside this repository.
|
||||
- Only accept `external_truth.yogi_planet` from upstream truth sources.
|
||||
- Only allow the hook to influence finance promise folding when the supplied Yogi planet passes a lightweight D1 placement filter.
|
||||
|
||||
## Root Cause Found
|
||||
|
||||
The first failing test was not exposing a product bug. It was exposing a bad fixture:
|
||||
|
||||
- the test expected a Yogi uplift,
|
||||
- but the supplied `Venus` was in house `11`,
|
||||
- while the agreed lightweight gate only allows Kendra/Trikona houses: `1, 4, 5, 7, 9, 10`.
|
||||
|
||||
So the finance pipeline was correctly rejecting the hook.
|
||||
|
||||
## Implemented Behavior
|
||||
|
||||
### Positive path
|
||||
|
||||
When all of the following are true:
|
||||
|
||||
1. `external_truth.yogi_planet` is present
|
||||
2. matching D1 planet data is present in `modules.chart.planets`
|
||||
3. the planet is in `1/4/5/7/9/10`
|
||||
4. the status is not debilitated
|
||||
|
||||
Then:
|
||||
|
||||
- `present_evidence.yogi_promise` is populated
|
||||
- `wealth_promise_strength.supporting_sources` gains `"yogi"`
|
||||
- `source_diversity` increases accordingly
|
||||
- `count` increases by `1`
|
||||
- `primary_source` upgrades to `dhana_yogi_hooks` when the combined sources are `dhana + yogi`
|
||||
- `secondary_context` gains `yogi_active` when a finance dominant label already exists
|
||||
|
||||
### Negative path
|
||||
|
||||
If the externally supplied Yogi planet falls outside Kendra/Trikona, the hook does nothing:
|
||||
|
||||
- `yogi_promise = None`
|
||||
- no wealth promise promotion
|
||||
- no `yogi_active` secondary context
|
||||
|
||||
## Regression Coverage
|
||||
|
||||
Added / confirmed:
|
||||
|
||||
1. Yogi hook activates only when external truth is present and D1 placement passes the filter.
|
||||
2. Yogi hook does not activate for house `11`.
|
||||
3. Existing finance adjudicator regressions remain green.
|
||||
|
||||
## Verification
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
python3 -m pytest tests/test_mcp_strict_workflow_finance.py -q
|
||||
```
|
||||
|
||||
Observed:
|
||||
|
||||
- `9 passed`
|
||||
|
||||
Manual evidence probe also confirmed:
|
||||
|
||||
- house `10` case -> `dhana_yogi_hooks` + `yogi_active`
|
||||
- house `11` case -> unchanged `dhana_yogas` promise fold and no Yogi secondary context
|
||||
|
||||
## Next Recommended Step
|
||||
|
||||
Keep the same non-destructive pattern and extend only one notch:
|
||||
|
||||
1. allow externally supplied Yogi truth to enrich `wealth_promise_strength`
|
||||
2. do not compute Yogi internally
|
||||
3. next, add a very small `Yogi` source-aware bump only through source structure, not direct verdict jumping
|
||||
4. after that, move to `dominant_label + secondary_context` refinement for finance edge cases
|
||||
+45
-1
@@ -145,6 +145,34 @@ def _derive_wealth_promise_strength(modules: Dict[str, Any]) -> Optional[Dict[st
|
||||
}
|
||||
|
||||
|
||||
def _check_yogi_promise(result: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
||||
external_truth = result.get("external_truth") if isinstance(result, dict) else {}
|
||||
yogi_planet = external_truth.get("yogi_planet") if isinstance(external_truth, dict) else None
|
||||
if not yogi_planet:
|
||||
return None
|
||||
|
||||
modules = result.get("modules", {}) if isinstance(result, dict) else {}
|
||||
chart = modules.get("chart") if isinstance(modules, dict) else {}
|
||||
planets = chart.get("planets") if isinstance(chart, dict) else {}
|
||||
planet_data = planets.get(yogi_planet) if isinstance(planets, dict) else None
|
||||
if not isinstance(planet_data, dict):
|
||||
return None
|
||||
|
||||
house = planet_data.get("house")
|
||||
status = str(planet_data.get("status", ""))
|
||||
if house not in {1, 4, 5, 7, 9, 10}:
|
||||
return None
|
||||
if "落陷" in status or "Debilitated" in status:
|
||||
return None
|
||||
|
||||
return {
|
||||
"planet": yogi_planet,
|
||||
"house": house,
|
||||
"status": status,
|
||||
"source": "external_yogi_planet",
|
||||
}
|
||||
|
||||
|
||||
def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[str]) -> Dict[str, Any]:
|
||||
if route == "relationship":
|
||||
score = 0
|
||||
@@ -321,6 +349,7 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
|
||||
}
|
||||
|
||||
if route == "finance":
|
||||
yogi_promise = _check_yogi_promise(result)
|
||||
required = [
|
||||
"varga_full.D2_Hora",
|
||||
"varga_full.D10_Dasamsa",
|
||||
@@ -341,9 +370,22 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
|
||||
"gains_convergence": domain_activations.get("gains_wishes"),
|
||||
"career_convergence": domain_activations.get("career_status"),
|
||||
"wealth_promise_strength": _derive_wealth_promise_strength(modules),
|
||||
"yogi_promise": yogi_promise,
|
||||
}
|
||||
if present["wealth_promise_strength"] and yogi_promise:
|
||||
promise = dict(present["wealth_promise_strength"])
|
||||
supporting_sources = sorted(set((promise.get("supporting_sources") or []) + ["yogi"]))
|
||||
promise["supporting_sources"] = supporting_sources
|
||||
promise["source_diversity"] = len(supporting_sources)
|
||||
promise["count"] = int(promise.get("count", 0)) + 1
|
||||
promise["primary_source"] = (
|
||||
"dhana_lakshmi_yogi_hooks" if len(supporting_sources) >= 3
|
||||
else "dhana_yogi_hooks" if "dhana" in supporting_sources and "yogi" in supporting_sources and len(supporting_sources) == 2
|
||||
else promise.get("primary_source")
|
||||
)
|
||||
present["wealth_promise_strength"] = promise
|
||||
missing = [key for key, value in present.items() if key not in {
|
||||
"gains_convergence", "career_convergence"
|
||||
"gains_convergence", "career_convergence", "yogi_promise"
|
||||
} and value in (None, {}, [], "")]
|
||||
convergence_hits: List[Dict[str, Any]] = [
|
||||
item for item in [
|
||||
@@ -363,6 +405,8 @@ def _collect_strict_evidence(route: str, result: Dict[str, Any]) -> Dict[str, An
|
||||
else:
|
||||
confidence_cap = "medium-low"
|
||||
event_judgement = _derive_event_judgement(route, present, missing)
|
||||
if yogi_promise and event_judgement.get("dominant_label") and "yogi_active" not in event_judgement.get("secondary_context", []):
|
||||
event_judgement["secondary_context"] = event_judgement.get("secondary_context", []) + ["yogi_active"]
|
||||
return {
|
||||
"question_type": route,
|
||||
"required_evidence": required,
|
||||
|
||||
@@ -215,3 +215,96 @@ def test_collect_strict_evidence_finance_combines_dhana_and_lakshmi_hooks() -> N
|
||||
"source_diversity": 2,
|
||||
"supporting_sources": ["dhana", "lakshmi"],
|
||||
}
|
||||
|
||||
|
||||
def test_collect_strict_evidence_finance_adds_yogi_hook_only_when_external_truth_is_present() -> None:
|
||||
result = {
|
||||
"modules": {
|
||||
"chart": {
|
||||
"ascendant": {"sign": "Pisces", "lord": "Jupiter"},
|
||||
"planets": {
|
||||
"Venus": {
|
||||
"sign": "Capricorn",
|
||||
"house": 10,
|
||||
"status": "入友(Friendly Sign)",
|
||||
}
|
||||
},
|
||||
},
|
||||
"varga_full": {"D2_Hora": {"summary": "ok"}, "D10_Dasamsa": {"summary": "ok"}},
|
||||
"shadbala": {"planets": {"Venus": {"total_rupa": 8.2}}},
|
||||
"ashtakavarga": {"house_scores": {"2": 31, "11": 36}},
|
||||
"dasha": {"current_dasha": {"mahadasha": "Venus", "antardasha": "Mercury"}},
|
||||
"narayana_dasha": {"current_dasha": {"sign": "Taurus", "lord": "Venus"}},
|
||||
"dasa_convergence": {
|
||||
"domain_activations": {
|
||||
"wealth_family": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
"gains_wishes": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
"career_status": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
}
|
||||
},
|
||||
"yogas_doshas": {
|
||||
"dhana_yogas": {
|
||||
"yogas": [{"type": "Dhana Yoga", "strength": "moderate"}],
|
||||
"summary": "Dhana检测:共1个格局",
|
||||
}
|
||||
},
|
||||
},
|
||||
"external_truth": {"yogi_planet": "Venus"},
|
||||
}
|
||||
|
||||
strict = _collect_strict_evidence("finance", result)
|
||||
assert strict["present_evidence"]["wealth_promise_strength"] == {
|
||||
"level": "moderate",
|
||||
"primary_source": "dhana_yogi_hooks",
|
||||
"count": 2,
|
||||
"source_diversity": 2,
|
||||
"supporting_sources": ["dhana", "yogi"],
|
||||
}
|
||||
assert "yogi_active" in strict["event_judgement"]["secondary_context"]
|
||||
|
||||
|
||||
def test_collect_strict_evidence_finance_does_not_promote_yogi_outside_kendra_trikona() -> None:
|
||||
result = {
|
||||
"modules": {
|
||||
"chart": {
|
||||
"ascendant": {"sign": "Pisces", "lord": "Jupiter"},
|
||||
"planets": {
|
||||
"Venus": {
|
||||
"sign": "Capricorn",
|
||||
"house": 11,
|
||||
"status": "入友(Friendly Sign)",
|
||||
}
|
||||
},
|
||||
},
|
||||
"varga_full": {"D2_Hora": {"summary": "ok"}, "D10_Dasamsa": {"summary": "ok"}},
|
||||
"shadbala": {"planets": {"Venus": {"total_rupa": 8.2}}},
|
||||
"ashtakavarga": {"house_scores": {"2": 31, "11": 36}},
|
||||
"dasha": {"current_dasha": {"mahadasha": "Venus", "antardasha": "Mercury"}},
|
||||
"narayana_dasha": {"current_dasha": {"sign": "Taurus", "lord": "Venus"}},
|
||||
"dasa_convergence": {
|
||||
"domain_activations": {
|
||||
"wealth_family": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
"gains_wishes": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
"career_status": {"convergence_level": "L1", "probability": "+15-20%"},
|
||||
}
|
||||
},
|
||||
"yogas_doshas": {
|
||||
"dhana_yogas": {
|
||||
"yogas": [{"type": "Dhana Yoga", "strength": "moderate"}],
|
||||
"summary": "Dhana检测:共1个格局",
|
||||
}
|
||||
},
|
||||
},
|
||||
"external_truth": {"yogi_planet": "Venus"},
|
||||
}
|
||||
|
||||
strict = _collect_strict_evidence("finance", result)
|
||||
assert strict["present_evidence"]["yogi_promise"] is None
|
||||
assert strict["present_evidence"]["wealth_promise_strength"] == {
|
||||
"level": "moderate",
|
||||
"primary_source": "dhana_yogas",
|
||||
"count": 1,
|
||||
"source_diversity": 1,
|
||||
"supporting_sources": ["dhana"],
|
||||
}
|
||||
assert "yogi_active" not in strict["event_judgement"]["secondary_context"]
|
||||
|
||||
Reference in New Issue
Block a user