Files
codex-app-server/cloud/tests/test_audit_fixes.py
T
host f9a77577c5 fix: audit findings (fallback dead code, silent fallback, registry re-parse, shadow sort, gateway capability)
- RoutingPolicy.fallback_models: move the cleaning loop into
  __init__ (it was unreachable after tier_mode's return, so the
  attribute never existed); still parsed but not applied.
- Capability fallback: RoutingDecision gains capability_fallback;
  the worker audits worker_capability_fallback when it fires, so
  a tier-model rejection followed by a worker-default fallback
  is no longer invisible (source stays worker_default, no
  model_routing event, so shadow samples are unaffected).
- Registry: resolve_registry_agent checks skills directly
  against the loaded definition instead of re-parsing a
  hand-built dict, so future fields cannot be silently dropped
  the way tool_approvals was in v9.
- Shadow: evaluate_shadow sorts rows earliest-first by
  created_at (id tiebreak) when timestamps are present, so
  dedup no longer depends on caller row order; the server
  path (which strips created_at) is unchanged.
- Gateway: when sub2api fills the default model, the worker
  now checks it against the tier's capability requirements
  with the same mode semantics as v8 -- shadow only audits,
  active fails fast with worker_capability_gate_rejected and
  never calls the runner. No worker-default fallback here:
  the gateway model is the task's gateway model, falling back
  to a worker default would run against the wrong gateway.
2026-11-04 18:02:21 +00:00

234 lines
8.7 KiB
Python

