feat: gate in-call demotion on credible alternative health

Round 3 showed unconditional yield-after-two-failures pushes the third
attempt onto known-bad sources in heterogeneous pools (83% vs 10%
expected success). OutcomeAwareSelector now exposes health(); a failed
source only yields when some untried candidate scores at least half its
health. Health-blind selectors keep the unconditional rule.
This commit is contained in:
2026-07-21 11:24:52 -04:00
parent 58061c7536
commit 0e17f71482
6 changed files with 95 additions and 4 deletions
+7
View File
@@ -69,6 +69,13 @@ class TestHealthAwareSelector:
assert order[0].name == "s1" # 两候选中 s1 胜出
assert order[-1].name == "s3" # 塌陷源垫底
def test_health_exposes_raw_ewma(self):
sel = HealthAwareSelector(rng=lambda: 0.0)
assert sel.health("s1") == pytest.approx(1.0) # 乐观初始
for _ in range(3):
sel.record_outcome("s1", ok=False)
assert sel.health("s1") == pytest.approx(1.0 * 0.8**3)
def test_missing_stats_defaults_to_zero_inflight(self):
sel = HealthAwareSelector(rng=lambda: 0.0)
assert [s.name for s in sel.order([_src("s1")], {})] == ["s1"]