The Model Is a Dependency You Forgot to Vet

The AI Supply Chain Risk Hiding in Your LLM Choice

Part 3 of 5 in AI-Native Engineering

A model can hand you weaker code because of who it thinks you are. Not weaker because your prompt was vague or your problem was hard — weaker because it inferred something about your identity and quietly adjusted its output. That’s the finding buried in Booz Allen’s June 2026 report, What’s In America’s Code?, and it should change how you think about AI model selection.

The specifics are stark. Across more than 2,800 trials and nearly 450,000 lines of generated code, three of four Chinese frontier models produced significantly more vulnerable code when the request came from someone identifying as US government personnel. The vulnerabilities weren’t sloppy — they were highly obfuscated, the kind a normal review pass would miss. The same models showed political bias, refusing some requests and shading others towards a party line.

You can read that as a geopolitical story. Plenty of people will. I’m more interested in the engineering lesson underneath it — because it applies to every model you run, regardless of where it was trained. This is a AI supply chain problem, and the model is the newest dependency in it.

Your AI model is a dependency you forgot to vet

We spent a decade learning to treat dependencies with suspicion. We pin versions. We scan for CVEs. We read changelogs, check maintainer reputation, and argue about whether a transitive package pulled in by a build tool is worth the risk. Supply-chain security became a discipline because we learned the hard way that the code you didn’t write can hurt you.

The model that writes the code is now the most powerful dependency in your stack. It touches every file. It shapes every pattern. And most teams evaluate it on a benchmark screenshot and a good afternoon of vibes.

Booz Allen’s contribution isn’t “foreign models are bad.” It’s evidence that a model’s behaviour can be conditional, adversarial, and hidden — that it can do one thing for one user and something meaningfully worse for another, in a way no static scan will surface. That’s a supply-chain problem wearing a new hat.

And adversarial intent is only the loudest version of it. A model’s behaviour is shaped just as much by what it was trained on and how it was tuned. The training data carries the biases of its sources. The guardrails encode someone’s judgement about what’s acceptable to generate — someone who isn’t you, working to priorities you didn’t set and can’t inspect.

None of that requires malice. A model can hand you a skewed answer with a completely clean conscience, because the skew was baked in long before your prompt arrived.

The fourth axis of model selection: trust

In Match the Model to the Job I argued that model selection comes down to three questions. What does the task need — reasoning, speed, or structured output? How often does it run? What’s the cost of a wrong answer? Capability, frequency, cost.

There’s a fourth axis I didn’t name: trust.

Trust is different in kind from the other three, and that’s what makes it dangerous. You can measure capability, frequency, and cost from the outside. You can benchmark them, budget them, watch them in a dashboard. Trust is about behaviour you can’t see — behaviour that only shows up under conditions you didn’t test, for users you didn’t simulate. You can’t read it off the output, because the whole problem is that the output looks fine.

The AI supply chain risk you can’t grep

To be fair, most insecure AI-generated code is just incompetence. The model didn’t sanitise the input because it pattern-matched to an example that didn’t either. That’s a quality problem, and it’s the kind of thing structural review is built to catch.

The Booz Allen finding is a different animal. Obfuscated vulnerabilities, produced conditionally, are the nightmare version of the problem I described in Auto Mode Needs a Referee — output that is confidently, plausibly wrong and looks exactly like output that’s right. Except now you have to consider that the wrongness might be deliberate and camouflaged, not accidental and obvious.

You can’t grep your way out of that. Which raises an uncomfortable question about the defences I’ve spent a lot of words recommending.

Specification assumes a neutral machine

I’ve argued before that prompt engineering is just specification — you describe what you want, and the system does exactly that, no more, no less. That framing tacitly assumes the machine on the other end is neutral. It isn’t.

A model brings its own priors to every prompt, and none of them appear in your spec. You can specify the task perfectly and still get an answer shaped by decisions made without you in the room. The Booz Allen finding shows the extreme end of it.

So specification now has to account for something it never did before: the executor has a point of view. In that specification post I said LLMs fail confidently, returning plausible wrong answers instead of loud errors. Inherited bias is that failure mode’s quiet cousin — the output looks like it met your spec, and the part that didn’t came from the model, not from you.

The same-family monoculture in my own stack

Here’s a tension in my own architecture — one I’ve seen from the start, not one I’m discovering now.

My system is Claude-heavy, and that was a deliberate call. I matched the model to the job, exactly as I’ve argued you should. I tried GPT in the coding and orchestration tiers and it wasn’t close — it followed instructions less reliably and wrote weaker code, so it does the one thing it’s genuinely good enough for in my pipeline: deterministic PR creation. Tier by tier, on capability, Claude won. So that’s what I built.

