FALCON

Secure Agentic Coding through
Counterexample‑Grounded Feedback

Tue Le1 Anh Nguyen Hoang1 Gabriel Sasseville2,3 Doseok Jang2,3 Pierre-Luc Bacon2,3 Nghi D. Q. Bui4,†
1Quantum AI & Cyber Security Institute (QACI), FPT Corporation 2Mila – Quebec Artificial Intelligence Institute 3Université de Montréal 4Google
†Work done while at FPT.

The attacker-verifier plugin running /secure-code-generation in Claude Code, animated from a recorded run. Claude writes an endpoint on top of an existing helper. The attacker's probe reads a file outside the reports folder through a symbolic link, the verifier judges that execution trace insecure (CWE-59), Claude fixes the code, and the second turn finds no violation.

Abstract

As coding models and agent harnesses become more capable, reliable security verification is becoming a central bottleneck. Improving secure code generation requires a signal whose reported progress remains aligned with actual program behavior under optimization; otherwise, an optimizer can improve the signal's verdict without removing the underlying vulnerability. Existing model-based approaches require models to either infer program behavior from source code or specify correct outcomes for adversarial tests, placing substantial reasoning demands on the security signal. We introduce FALCON, a counterexample-grounded verification framework that separates attack exploration from behavioral verification and connects them through execution traces of the program under test. In test-time repair, FALCON yields substantially stronger held-out functional-security gains than alternative security signals across secure code generation benchmarks, while preserving or improving functionality. As an RL reward, FALCON also outperforms static-analysis and learned rewards on held-out functional-security, even when all policies successfully optimize their respective training rewards. Combining FALCON with either proxy reward further improves held-out performance, suggesting that execution-grounded feedback can mitigate reward overoptimization while preserving useful guidance from existing security signals.

How FALCON works

Prior approaches ask a model to judge source code or to write tests with expected outcomes; FALCON separates exploration from verification through execution evidence.
A judge that reads source code has to infer how the program behaves, and a model that writes security tests also has to decide the correct output. FALCON gives each model a narrower job and connects them through execution.
  1. Targets. The functions, methods, and classes the change touches are selected for attack; test files are excluded.
  2. Attack. An attacker writes deterministic proof-of-concept probes that call each target with adversarial inputs or a prepared environment. A probe records what happened and never states the expected result.
  3. Faithfulness. A probe is rejected if it redefines or patches the target, or reports evidence it produced itself, and discarded if its observations cannot be tied to the target at runtime.
  4. Execution. Each admitted probe runs alone in a sandbox, under a tracer that records the target's calls, return values, exceptions, and side effects.
  5. Verification. Deterministic checks decide traces with clear runtime evidence; a judge model reads the remaining traces, never the source, and decides whether the observed behavior is a violation.
  6. Feedback. Code is insecure if any admitted probe shows a violation. Each violation goes back to the coding agent as a counterexample: the probe, its trace, and the reason.
Overview of FALCON: coding agent, attacker, faithfulness check, sandboxed execution, verifier, and feedback.
The attacker generates PoC probes for code produced by the coding agent. The faithfulness check rejects probes that shadow the target or fabricate the apparent violation. Admitted probes run in a sandbox, and the verifier evaluates their traces with a crash oracle, deterministic CWE detectors, and an LLM trace judge for the cases those leave unresolved.

Results

Func-Sec@1 counts a task only when both the benchmark's functional tests and its security tests pass; those tests are never shown to the attacker, the verifier, or the coding model.

Reported progress versus held-out security

Repair on CWEval with four security signals: held-out Func-Sec@1 per round, the improvement each signal reports, and reported versus held-out improvement.
GPT-5.4-mini repaired its CWEval solutions for five rounds against four security signals. Every signal reported progress on its own verdicts, but only part of it reached the held-out tests: FALCON raised Func-Sec@1 by 25.2 points (61.3 to 86.6), CodeQL by 6.7, an LLM judge by 0.0, and attacker-written tests lowered it by 1.7.

Test-time repair

