Every computer you have ever touched is, at its core, a Deterministic Finite Automaton. Feed it the same input, you get the same output. Every time. Without exception. This is not a quirk — it is the bedrock on which all of software engineering is built. We write tests because we expect determinism. We build CI/CD pipelines because we expect determinism. We sleep soundly at 2 AM because, somewhere in a data center, a machine is faithfully executing a function the same way it did a billion times before.
But something is changing. Quietly, irreversibly, we are welding a non-deterministic engine into the deterministic machine. And most codebases are not ready for what happens next.
Two Kinds of Machines
Formal language theory gives us two flavors of finite automata. The Deterministic Finite Automaton (DFA) has exactly one possible transition for every state-input pair. Given a state and a symbol, there is exactly one place to go. No ambiguity. No surprises. The Non-deterministic Finite Automaton (NFA), by contrast, can have multiple valid transitions — or none at all — for the same input. It explores multiple paths simultaneously, accepting if any path leads to a valid end state.
Your CPU? DFA. Your compiler? DFA. Your database? DFA. The entire edifice of reliable software? Built on DFAs, all the way down. When you call a sorting function, it does not sometimes return a different order depending on its mood. When a SHA-256 hash runs, it does not occasionally produce a different digest because it felt creative that morning. Determinism is what makes software trustworthy.
A DFA is the reason debugging is possible. If the same input always produces the same output, you can reproduce bugs. You can write regression tests. You can bisect a git history. Determinism is not just a property of computers — it is the foundation of engineering accountability.
Enter the NFA in Your Stack
Large language models are, in a meaningful sense, NFAs that got extraordinarily good at picking the right path. Feed the same prompt twice to a model with temperature > 0, and you will get different tokens. The model samples from a probability distribution — it is not executing a lookup table. The output is not determined; it is probable.
This is not a bug. It is the design. The non-determinism is what makes AI feel creative, contextual, and generative. It is what allows a model to write novel code, not just regurgitate snippets. The NFA is the feature.
But now that NFA is writing code that will run inside your DFA. And that is where the tension begins.
Why AI-Generated Changes Will Create More Incidents
The argument is sometimes made that humans create incidents too — a stray off-by-one error, a forgotten null check, a race condition missed in review. All true. But the comparison breaks down when you examine the structure of how human changes and AI changes enter production.
The combinatorial blast radius of a large AI diff is enormous. A 1,500-line change touching five services, reviewed at high speed because "the AI checked it" — that is not the same risk profile as a two-line fix that three engineers scrutinized for twenty minutes.
The Confidence Trap
Here is the pernicious part: AI-generated code looks correct. It follows idioms. It uses the right variable names. It handles the happy path beautifully. The subtle failure modes — the edge case at 10x traffic, the race condition under partition, the off-by-one in a timezone conversion at midnight UTC — these are invisible until they are not. And because the code looks so clean, human reviewers lower their guard. The very quality of the output is a risk multiplier.
# Human diff: 47 lines, 1 function, clearly scoped
# Reviewer time: ~20 minutes. Risk surface: small.
# AI diff: 1,400 lines, 6 files, 3 new abstractions
# Reviewer time: ~15 minutes. Risk surface: enormous.
def process_payment(user_id, amount, currency):
# Looks right. Tests pass. Ships to prod.
# The currency rounding logic is wrong for JPY.
# This will never appear in a unit test.
# It surfaces at 3 AM on a Tuesday.
result = convert_and_round(amount, currency)
return charge(user_id, result)
The Safety Net That Was Never Tightened
Unit tests. Integration tests. Canary deployments. These are the guardrails we built for a DFA world. They are necessary — but they were designed around human-scale change. A developer writes a function, writes tests for the cases they can think of, and ships. The test suite catches regressions. The canary catches production anomalies. The on-call engineer catches whatever slips through.
But AI operates at a different scale. It generates edge cases we did not anticipate, because it was not thinking about the same edge cases we were. Its test generation is probabilistic too — it writes tests for the happy paths it imagined, not for the failure modes that lurk in a distributed system at 2 AM. If your test suite was not comprehensive before AI-assisted development, it is now critically underweight.
The Path Forward Is Not Slower AI — It's Better Gates
None of this is an argument to stop using AI in software development. The productivity gains are real, and the direction of the industry is clear. The argument is for proportionate engineering discipline. If your diff sizes have tripled, your review standards need to tighten by the same factor. If AI is reviewing AI, someone needs to audit that loop.
Concretely: treat AI-generated diffs with the same skepticism you would apply to a new hire who is brilliant but unfamiliar with your production environment. Require explicit ownership — a human engineer whose name is on the incident if it breaks. Mandate that test coverage is not AI-generated for the critical paths. Run your canary longer on large diffs. Build alerting for when the diff-to-review-time ratio gets dangerously lopsided.
Most importantly: do not let the fluency of the output create the illusion of correctness. A beautiful, well-structured 1,400-line diff from an LLM is not safer than a human's 80-line diff — it is riskier, precisely because it is harder to reason about and easier to rubber-stamp.
Your test suite should be the last DFA standing between AI's probabilistic output and your users. If it is not comprehensive, deterministic, and ruthlessly maintained — it will not catch the incident that is coming. Tighten the gates before the NFA ships to production.
A Prediction, Not a Panic
We will see more incidents. Not because AI engineers are careless — quite the opposite; the people integrating these tools are some of the most capable in the industry. We will see incidents because the tools are operating at a scale and in a probabilistic regime that our review and testing infrastructure was not designed for. The DFA is meeting the NFA in production, and the handoff is not yet clean.
The teams that figure this out first — that build the discipline to match the scale of AI-assisted development — will ship faster and safer. The teams that do not will read their postmortems and wonder why the tests all passed.
The machine always told the truth. We just forgot to ask it the right questions.