Add external-truth Yogi finance hook

This commit is contained in:
732642856
2026-06-28 10:00:54 +08:00
parent e18cb268a6
commit 0bee529579
3 changed files with 221 additions and 1 deletions
@@ -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
View File
@@ -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,
+93
View File
@@ -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"]