Func-Sec@1 on SecCodeBench-V2 before and after repair with FALCON.
Func-Sec@1 on CWEval before and after repair with FALCON.

Up to five rounds of repair, with the attacker and the judge on the same model as the coder (starred). Func-Sec@1 rises by 22.5 to 24.0 points on SecCodeBench-V2 and by 24.4 to 25.2 points on CWEval. GPT-5.4-nano goes from 40.6% to 64.3% and from 52.9% to 77.3%, close to or above Claude Opus 4.8 without repair.

Coding agents on SusVibes

Three harnesses (SWE-agent, Claude Code, and OpenCode) edit real Python repositories in SusVibes, 186 tasks across 77 CWEs. Before a patch is accepted, FALCON attacks the changed code and returns any violation to the agent, for at most five checks. Values are averaged over the three harnesses.

ModelFuncPassSecPassFunc-TestRateSec-TestRate
GPT-5.4-mini44.0912.3674.0169.76
+ FALCON46.59+2.5017.20+4.8476.24+2.2372.55+2.79
GPT-5.468.8220.2581.6577.55
+ FALCON70.97+2.1525.27+5.0283.12+1.4779.35+1.80
GPT-5.6-luna62.5419.0080.9977.78
+ FALCON63.62+1.0822.22+3.2281.47+0.4879.36+1.58
DeepSeek-V4-Pro (08-13)81.9020.7983.8779.92
+ FALCON82.61+0.7124.91+4.1284.68+0.8181.59+1.67

Reinforcement learning

GRPO training reward, held-out Func-Sec@1, and KL for six security rewards on Qwen2.5-Coder-3B and 7B.
GRPO on SecCodePLT+ with Qwen2.5-Coder 3B and 7B, six security rewards, and the same functionality reward. Every policy raises its own training reward, but the static-analysis (REAL) and learned (SecCodePRM) rewards transfer much less to held-out Func-Sec@1, and at 3B it falls while their reward keeps rising. Adding the FALCON reward to either one gives the best held-out results (57.25 at 3B with REAL, 77.26 at 7B with SecCodePRM); combining REAL with SecCodePRM does not help.

Verifier accuracy and cost

Agreement with CWEval's labeled security tests, averaged over code from three models, with GPT-5.2 as the judge. Judging one observed execution is easier than judging all the executions a piece of code allows, and it is cheaper.

VerifierAccuracyFalse positivesFalse negativesCost per example
Deterministic checks only97.54%2.33%2.62%$0
Deterministic checks + trace judge98.58%2.73%0.20%$0.085
Trace judge on every trace87.99%23.92%0.18%$0.634
Judge reading the source code61.16%50.43%28.05%$1.227
CodeQL56.68%17.95%66.42%$0

Use it in Claude Code

The repository includes FALCON as a Claude Code plugin named attacker-verifier. Install it from the Claude Code prompt:

/plugin marketplace add FSoft-AI4Code/FALCON
/plugin install attacker-verifier@attacker-verifier

Then audit existing code, or write new code and harden it:

/check-code-security src/storage.py
/secure-code-generation add an endpoint that serves report files by name

/check-code-security attacks the code you name and writes a report with each violation's probe, trace, and reason. /secure-code-generation implements the request, then runs attack, verify, and repair turns until a turn finds nothing or the turn budget runs out. While a pass runs, a band above the prompt shows the stage in progress and who is doing it: Claude, the attacker, the sandbox, or the verifier. The attacker and the verifier can run in your session or as separate subagents on a model you choose. Only Python is attacked, and a clean result means the probes that ran found nothing, not that the code is proven safe. See the README for configuration, the sandbox options, and the code for the paper's experiments.

BibTeX

@misc{le2026falcon,
  title  = {Secure Agentic Coding through Counterexample-Grounded Feedback},
  author = {Le, Tue and Nguyen Hoang, Anh and Sasseville, Gabriel and Jang, Doseok
            and Bacon, Pierre-Luc and Bui, Nghi D. Q.},
  year   = {2026},
  url    = {https://github.com/FSoft-AI4Code/FALCON}
}