"""Audit fixes: fallback_models storage, capability fallback audit,
registry skill check without re-parse, shadow dedup sorting, and
gateway-model capability check.
Run: python3 -m unittest discover -s cloud/tests -p "test_audit_fixes.py" -v
"""
import os
import sqlite3
import sys
import tempfile
import time
import unittest
from types import SimpleNamespace
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
from cloud.agent_def import default_agents_dir, resolve_registry_agent
from cloud.models import decide_routing, parse_routing_policy
from cloud.routing_shadow import evaluate_shadow
from cloud.server import init_db
from cloud.worker import Worker
class FallbackModelsTestCase(unittest.TestCase):
def test_policy_stores_fallback_models(self):
policy = parse_routing_policy({
"mode": "shadow",
"tiers": {"default": "m1"},
"fallback_models": ["m2", "m2", " ", "m3"],
})
# Previously unreachable dead code: the attribute did
# not exist at all on a RoutingPolicy.
self.assertEqual(policy.fallback_models, ["m2", "m3"])
class CapabilityFallbackAuditTestCase(unittest.TestCase):
def test_decision_flags_capability_fallback(self):
policy = parse_routing_policy({
"mode": "active",
"tiers": {"plan": {"model": "no-tools",
"requires": {"tool_calling": True}}},
"model_capabilities": {
"no-tools": {"tool_calling": False},
"worker-model": {"tool_calling": True},
},
})
decision = decide_routing(
{"id": "t1", "plan": True}, "worker-model", policy=policy)
self.assertEqual(decision.source, "worker_default")
self.assertTrue(decision.capability_fallback)
self.assertEqual(decision.chosen_model, "worker-model")
def test_normal_worker_default_is_not_flagged(self):
policy = parse_routing_policy({
"mode": "active", "tiers": {"plan": "plan-model"}})
decision = decide_routing(
{"id": "t1", "plan": True}, "worker-model", policy=policy)
self.assertFalse(decision.capability_fallback)
class CapabilityFallbackWorkerAuditTestCase(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.db_path = os.path.join(self.tmp.name, "control.db")
init_db(self.db_path)
self.calls = []
def tearDown(self):
self.tmp.cleanup()
def test_fallback_is_audited(self):
_insert_task(self.db_path, "F1")
def recording(cmd):
self.calls.append(list(cmd))
return _completed_runner(cmd)
worker = Worker(
self.db_path, "/fake/host.py", runner=recording,
env={"XCM_API_KEY": "test-placeholder"},
model="worker-model", model_explicit=False,
routing_policy={
"mode": "active",
"tiers": {"default": {"model": "no-tools",
"requires": {"tool_calling": True}}},
"model_capabilities": {
"no-tools": {"tool_calling": False},
"worker-model": {"tool_calling": True},
},
})
result = worker.run_one()
self.assertEqual(result["status"], "completed")
from cloud.auth import AuthStore
store = AuthStore(self.db_path)
try:
entries = [e for e in store.list_audit("p1")
if e["action"] == "worker_capability_fallback"]
finally:
store.conn.close()
self.assertTrue(entries)
self.assertIn("no-tools", entries[0]["detail"])
class RegistrySkillCheckTestCase(unittest.TestCase):
def test_registry_definition_keeps_all_fields(self):
# The old re-parse dropped any field not copied into
# its hand-built dict; the direct check must return
# the loaded definition unchanged, including
# tool_approvals, and still reject unknown skills.
definition = resolve_registry_agent(
"research-brief-approval", agents_dir=default_agents_dir(),
known_skills=["live-info"])
self.assertEqual(definition.tool_approvals,
{"websearch": "ask"})
self.assertEqual(definition.tools, ["websearch"])
with self.assertRaises(ValueError):
resolve_registry_agent(
"research-brief-approval",
agents_dir=default_agents_dir(),
known_skills=["other-skill"])
class ShadowSortTestCase(unittest.TestCase):
def test_dedup_uses_earliest_row_regardless_of_input_order(self):
rows = [
{"detail": "t1 tier=default source=shadow applied=False"
" suggested=new-model chosen=worker-model",
"created_at": 200, "id": 2},
{"detail": "t1 tier=default source=shadow applied=False"
" suggested=old-model chosen=worker-model",
"created_at": 100, "id": 1},
]
report = evaluate_shadow(
rows, {"t1": {"status": "completed"}}, {})
self.assertEqual(
report["tiers"]["default"]["suggested_models"],
{"old-model": 1})
def _completed_runner(cmd):
if "dispatch" in cmd:
name = cmd[cmd.index("--name") + 1]
else:
name = cmd[cmd.index("--task") + 1]
return SimpleNamespace(
returncode=0,
stdout='{"task": "%s", "status": "completed", "text": "done"}' % name,
stderr="")
def _insert_task(db_path, task_id):
now = time.time()
conn = sqlite3.connect(db_path)
try:
conn.execute(
"INSERT INTO tasks(id, project_id, prompt, status,"
" idempotency_key, depends_on, priority, created_by,"
" created_at, updated_at, last_heartbeat)"
" VALUES(?, 'p1', 'do work', 'queued', NULL, '[]', 0,"
" 'tester', ?, ?, NULL)", (task_id, now, now))
conn.commit()
finally:
conn.close()
class GatewayCapabilityTestCase(unittest.TestCase):
"""Gateway check is exercised through the worker's routing
policy path by stubbing _ensure_gateway: the worker's
run_one gateway step is the only place the sub2api
default model is filled, so the check must live there."""
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.db_path = os.path.join(self.tmp.name, "control.db")
init_db(self.db_path)
self.calls = []
def tearDown(self):
self.tmp.cleanup()
def _worker(self, policy_doc, gateway_model):
def recording(cmd):
self.calls.append(list(cmd))
return _completed_runner(cmd)
worker = Worker(self.db_path, "/fake/host.py",
runner=recording,
env={"XCM_API_KEY": "test-placeholder"},
routing_policy=policy_doc)
# Stub the gateway to behave like sub2api filling a
# default model, without touching real gateway code.
worker._ensure_gateway = lambda task: ("sub2api", {})
worker._sub2api_default_model = lambda env: gateway_model
return worker
def test_active_gateway_incapable_blocks_before_runner(self):
_insert_task(self.db_path, "G1")
worker = self._worker({
"mode": "active",
"tiers": {"default": {"model": "policy-model",
"requires": {"tool_calling": True}}},
"model_capabilities": {
"gateway-model": {"tool_calling": False},
},
}, gateway_model="gateway-model")
result = worker.run_one()
self.assertTrue(result["dispatched"])
self.assertEqual(result["status"], "failed")
self.assertIn("tool_calling", result["error"])
self.assertEqual(self.calls, [])
def test_shadow_gateway_incapable_only_audits(self):
_insert_task(self.db_path, "G2")
worker = self._worker({
"mode": "shadow",
"tiers": {"default": {"model": "policy-model",
"requires": {"tool_calling": True}}},
"model_capabilities": {
"gateway-model": {"tool_calling": False},
},
}, gateway_model="gateway-model")
result = worker.run_one()
self.assertEqual(result["status"], "completed")
from cloud.auth import AuthStore
store = AuthStore(self.db_path)
try:
entries = [e for e in store.list_audit("p1")
if e["action"]
== "worker_capability_gateway_shadow"]
finally:
store.conn.close()
self.assertTrue(entries)