Begin with a result that breaks the obvious intuition.
A frontier model secures a complete, self-contained backend application better than it secures a single function dropped into an existing repository — 53.8% against the application, 39.3% against the function-in-repo. The larger artifact is the safer one. Vulnerability is not scaling with the size of the generated code. It is scaling with something else, and naming that something is the whole architectural point.
The ladder, and what climbs it
Read the benchmarks in order of the unit they generate. At the snippet level, the 2021 baseline found roughly 40% of generated programs carried a weakness. At the function level, current benchmarks show about a 30% drop from “functionally correct” to “functionally correct and secure” — a third of working functions are insecure. At the full-repository, inter-procedural level, where the security of a fix depends on a data path that may cross more than thirty functions, no model exceeds 8% on the joint correct-and-secure measure.
The gap widens as you climb. But it does not widen with raw size, and the application-versus-function inversion is the proof. A self-contained application is large, yet the model authors all of it; the security requirement lives inside the artifact the model controls. A function completed inside a repository is small, yet its security depends on how the surrounding code calls it — context the model only partially sees. The smaller, more connected unit is the harder one. What climbs the ladder is not lines of code. It is the degree to which the security requirement lives outside the unit being generated, in how the pieces compose.
Composition is where the requirement lives
This is the assembly boundary. A function can be correct in isolation and insecure in use, because the property that makes it secure — a sanitized input, an enforced authorization check, a closed side-channel — is a property of the composition, not of the function. The full-application benchmarks make the same point from the other side: a generated app passes its own functional tests and is then exploitable through its exposed interface, where an untrusted user meets the deployed system. Around half of the programs that pass correctness are exploitable at that boundary. The defect was never in a line. It was in the seam.
The agentic “vibe coding” benchmarks sharpen it further. A coding agent building a real repository feature produces functionally passing work about 61% of the time and secure work about 10% of the time — more than 80% of its correct solutions are vulnerable, and the failure surfaces in deployed runtime behavior such as a timing side-channel, not in a static pattern a reviewer would catch reading the diff.
Agents assemble faster; they do not secure the seam
Scaffolding a model into an agent raises how much it can assemble. It does not raise how securely the assembly composes. On the repository benchmark, agentic scaffolding adds about 18 points of correctness but only 14 of security — the agent builds more working code, and the security gap rides along. On the vibe-coding benchmark, the “more than 80% of correct is vulnerable” result is itself an agentic result. More assembly means more boundary, and the boundary is where the defect concentrates. The agent is a faster assembler of the exact thing that fails.
The same signature appears in time as well as in space. Holding the unit fixed and spreading generation across conversational turns drops the correct-and-secure rate 20–27%, and the benchmark’s control isolates the cause: it is the cross-turn dependency, not the added context length, that does the damage. The boundary between turns behaves like the boundary between files. Wherever the work is handed from one piece to the next, security leaks at the handoff.
Why generation-time fixes miss
Across its corpus, Luminity reads controls along one axis: deterministic controls enforce categorically, while probabilistic controls mitigate but degrade under adversarial pressure. A prompt-time security hint is a probabilistic control applied at the moment of generation. The benchmarks show it cannot reach a defect that lives at assembly. Telling the agent which weakness class to avoid does not raise the secure rate — given the true vulnerability category in advance, the vibe-coding secure rate moves by a rounding error and functionality falls. Prompting the inter-procedural benchmark with security guidelines does worse than nothing: it drops correct-and-secure output by causing outright compilation failures. A nudge at the point of generation cannot enforce a property that only exists once the pieces are composed.
Vulnerability in generated code is not a per-line defect rate that scales up with volume. It is an assembly-boundary property, and it concentrates where the security requirement depends on composition the generated unit does not contain.
You cannot review your way to secure agentic output one snippet at a time, because the defect is not in the snippets. Enforcement has to live at the boundary where the requirement emerges — the assembly and protocol layer — not at the point of generation.
