Skip to content
CodeAuditAgent
All articles

Two Engines, One Audit

Why a second AI model reading the same code changes what a security audit finds, and how two reports are merged into one without doubling the noise.

· 5 min read · Lina Source LLC

Ask two experienced reviewers to read the same pull request and you get two different lists. One notices that the identifier in the URL is never checked against the session; the other notices that the retry loop keeps a database connection open on every failure. Neither is wrong, and neither is complete. Language models behave the same way, for the same reason: what a reviewer notices depends on what it has seen before.

Agreement is a signal

A single model tells you how confident it is. That number is worth something, but it is self-reported: the model is grading its own homework. When two models trained by different labs, on different data, with different failure modes, independently land on the same weakness in the same file, that agreement is evidence from outside the model. It is the closest thing an automated review has to a second opinion.

The inverse matters as much. A finding only one engine reports is not automatically wrong, and dropping it would throw away exactly the bugs a single reviewer is good at spotting. It should be reported and attributed, so you can weigh it yourself.

Where one engine goes quiet

In practice the two engines diverge most on the bug classes that need reasoning rather than pattern matching:

  • Logic flaws: a discount applied twice, a state machine that accepts a refund after a refund, an ownership check that runs on the wrong object.
  • Framework-specific authorization: middleware that protects a route group but not the API handler mounted beside it.
  • Resource and memory leaks: listeners, timers and connections that are opened per request and released only on the happy path.
  • Prompt injection hidden in comments or fixtures, which reads as harmless text unless the reviewer is looking for it.

How two reports become one

Merging is where a second engine either pays for itself or doubles your noise. The rules we settled on:

  • Findings are matched on what identifies a bug, not on wording: its CWE class and the file it lives in.
  • A match is reported once, with the stricter of the two severities, because the safer reading is the one worth acting on.
  • The write-up kept is the one a developer can act on: the longer evidence, the concrete patch, the ordered fix steps.
  • A corroborated finding is raised to high confidence and labelled with both engines.
  • A finding only one engine saw is kept, marked with the engine that found it.

Both engines read the same source at the same time, so the audit does not take twice as long; it costs twice as much to run, which is why it belongs to the Pro plan. If the second engine is unavailable or returns something unusable, the audit completes on the first one alone rather than failing.

None of this makes a report true. Two engines can agree and both be wrong, and the evidence quoted under every finding exists so you can check rather than trust. What corroboration buys you is an ordering: when a hundred findings arrive and an afternoon is what you have, start with the ones two independent reviewers both saw.