If your CI pipeline runs the functional tests your coding agent wrote alongside its patch, a green checkmark tells you the code does what the spec asked. It tells you almost nothing about whether the code is safe to ship. A new benchmark called DualGauge-Bench measures both properties at once, and the gap between them is wide: across 307 tasks and 10 models, the strongest LLM stayed below 15% joint security-functionality success in every language tested. The practical consequence is that a merge gate for agent-generated code cannot be “tests pass.” It has to be a layered thing: static analysis chosen per vulnerability class, sanitizer-instrumented execution where the language allows it, and targeted human review on short iteration chains, because the two cheapest alternatives (agentic self-refinement and “write secure code” prompts) both fail to close the gap in measured studies.
One caveat up front, because it shapes everything below: DualGauge is a single arXiv preprint with author-reported results, one sample per prompt, in a specification-only setting with no repository context. Treat its numbers as evidence about a failure mode, not as a pass rate for your repo-aware agent.
What DualGauge tests: one specification, two verdicts
DualGauge-Bench is “a language-agnostic benchmark of 307 coding tasks each paired with functional and security tests derived from the same specification.” That last clause is the design decision that matters. The functional tests and the security tests come from the same natural-language spec, so a model cannot pass the security side by doing something other than what was asked. The benchmark grades each generation on two axes independently: does it work, and is it secure.
This mirrors the situation the benchmark is built for: a team hands a spec to a coding agent and gets back a whole feature. There is no starter code, no existing test suite, no linter configuration inherited from the repo. The agent writes from the specification alone, and the benchmark asks the question your merge queue implicitly asks: is this patch both correct and safe?
Most existing evaluation harnesses answer only half of that. Functional pass rates are the currency of coding-benchmark leaderboards, and security, when it appears at all, is usually a separate evaluation on different tasks. DualGauge’s contribution is forcing the two measurements onto the same artifact, which is what makes the divergence visible.
The divergence: working code and safe code are different events
Evaluating 10 representative LLMs across Python, C++, and JavaScript, the DualGauge authors report that even “the strongest model remains below 15% joint security-functionality success in every language.” Functional correctness, they conclude, “substantially overestimates reliable code generation.”
Read that carefully, because it is easy to misquote. The claim is not that models produce broken code most of the time. It is that when you require both properties on the same generation, the joint success rate collapses. A patch can pass every functional test and still carry an injection hole, a missing authorization check, or a memory error, and the functional score will never register it. If your pipeline surfaces only the functional axis, the security axis defaults to whoever reviews the diff after merge.
The authors extend this to agentic workflows directly: “Together, these results suggest that agentic coding is not yet a remedy for secure code generation: multi-turn refinement, tool use, and feedback do not automatically overcome the core challenge of producing code that is both functionally correct and secure.” That is the first misconception to put down. In DualGauge’s specification-only setting, iteration did not reliably buy either axis: two of the three agents failed to outperform a comparable direct model, and Claude Code showed substantially lower functional correctness than its direct-generation counterpart.
Why “write secure code” in the prompt is not a control
The cheapest proposed mitigation is prompt-level: prefix the spec with security instructions and let the same pipeline run. A formal verification study of 3,500 AI-generated code artifacts measured the effect directly and is blunt about the result: “A mean improvement of 4 percentage points under an explicit security prompt is not a safety margin—it is noise.” The same passage tells developers who add “write secure code” to their prompt prefixes not to treat the four-point difference as a mitigation.
Four points is within the range you would expect from sampling variation, and the study’s authors say so. If your current security posture for agent output is a system prompt, you do not have a posture.
Interestingly, prompt strategy is not irrelevant in general, just not as a security control. In a separate evaluation of LLM-generated cryptographic Rust code, prompt strategy significantly influenced outcomes (p=0.002), but in an unhelpful direction: chain-of-thought prompting performed five times worse than zero-shot for compilation success. Prompting moves things; it does not move them reliably toward security.
Gate option 1: static analysis, and where it goes blind
Static analysis is the obvious first layer: it is cheap, deterministic, and already wired into most CI. The measured problem is that coverage is vulnerability-class-specific, and the blind spots are not small.
The cryptographic Rust study generated 240 Rust samples, of which only 56 compiled; CodeQL ran on those compiled samples and found “CodeQL at 0% true positive rate” for cryptographic misuse, which the authors describe as “a previously underexplored limitation of existing tools.” Zero percent is not a weak detector; it is no detector, for that class, in that experiment. Cryptographic misuse is a particularly instructive failure because it rarely breaks functional tests. Code that uses the wrong padding mode or a hardcoded key encrypts and decrypts fine. The functional axis passes, the SAST run passes, and the merge gate reports success on both fronts.
The operational conclusion is not “drop static analysis.” It is that “SAST is running” is not a coverage statement. The audit question is which vulnerability classes your tool actually detects on LLM-generated code, and for classes where detection is unproven, you need a different layer. Choosing the tool per class, rather than treating a single tool’s green run as a gate, is the defensible position.
Gate option 2: sanitizer-instrumented execution
For systems languages, the formal verification study prescribes a concrete runtime layer: “Treat AI-generated C/C++ as unreviewed code requiring explicit security audit” and “Apply -fsanitize=address,undefined to all AI-generated systems code.”
This is worth distinguishing from the functional tests you already run. AddressSanitizer and UndefinedBehaviorSanitizer instrument the binary so that memory errors and undefined behavior become observable failures during execution. A buffer overflow in agent-generated C++ can pass a functional suite that never exercises the overflowing path; the same code under sanitizers fails loudly on the first bad access. The gate changes from “does it produce the right output” to “does it survive execution under instrumentation,” which catches a class of defect that neither functional tests nor pattern-matching static analysis reliably reaches.
The cost is real but bounded: sanitizer builds are slower than uninstrumented ones, a general property of the instrumentation rather than a figure the study measures, and the recommendation is scoped. The study’s advice covers AI-generated C/C++ systems code, not Python glue or JavaScript UI. For those languages, the equivalent layer is fuzzing or property-based testing against the security-relevant inputs, which no study cited here measures, so I would treat it as an inference from the same principle rather than a validated prescription: if the defect class does not surface in functional output, you need execution that instruments for it.
Gate option 3: human review, but aimed
Human review is the layer everyone assumes is the backstop, and the evidence says the assumption is unsafe twice over: review is too slow to cover everything, and untargeted review demonstrably misses the worst defects.
On throughput, the Bugdar paper reports that “a security audit of a new future consisting of 10,000 lines of Move smart contract code took two security engineers 10 days–0.11 lines of code per second, and not all security vulnerabilities were identified.” The same authors claim their tool processes code at least 100x faster; that figure is author-reported with no independent replication, so I would not budget against it. The human number is the durable finding: line-by-line security audit runs at a pace no agent merge queue can wait for, and it still misses things.
On targeting, a study of security-related AI-generated pull requests found that “some AI PRs introduce serious security flaws, such as command injection, yet they still pass review and are merged. In contrast, RQ4 reveals that other contributions are rejected for minor quality issues such as inconsistent style or missing test coverage.” Reviewers are catching what their attention is pointed at, and default attention goes to style and tests, not injection sinks. A companion study of silent AI pull requests adds a skew signal: accepted Claude SPRs raised complexity in 60.00% of cases versus 28.57% for rejected ones, suggesting merge acceptance does not track the risk signals a security reviewer would weight. These are single-study, author-reported percentages, but the direction is consistent with the command-injection result.
So the human layer has to be aimed at what automation cannot see, and it has to be scheduled. On scheduling, an IEEE-ISTAS 2025 study of iterative AI code generation observed 387 distinct vulnerabilities across 40 rounds of iteration, with counts increasing substantially in later iterations, and prescribes a cadence: “Restrict consecutive LLM-only iterations to 3 maximum, as vulnerability counts increase substantially in later iterations. Reset the ‘iteration chain’ after each human review.” The mechanism is intuitive: each unattended refinement round accumulates changes nobody has read, and the agent’s own fixes introduce fresh defects. The cap of 3 is one study’s heuristic, not a measured optimum, but the underlying practice, bounding unattended iteration and resetting after review, follows directly from the accumulation finding.
Assembling the merge gate
None of these studies tests these layers in combination, so the layered gate is a synthesis of complementary single-study results, each layer justified by a measured failure of the alternatives rather than by an end-to-end trial. With that stated plainly:
| Gate layer | What it catches | Measured failure or cost | Evidence |
|---|---|---|---|
| Functional tests (status quo) | Spec conformance | Blind to entire security axis; best model under 15% joint success | DualGauge |
| Prompt-level security instructions | Nothing reliably | 4-point mean effect, characterized as noise | Formal verification study |
| Static analysis | Class-dependent | CodeQL: 0% true positives on crypto misuse across the 56 compiled samples (of 240 generated) | Cryptographic Rust evaluation |
| Sanitizer-instrumented execution | Memory errors, UB in systems code | Prescribed for AI-generated C/C++; the study measures no build-time cost | Formal verification study |
| Untargeted human review | Style and coverage nits | Command injection merged; 0.11 lines/second full audit | AI security PRs, Bugdar |
| Targeted review on bounded iteration chains | The residual classes automation misses | Cadence cap (max 3 LLM-only iterations) is one study’s heuristic | Iterative generation study |
As a checklist for a spec-only agent workflow, the defensible gate looks like this:
- Functional CI stays, but stops being read as a security signal.
- Static analysis runs, with documented coverage per vulnerability class, and known blind classes routed elsewhere.
- AI-generated C/C++ builds and tests run under
-fsanitize=address,undefined. - Consecutive LLM-only iterations are capped (3 is the one evidenced number) and the chain resets after each human review.
- Human security review is targeted at the residual classes: injection sinks, authz logic, cryptographic usage, and anything the static tool is known to miss.
What spec-only, k=1 evidence cannot tell you
The DualGauge authors bound their own claim, and the bound lands exactly on this article’s readers: “Our conclusions about coding agents apply to the specification-only setting alone, where there is no repository context, ground-truth test suite, CI, or human feedback; we do not extend them to repository-level or test-driven workflows.” The main study also drew one sample per prompt (k=1) under fixed models, languages, and prompting conditions, and the results are author-reported without independent replication.
A repo-aware agent that inherits your linters, your existing tests, and your code review culture is operating outside the measured envelope. The sub-15% figure may not transfer in either direction. What does transfer is the measurement design: grade the same artifact on both axes, and count joint success. If you want to know where your own pipeline stands, that is the experiment to run on your own merge history rather than borrowing a benchmark’s percentage. My judgment, given the evidence: adopt the two-axis audit now, because every option a pipeline falls into by default (functional-only CI, prompt-level security instructions, a single static-analysis run, untargeted review) failed on at least one measured class, and calibrate the thresholds on your own agent’s output rather than on any preprint’s numbers, including these.
Frequently Asked Questions
What is the maximum number of consecutive LLM-only iterations recommended before a human review?
Restrict consecutive LLM-only iterations to 3 maximum, as vulnerability counts increase substantially in later iterations. Reset the ‘iteration chain’ after each human review.
Which sanitizers should be applied to AI-generated C/C++ code?
Apply -fsanitize=address,undefined to all AI-generated systems code.

Join the discussion
Share a useful perspective or ask a question about this article.