Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/ml/direct_ranker_elite_guarded_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EliteGuardrails:

max_eval_gap_cp: float
max_candidate_rank: int
min_probability: float = 0.0
allow_missing_eval_gap: bool = False
allow_missing_candidate_rank: bool = False

Expand All @@ -52,10 +53,23 @@ def elite_guarded_policy_label(move_policy: str | None) -> str:

def guardrails_for_policy(move_policy: str | None) -> EliteGuardrails:
policy = str(move_policy or "").strip()
# Step 35B:
# Elite policies are model-first only for truly engine-like personas, but
# manual/runtime use must still avoid feeling like unrestricted engine play.
# Keep the model behind conservative per-move guardrails so unsafe or
# low-confidence suggestions fall back to the Statistical selector.
if policy == DIRECT_RANKER_ELITE_GUARDED_STRICT:
return EliteGuardrails(max_eval_gap_cp=100.0, max_candidate_rank=5)
return EliteGuardrails(
max_eval_gap_cp=50.0,
max_candidate_rank=3,
min_probability=0.35,
)
if policy == DIRECT_RANKER_ELITE_GUARDED:
return EliteGuardrails(max_eval_gap_cp=200.0, max_candidate_rank=5)
return EliteGuardrails(
max_eval_gap_cp=75.0,
max_candidate_rank=5,
min_probability=0.30,
)
raise ValueError(f"not an elite guarded policy: {move_policy!r}")

def recommended_elite_runtime_policy(
Expand Down
11 changes: 11 additions & 0 deletions tests/test_direct_ranker_guarded_hybrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,14 @@ def test_guarded_hybrid_audit_counts_eligible_and_fallbacks() -> None:
"engine_gap_too_high": 1,
"outside_top_engine_rank": 1,
}

def test_low_probability_falls_back_when_config_requires_confidence() -> None:
result = guardrails_for_shadow_result(
shadow_result(ml_top_probability=0.12),
board=chess.Board(),
release_report=ready_report(),
config=GuardedHybridConfig(min_probability=0.30),
)

assert result["passed"] is False
assert result["reason"] == "probability_too_low"
15 changes: 9 additions & 6 deletions tests/test_elite_guarded_runtime_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_standard_elite_policy_allows_safe_model_first_move() -> None:
model_move="Nf3",
fallback_move="e4",
candidate_rank=3,
eval_gap_cp=90,
eval_gap_cp=60,
)
assert decision.selected_move == "Nf3"
assert decision.used_model_move is True
Expand All @@ -35,12 +35,12 @@ def test_strict_elite_policy_uses_tighter_gap_guardrail() -> None:
normal_ok, _ = should_use_model_move(
move_policy=DIRECT_RANKER_ELITE_GUARDED,
candidate_rank=2,
eval_gap_cp=150,
eval_gap_cp=60,
)
strict_ok, strict_reason = should_use_model_move(
move_policy=DIRECT_RANKER_ELITE_GUARDED_STRICT,
candidate_rank=2,
eval_gap_cp=150,
eval_gap_cp=60,
)
assert normal_ok is True
assert strict_ok is False
Expand Down Expand Up @@ -79,6 +79,9 @@ def test_non_elite_status_does_not_get_elite_policy() -> None:
def test_guardrail_values_are_documented_by_tests() -> None:
normal = guardrails_for_policy(DIRECT_RANKER_ELITE_GUARDED)
strict = guardrails_for_policy(DIRECT_RANKER_ELITE_GUARDED_STRICT)
assert normal.max_eval_gap_cp == 200
assert strict.max_eval_gap_cp == 100
assert normal.max_candidate_rank == strict.max_candidate_rank == 5
assert normal.max_eval_gap_cp == 75
assert strict.max_eval_gap_cp == 50
assert normal.max_candidate_rank == 5
assert strict.max_candidate_rank == 3
assert normal.min_probability == 0.30
assert strict.min_probability == 0.35
18 changes: 18 additions & 0 deletions tests/test_elite_guarded_runtime_wiring.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,21 @@ def test_ui_elite_helpers_accept_original_worker_call_signature() -> None:
assert report["assessment"]["status"] == "release_candidate_ready"
assert config.require_release_gate_ready is False
assert config.max_engine_rank == 3

def test_worker_elite_config_is_conservative() -> None:
strict = workers._elite_guarded_config(
BOT_MOVE_POLICY_DIRECT_RANKER_ELITE_GUARDED_STRICT,
)
normal = workers._elite_guarded_config(
BOT_MOVE_POLICY_DIRECT_RANKER_ELITE_GUARDED,
)

assert strict.require_release_gate_ready is False
assert strict.max_engine_rank == 3
assert strict.max_score_gap_cp == 50
assert strict.min_probability == 0.35

assert normal.require_release_gate_ready is False
assert normal.max_engine_rank == 5
assert normal.max_score_gap_cp == 75
assert normal.min_probability == 0.30