DEV Community

CopperSunDev
CopperSunDev

Posted on • Originally published at coppersun.dev

Why AI Code Needs a Deterministic Gate, Not Just an LLM

An LLM reviewer can read the same file twice and return two different verdicts. BrassCoders, the scanner that catches what AI assistants structurally miss, returns the same findings on the same commit every time. That gap is the whole case for putting a deterministic gate in front of AI-generated code, and a 2025 benchmark backs running the two together rather than picking one.

The question worth answering isn't which is smarter. It's which belongs in CI, where a check has to mean the same thing on every run.

The Determinism Problem

BrassCoders produces identical findings on the same commit across repeated runs; an LLM reviewer samples its output and can flag a bug on one run and miss it on the next. A gate that returns different verdicts on the same code is noise, not a gate.

CI checks earn trust by being repeatable. A failing test points at the same failure every time, so the team learns to act on it. An LLM review that flips between "looks good" and "three issues" on identical input teaches the opposite lesson: ignore it. The value of a deterministic scan is that a green run today means the same thing as a green run tomorrow.

What the Research Actually Found

BrassCoders trades raw recall for exact location and repeatability, and that trade has measurement behind it: a 2025 study of language models versus static analyzers found the LLMs scored higher F1 through recall, yet mislocated findings at the line-and-column level because of tokenization, while deterministic tools point at the exact line.

The benchmark, Large Language Models Versus Static Code Analysis Tools by Gnieciak and Szandala, ran three LLMs against three static analyzers on 63 real security issues. The language models led on F1 (roughly 0.75–0.80 against 0.26–0.55 for the static tools), driven by recall. The cost showed up in precision and in localization: the models flagged more false positives and could not reliably say where the problem was. A finding you can't locate is a finding a developer has to re-derive by hand.

The Hybrid Pattern The Papers Recommend

BrassCoders is built for the hybrid the research points to: a deterministic scanner for high-assurance verification, feeding a language model for context-aware triage. It emits a YAML file that Claude Code or Cursor reads and acts on.

The same benchmark's authors recommend using LLMs "early in development for broad, context-aware triage, while reserving deterministic rule-based scanners for high-assurance verification." A separate 2025 paper, ZeroFalse, takes the pairing further: it feeds static-analyzer output to an LLM for adjudication and reports F1 scores of 0.912 on the OWASP Java Benchmark and 0.955 on the OpenVuln dataset, with precision and recall above 90%. The pattern in both: deterministic detection first, model judgment second. That is exactly the BrassCoders-to-Claude handoff.

Reviewing AI Code Without Sending It to an API

BrassCoders runs offline: brasscoders --offline scan makes zero outbound network calls and sends zero bytes off the machine, while an LLM reviewer sends your full source to an external API. For any codebase under data-handling rules, the deterministic path is the one that can run on every commit.

GitHub's own guidance, Review AI-generated code, tells developers to "always run automated tests and static analysis tools first" and to "apply CodeQL or similar scanners." The deterministic gate is the part that runs locally, in CI, on every push, for free. The model review is the part you reach for when you want a second read on intent. Run both, in that order.

pip install brasscoders
brasscoders --offline scan /path/to/your/project
Enter fullscreen mode Exit fullscreen mode

Top comments (0)