Private
Public Access
0
0
Files
manual_slop/tests/tier2/phase11_invariant_test.py
T
ed 1fa2b19257 conductor(plan): mark Phase 11 complete (ai_client SS 11->0; CRITICAL anti-sliming)
Phase 11: ai_client silent-swallow cleanup (11 sites migrated).

Helpers added to src/ai_client.py:
- _try_warm_sdk_result(name) -> Result[Any] (sites 1+2)
- _set_tool_preset_result(preset_name) -> Result[None] (site 5)
- _set_bias_profile_result(profile_name) -> Result[None] (site 6)
- _extract_gemini_thoughts_result(resp) -> Result[str] (site 7)
- _list_minimax_models_result(api_key) -> Result[list[str]] (site 8)
- _count_gemini_tokens_for_stats_result(md_content) -> Result[int] (sites 9+10)

Helpers reused from earlier phases:
- _delete_gemini_cache_result from Phase 10 (sites 3+4)
- _set_tool_preset_result from site 5 (site 11)

Per-site decision (TIER1_REVIEW Phase 11 anti-sliming protocol):
- Sites with 'except: pass': MIGRATE to Result (no sentinel-None)
- Sites with 'except (NarrowType): sys.stderr.write': MIGRATE to Result
- _try_warm_sdk_result: Result variant (NOT sentinel-None which the audit
  flagged as UNCLEAR; Result pattern matches Heuristic A)

Dilemma resolved: initial sentinel approach (_try_warm_sdk -> Any | None)
flagged as UNCLEAR (Heuristic B requires class method + self.attr assign).
Per Phase 9 redo precedent: migrate to Result instead of adding heuristic.

Audit state (after Phase 11):
  mcp_client: 0 migration-target (Phase 3-8 complete)
  ai_client:  18 -> 7 migration-target
              BC: 0 (Phase 10 done)
              SS: 11 -> 0 ✓
              RETHROW: 6 (Phase 12)
              UNCLEAR: 0
              COMPLIANT: 27 -> 33 (+6 from helpers)
  rag_engine: 9 migration-target (Phase 13)

Tests: 97 pass (was 79 in Phase 10; +18 Phase 11 site/invariant tests).
2026-06-20 14:13:09 -04:00

80 lines
2.8 KiB
Python

"""Phase 11 invariant tests (GREEN).
11 SS sites migrated via 8 helpers + 1 reused helper:
- _try_warm_sdk_result (sites 1+2; both classify functions)
- _delete_gemini_cache_result (reused from Phase 10 for sites 3+4)
- _set_tool_preset_result (site 5)
- _set_bias_profile_result (site 6; also used by site 11)
- _extract_gemini_thoughts_result (site 7)
- _list_minimax_models_result (site 8)
- _count_gemini_tokens_for_stats_result (sites 9+10)
- _set_tool_preset_result (site 11; reused from site 5)
"""
import sys
sys.path.insert(0, ".")
def test_phase11_ai_client_ss_count_zero():
"""After Phase 11: ai_client SS count is 0 (was 11)."""
import json
import subprocess
r = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py",
"--include-baseline", "--json"],
capture_output=True, text=True
)
data = json.loads(r.stdout)
files = {f["filename"]: f for f in data["files"]}
ai = files["src\\ai_client.py"]
ss = sum(1 for x in ai["findings"] if x["category"] == "INTERNAL_SILENT_SWALLOW")
assert ss == 0, f"expected ai_client SS=0 after Phase 11, got {ss}"
def test_phase11_ai_client_unclear_count_zero():
"""After Phase 11: ai_client UNCLEAR count is 0."""
import json
import subprocess
r = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py",
"--include-baseline", "--json"],
capture_output=True, text=True
)
data = json.loads(r.stdout)
files = {f["filename"]: f for f in data["files"]}
ai = files["src\\ai_client.py"]
unclear = sum(1 for x in ai["findings"] if x["category"] == "UNCLEAR")
assert unclear == 0, f"expected ai_client UNCLEAR=0 after Phase 11, got {unclear}"
def test_phase11_all_helpers_exist():
"""All 7 new _result helpers must exist on ai_client."""
import src.ai_client
expected = [
"_try_warm_sdk_result",
"_set_tool_preset_result",
"_set_bias_profile_result",
"_extract_gemini_thoughts_result",
"_list_minimax_models_result",
"_count_gemini_tokens_for_stats_result",
]
for name in expected:
assert hasattr(src.ai_client, name), f"{name} helper missing"
def test_phase11_legacy_functions_preserved():
"""All legacy functions must still be callable."""
import src.ai_client
legacy = [
"_classify_anthropic_error",
"_classify_gemini_error",
"cleanup",
"reset_session",
"set_tool_preset",
"set_bias_profile",
"_extract_gemini_thoughts",
"_list_minimax_models",
"get_token_stats",
]
for name in legacy:
assert hasattr(src.ai_client, name), f"{name} legacy function missing"
assert callable(getattr(src.ai_client, name)), f"{name} not callable"