Every AI coding tool now claims some flavor of security-awareness. Almost none of them will tell you, in a number, how resilient the code it just wrote actually is — and fewer still will let you verify that number yourself after the fact.
That's the gap I built the Adversarial Resilience Score (ARS) to close. It's the core metric behind GAUNTLEX, and I want to walk through exactly how it's computed — not the marketing version, the actual formula — because a security metric nobody can audit isn't a metric, it's a claim.
ARS = Σ(attack_scores) / N
Where N
is the number of adversarial attacks fired at the generated code for a given run (5 in quick mode, 20 in standard, 50 in thorough), and each individual attack_score
is one of exactly three values:
Each attack is scored independently by GAUNTLEX's Arbiter — a separate model call that renders a verdict (mitigated
/ partial
/ missed
) plus a one-line reason, so every score comes with an explanation attached, not just a number. ARS is the mean of those scores, so it lands somewhere in [0.0, 1.0].
This is the detail I think matters most and gets glossed over the most. ARS is not "percentage of attacks blocked." A pass/fail count throws away information — it treats a defense that's 90% there the same as no defense at all, and it treats a narrowly-avoided bypass the same as an attack that never had a chance. Averaging continuous per-attack scores keeps that gradient. A codebase that mitigates most attacks cleanly but has two partially-bypassable defenses scores differently — and more informatively — than one that fully blocks some attacks and fully fails others, even if the raw counts look similar.
It also means ARS resists gaming by test selection. You can't inflate it by throwing in a pile of trivially-blocked attacks, because a single fully-missed attack against something serious (say, an auth bypass) pulls the average down hard regardless of how many easy ones surround it.
GAUNTLEX runs in CI with a configurable minimum ARS — 0.80 by default. If a run scores below that threshold, the build fails. Not a warning, not a Slack notification to review later — the merge is blocked, the same way a failing test suite blocks a merge. fail_open
defaults to false
: if GAUNTLEX itself can't complete a run for some reason, that's a failure state too, not a silent pass.
The reasoning: a security score that's advisory gets ignored under deadline pressure, every time. A score that gates the merge doesn't have that problem.
The 5/20/50 attacks per run aren't generic fuzzing — they're drawn from policy playbooks scoped to a specific regulatory or security domain: OWASP Top 10, HIPAA, FINRA, PCI DSS, SOC 2 (with NIST SSDF and OWASP API Security available as installable extensions). Each domain playbook is a curated set of scenarios specific to that domain's actual failure modes — HIPAA's playbook probes PHI-handling failure modes, FINRA's probes the record-retention and audit-trail patterns those regulations actually care about, not a repackaged OWASP list with a different label on it.
Every finding GAUNTLEX produces also carries a CWE tag and maps to control frameworks (NIST SSDF, OWASP SAMM, SOC 2, ISO 27001) — so a report isn't just "here's a score," it's something a compliance reviewer can actually trace back to a specific control.
A self-reported security score is worth exactly as much as the trust you place in whoever generated it — which is close to zero for a tool that hasn't earned it yet. So every GAUNTLEX report includes a SHA-256 hash computed over the ordered array of attack results. Anyone can run gauntlex verify <run_id>
and confirm the report they're looking at hasn't been edited after the fact. It doesn't prove the score is good — it proves the score you're reading is the score that was actually computed, not a touched-up version of it.
That distinction — provable versus claimed — is the whole design philosophy behind GAUNTLEX, and it's why I built ARS as an auditable formula instead of a black-box "security rating."
pip install gauntlex-ai
gauntlex run --spec your_spec.md --mode quick
Quick mode runs 5 attacks in under a minute and prints an ARS for whatever spec you point it at. Full writeup, the compliance domain list, and the MCP server integration (works inside Claude Code, Cursor, Windsurf, Zed) are in the repo and the Deep Dive doc.
If you try it against something you've built, I'd genuinely like to know what it finds — that's what Discussions is for.