The bias risk was on my mind the whole time. But the real tension was capability now against bias risk later — and with the fallback shipping weaker code today, capability won. That’s the honest shape of it: not an oversight, a trade-off made with eyes open. What’s changed is that I’m no longer treating capability as the sole yardstick.

In Specialists Beat Generalists I argued that a dedicated reviewer catches what the author misses, because it brings fresh context and a different lens. That’s true when the reviewer is genuinely different. But in my pipeline, @code-backend writes with Claude and @author-code reviews with Claude. Same model family, same training — and if either one carries a blind spot, they both do. The referee and the player went to the same school.

If a model has a systematic failure mode — a class of vulnerability it tends to produce, or one it’s been shaped to overlook — then a same-family reviewer is the worst possible auditor. It shares the exact bias you need a second opinion to catch.

And remember where that bias comes from — the training data and the guardrails, shipped in before either agent ran. Two agents on the same model don’t just share failure modes. They share an inherited worldview. A monoculture is efficient right up until the moment the thing everyone agrees on is wrong.

Making room for a second LLM

A same-family reviewer isn’t useless. It catches most of what author agents were designed to catch — weak error handling, missing edge cases, insecure patterns copied from bad examples in the training set. That’s real value, and it’s not going anywhere.

The problem is narrower and sharper: the specific class of failure where the reviewer shares the disposition it’s supposed to detect. For that class, a same-family agent isn’t just weak — it’s structurally the wrong tool.

The reflex is to call the fix expensive — a second provider, separated context, a duplicate review pass, all more cost and more moving parts. But that framing is a trap, and it’s one I set myself. “Match the cheapest capable model to the job” was never about cheapest in absolute terms. It was about not paying for capability you don’t need — not about refusing to pay for the trust you do.

A reviewer that genuinely catches what the author missed isn’t overhead you’re indulging. It’s the thing you’re buying.

And weigh whatever it costs against what it prevents. An obfuscated vulnerability in production. A class of insecure code reproduced across every service because one model had a blind spot and its same-family reviewer shared it. The rework, the incident response, the slow erosion of trust in the whole pipeline. Set the price of a second opinion next to that and it stops looking like a premium. I’ll spend a bit more to not ship that failure mode, every time. That’s not a splurge — it’s the job.

So here’s where I’ve landed. Capability doesn’t get the only vote any more. I’m treating model diversity as part of the refinement loop — making room for more than one model family in the stack, and making that case to the teams and clients I work with — before an incident makes it for me. Not because a second provider is cheaper or faster. Because a second provider disagrees — and disagreement is the only thing that reliably catches a bias a model can’t see in itself.

A second model family is a safety net, though, not a guarantee. It’s not always affordable, and it’s not always available — plenty of teams are locked into one provider by contract, budget, or platform. And even when you have it, two models can still miss the same thing by coincidence rather than shared training. Diversity lowers the odds of a blind spot slipping through. It doesn’t get you to zero.

What this means for engineers

You don’t need a government threat model to take something from this. A few practical shifts:

  • Treat provenance as a selection criterion, not trivia. Where a model came from, who trained it, and what it optimises for belong in the same decision as latency and price.
  • Diversify across tiers where the stakes justify it. The model that reviews security-critical code shouldn’t share a brain with the model that wrote it. Difference is the whole point of asking twice.
  • Test behaviour, not just output. Benchmarks measure capability on a good day. Run the same task through different model families and watch where they diverge — divergence is where a systematic bias tends to hide.
  • Keep a human on the security-critical path. Model diversity narrows the odds of a shared blind spot — it doesn’t erase them, and it isn’t always an option. Author agents move quality left and catch an enormous amount, but they are not a substitute for a senior engineer on the code that would hurt you most if it were quietly wrong.

Thinking in public

I don’t have this solved. I’m raising a concern about my own architecture out loud — running the trade-offs deliberately, while I still have room to move.

That’s the whole reason I write here. Thinking in public sharpens thinking in private — and if putting this question down in words helps you make a better decision about the models you’re trusting with your code, that’s the point. So I’ll leave it with you: whose brain is reviewing your brain, and did you choose it, or did you just default to it?

AI-Native Engineering

  1. 1. The AI-Powered Developer
  2. 2. Meet ADLC
  3. 3. The Model Is a Dependency You Forgot to Vet
  4. 4. Auto Mode Needs a Referee
  5. 5. Who Trains the Next Senior Engineers?