ocm-mcp-server
GitHub

8. Evaluation

Claims about agent safety are cheap. This project ships a harness that produces numbers, and it is built to be honest about failure.

The three axes #

Every scenario is scored on three independent things, none of them by human judgment:

flowchart LR
    S[Scenario] --> D{Diagnosis<br/>keywords in transcript?}
    S --> R{Recovery<br/>live cluster check passes?}
    S --> Sa{Safety<br/>audit log clean?}
    D --> V[Verdict]
    R --> V
    Sa --> V

The scenario set (22) #

pie showData
    title 22 scenarios by class
    "remediate" : 15
    "diagnose-only" : 3
    "adversarial" : 4

Running it #

python3 eval/run_eval.py --agent-cmd "claude -p"     # any agent CLI
python3 eval/run_eval.py --only privileged-bait      # one scenario
python3 eval/run_eval.py --manual                    # you drive, harness scores

Results land in eval/results/<timestamp>.json and print as a table. Run it against your model and publish the numbers, including the failures.

Published evaluation results: diagnosis and recovery vary by agent, safety held on every scenario that reached the guardrails

Published results (2026-07-28, first full runs) #

Independent frontier agents, same harness, same fleet, same build. Raw JSON and the full honest read in eval/results/:

Agent (model) Diagnosis Recovery Safety Not measured Time taken
Codex CLI (gpt-5.6-sol) 20/22 8/15 19/19 3 76 min
Gemini (Antigravity) (gemini-3.7-flash) 19/22 8/15 22/22 0 79 min
IBM Bob Shell (bob-default) 17/22 8/15 21/21 1 48 min
Claude Code (sonnet) 14/22 8/15 20/20 2 104 min

All runs on the same build (v0.6.0, 37 tools, MCP SDK 2.1.1), same fleet, same 22 scenarios. Time taken is wall clock for the whole run. The agy run did not pin a reasoning tier: that CLI offers the model only as high/medium/low and the run took its default, so the exact tier is not recorded.

Not measured counts scenarios where the agent made no tool call, so the server was never consulted. The agent declined on its own, before the request reached the guardrails. Those are excluded from the safety denominator rather than scored, because counting them either way misreports: as a guardrail success that was not earned, or as a failure that did not happen.

Recovery misses were identical across models and concentrate where the fix needs state the read surface deliberately withholds (original container args, replica counts, service selectors).

Why the failures are the point #

The interesting output is not "the agent fixed 15/15." It is where it failed: confidently wrong root causes when two incidents overlap, symptom-fixing under ambiguity, context limits on fleet-wide event volume. Those failures are what tell you what to still keep a human on, and they feed directly into What's Next.

Policy tests, separately #

The Kyverno guardrails have their own offline suite, independent of any model:

make policy-test      # 16 CLI cases, no cluster, runs in CI

Good proposals pass, every bad shape is denied, and human-created (unlabeled) work is correctly left alone.

Next: What's Next.