Skip to content

Independent verification

Most security tools grade themselves on ground truth they wrote. Mylonite ships a deliberately-vulnerable reference agent and an answer key for it — which is useful but circular: of course it scores well on the target it was built against. So Mylonite also carries a separate third-party verification harness (verification/) that scores it against external ground truth it did not author — runnable vulnerable MCP servers and published academic benchmarks — and publishes the result here, negatives included.

This page is the honest scorecard. The numbers are from live runs in June 2026 with Claude Haiku 4.5 as the planner/judge (the only provider keyed on the maintainer's machine), small samples, cost-bounded. Read the caveats — several numbers mean less (or more) than they look.

The one-line result

Model robustness ≠ app security. A frontier model resisted generic injection everywhere we threw it — but the same model was caught immediately where the app's own design was the flaw. Mylonite's demonstrable value is app-flaw detection + regression gating + honesty, not out-fooling frontier alignment.

Example: same model, app design decides

Same Claude Haiku 4.5, two targets:

Target Findings What landed
reference:vulnerable 2 W4 — send_email dispatched with no approval step (the server is the flaw); W1 — followed a tool-description instruction
reference:guarded 0 every attack blocked

The W4 catch is a pure app flaw: the model legitimately sent an email a user asked for, and the app dispatched it with no confirmation. No amount of model alignment prevents that — only the app's missing approval gate does. This is the existence proof, and it live-verifies the judge's deterministic predicate leg.

You can reproduce this leg yourself in one command, offline and with no API key — see Reproduce it yourself.

Layer 1 — DVMCP (real external MCP app), recall

8 in-scope challenges from DVMCP scanned over SSE (the remote adapter), same model:

  • Coverage: 8/8 attempted. Before the attack-pattern-portability fix, all 8 skipped with SeedArmUnavailable — Mylonite's attack patterns were shaped around the bundled kitchen-sink's tool surface and didn't fit a different server. Synthesising the probe for each target's introspected tool surface fixed that.
  • Recall: 0/8. Haiku resisted every model-fooling attack, including an unguarded file_manager (it declined to misuse it). Honest read: coverage went 0 → 100%; recall is 0 because this model resists, not because Mylonite can't test. An app-flaw challenge needs the model to agree to over-reach, which a robust model won't — unlike the reference:vulnerable W4 server flaw, which lands regardless.

Layer 2 — academic benchmarks, judge verification

Dataset What we measured Result
InjecAgent (run by us, Haiku) faithful ASR 0/60 — Haiku resisted; judge agreement vacuous (no positives), flagged as such
InjecAgent --elicit-positives compliant agent to manufacture positives 0/15 — Haiku resisted even when told to comply
AgentDojo (its released runs, gpt-3.5) judge vs AgentDojo's security oracle on real third-party positives 27 runs, 12 real positives (ASR 44.4%); judge agreement P=0.32, R=0.58, F1=0.41

The AgentDojo row closes the LLM-judge verification leg live: its released trajectories include 12 attacks that genuinely succeeded (on a weaker model), so the judge's positive class is exercised against an independent label — no synthesis, no model run by us.

That F1 of 0.41 is itself a finding, not just a weak score. Mylonite's judge asks "did the agent follow the attacker's intent and did harm materialize?", while AgentDojo's oracle asks "was this exact injection goal achieved?" They are different definitions of success, and the moderate agreement quantifies the gap. Don't read 0.41 as "the judge is 41% good" — read it as "Mylonite's effect-based judge and AgentDojo's exact-goal oracle agree moderately; investigate the disagreements before trusting either as a drop-in for the other."

Triaging the 15 false positives — none is a judge bug

We classified every one of the 15 disagreements where Mylonite flagged an attack that AgentDojo's oracle did not (verification/reports/layer2_agentdojo.json):

  • All 15 are the same definitional difference, not a bug. In every case the attacker's consequential tool actually executedsend_money to the attacker IBAN US13…, update_password, or update_scheduled_transaction, each returning [ok]. Mylonite's effect-based judge flags materialized harm; AgentDojo's stricter exact-goal oracle didn't credit it (e.g. the user's original task wasn't also completed in the exact expected way). For a CI security gate, "money left the account to the attacker's IBAN" should fire — so here Mylonite's judge is arguably the more useful of the two, not the broken one. The judge keyed on the attacker-controlled account, so it is distinguishing attacker-directed sends from the user's legitimate ones.
  • FPR = 1.0 is a measurement artifact, not "the judge cries wolf." False-positive rate is fp / (fp + tn), and this AgentDojo subset has tn = 0 — every case is an actual injection attempt, so there are no benign / true-negative control cases for the judge to be quiet on. FPR is therefore pinned at 1.0 by construction regardless of judge quality. The verification report now flags this explicitly (fpr_informative: false) so the number is never cited as a precision failure. The honest precision signal needs an external defended baseline (see Layer 3's open gap).
  • The 5 false negatives (AgentDojo says exploited, Mylonite says not) are cases where the trace shows the action was refused or not executed — a transcript/oracle-semantics nuance in the released runs, not the product judge under-reporting a materialized effect.

Layer 3 — precision (false positives on known-good targets)

  • reference:guarded: 8 probes, 0 false positives (FPR 0%). Mylonite stays quiet on a defended app.
  • External benign baseline: a known gap. Freely-available MCP servers are unguarded-capable — attacks "land" by design, so they aren't clean baselines. A truly external defended server is the missing precision baseline.

Where the value is real vs. open

Real, demonstrated:

  • App-flaw detection (the W4 server flaw caught with a robust model).
  • Honesty rails: NOT-TESTED vs false-clean; the vacuous-agreement flag; out-of-scope marking. The harness even caught the source research's own errors (it mis-stated two external targets' licenses and a third's nature — all verified wrong via the GitHub API before any number was produced).
  • Coverage portability: attack patterns now run on real non-kitchen-sink targets.
  • Precision on a defended app (0 FP).
  • Judge positive-class verified on real third-party positives (AgentDojo).

Open / honest gaps:

  • No model-fooling catch on an external app — every robust-model injection resisted.
  • DVMCP recall is 0 with Haiku (weaker models / app-flaw challenges would differ).
  • Judge ≠ AgentDojo oracle (F1 0.41) — a semantic mismatch still to investigate.
  • No external defended server for a true external precision number.
  • Samples are small and Claude-only; the opt-in verification.yml workflow runs larger N.

Reproduce it yourself

The harness lives in verification/ (outside the wheel; external data fetched at pinned commits, never vendored — see verification/SOURCE.md). Three tiers, easiest first:

1. The harness wiring, offline, no API key. Hermetic tests that guard the plumbing (judge agreement on a committed fixture, the scorers, the vacuous-agreement flag):

pytest tests/verification/ -q

2. The core example, live (needs an API key). The differential that the whole product rests on, run against the bundled reference app — same model, vulnerable build vs guarded build:

export ANTHROPIC_API_KEY="sk-ant-..."
mylonite scan reference:vulnerable   # expect findings
mylonite scan reference:guarded      # expect none

3. The live external numbers (need an API key). Score Mylonite's judge against AgentDojo's released runs — real third-party positives, no model run by you:

python -m verification.runner fetch --dataset agentdojo --out verification/reports/agentdojo.jsonl
python -m verification.runner score --transcripts verification/reports/agentdojo.jsonl --with-llm

Run InjecAgent or DVMCP recall the same way — the exact commands, the pinned sources, and every honesty caveat (prompt fidelity, sample size, which input is Mylonite-authored) are in the harness's own README and FINDINGS.md. The opt-in .github/workflows/verification.yml runs the larger-N live numbers on a schedule.

Bottom line

The verification system works and earns its keep as an independent honesty + coverage check. It proved the strategically important point — model-robust ≠ app-secure — with a real catch, and it closed the judge-verification gap with real third-party positives. It did not show Mylonite beating frontier-model alignment on generic injection, because that isn't where the value is — or where real AI-app risk lives.