← All posts

Our CI Pipeline Got an AI Brain — What It Caught Surprised the Whole Team

May 16, 2026Faisal KCAI · DevOps

Last week I wrote about the vibe coding experiment and how our pull request reviews exposed the gaps in AI-generated code. That post ended with the guardrails we put in place — human review, linter gates, test coverage thresholds. All necessary. All manual.

But here's the thing that kept bothering me: we were using AI to write code faster, then slowing down to review it the same way we always have. That felt like buying a faster car and keeping the same brakes. So about six weeks ago, I asked Rashid, our DevOps lead, a question: what if the pipeline itself could think?

The Experiment

The idea was simple. We already run linting, tests, and static analysis on every pull request through GitHub Actions. What if we added one more step — an AI review that reads the diff, understands the context, and posts comments on the PR before any human looks at it?

Not to replace human review. To give the human reviewer a head start. Flag the things that are easy to miss when you're scanning 400 lines of changes at 6 p.m. on a Thursday.

Rashid set up the integration over a weekend. A custom GitHub Action that triggers on every PR, extracts the diff, sends it to an AI API with a system prompt tuned to our stack and conventions, and posts the findings as inline PR comments. The whole thing runs in about 45 seconds for an average-sized PR. We rolled it out first on our NestJS backend repo — the one that powers AWQAF UAE — because that's where the stakes are highest.

Week One: The Noise Problem

The first week was rough. The AI flagged everything. Variable naming suggestions. Minor style preferences. Comments like “consider using a more descriptive name for this parameter.” The kind of feedback that isn't wrong but isn't useful when you're shipping a critical fix for a government platform.

Arjun was the first to push back. He sent me a screenshot of a PR with 23 AI comments — 20 of which were style nitpicks. His message: “This is like having a very enthusiastic intern review every PR.” He was right. Alert fatigue is real, and if the team starts ignoring AI comments, the whole experiment fails.

We spent the next three days tuning the system prompt. Stripped out style suggestions entirely — that's the linter's job. Told the AI to focus on three categories only: potential bugs, security concerns, and architectural inconsistencies. We also told it to stay silent when it had nothing meaningful to say. No “looks good” comments. If it can't find a problem, it shouldn't speak.

Week Three: The Finds That Mattered

Once we tuned the noise down, the signal got interesting.

A race condition in a queue processor. One of our NestJS services processes donation transactions asynchronously. A developer submitted a PR that added a new processing step but didn't account for the case where two messages arrive for the same transaction within milliseconds. The AI flagged it: “This handler reads and writes to the same record without a lock or idempotency check. Under concurrent load, this could process the same transaction twice.” That comment saved us a production incident. The human reviewer — Arjun, ironically — said he would have caught it eventually, but admitted the AI got there in 45 seconds while he was still reading the file imports.

An environment variable leak in a Docker compose file. A developer added a new service to our local development setup and hardcoded a database URL with credentials in the compose file. The AI caught it and suggested using environment variable references instead. Simple, but easy to miss in a config file that people rarely read line by line.

An inconsistent error response contract. Across our NestJS services, we have a standard error response shape that the Flutter apps depend on. A new endpoint returned errors in a slightly different format — the field was called error_message instead of message. The AI had enough context from the surrounding codebase to flag the inconsistency. Nadia on the mobile side confirmed it would have broken the error dialog in the app.

What It Cannot Do

For all the useful catches, the AI has clear blind spots that the team needs to understand.

It cannot evaluate business logic. If a discount calculation is wrong because the product manager changed the rules last Tuesday, the AI has no way to know. It sees code that compiles and follows patterns. Whether the output is correct for the business is a human judgment.

It struggles with cross-repo context. Our Flutter apps call our NestJS APIs, but the AI analyzes each repo independently. It cannot tell you that a change to the API response shape will break the mobile app unless both changes are in the same PR. We're exploring ways to feed it API contract schemas, but that's still a work in progress.

It generates false positives on intentional patterns. We have a few places in our codebase where we deliberately use patterns that look like mistakes — like catching and silently swallowing certain errors in a retry loop. The AI flags these every time. We added inline comments (// AI-OK: intentional silent catch for retry logic) to suppress specific findings, but it's an ongoing tuning exercise.

The Numbers After Six Weeks

We expanded the AI review to four repos: the AWQAF backend, the National Payment of Zakat API, a shared Flutter component library, and one of our React admin dashboards. Here's what the data shows.

Across 187 pull requests, the AI posted 312 comments. Of those, 74 were actionable — meaning the developer made a change based on the AI's feedback. That's a 24% signal-to-noise ratio. Not amazing, but improving as we refine the prompt. More importantly, 11 of those 74 were classified by the team as “would have reached production” — bugs or security issues that the human reviewer agreed they likely would have missed.

The average time added to the CI pipeline is 38 seconds. The team consensus: worth it.

What Changed About Human Review

The unexpected benefit wasn't the bugs the AI caught. It was how it changed the way humans review code.

Arjun told me that he now reads AI comments before starting his own review. If the AI has already covered the mechanical issues — null checks, error handling, naming inconsistencies — he can spend his review time on the things only a human can evaluate: does this architecture make sense for where we're headed? Is this the right abstraction? Will we regret this in six months?

Rashid extended the concept to infrastructure. Our Terraform configs and Nginx configurations now get a similar AI pass. Last week it caught a misconfigured CORS header on a staging environment before anyone deployed to it.

The team went from skeptical to quietly reliant in about three weeks. Nobody talks about the AI reviewer anymore. It's just part of the pipeline, like linting. And that's probably the best outcome — when a tool becomes invisible because it just works.

If You're Thinking About This

Start small. Pick one repo — ideally the one with the highest stakes — and run the AI review alongside your existing process for two weeks before acting on any of its findings. Use that time to tune the prompt. Every team's conventions are different, and the default behavior of most AI models is too verbose for code review.

Set expectations with the team early. This is not a replacement for their expertise. It's a second pair of eyes that never gets tired, never skips a file, and never rushes because it's Friday afternoon. The things it catches are the things humans miss not because they can't see them, but because attention is finite.

And measure everything. Track the signal-to-noise ratio, the time added to the pipeline, and — most importantly — the issues that would have reached production without the AI catching them. If the numbers don't justify the effort after a month, it's not the right time. But in our case, 11 near-misses in six weeks made the case for us.