Back to News & Insights
Artificial Intelligence October 12, 2026 · 26 min read

Security Regression Gate Sentinel — block the rise, not the presence

Security Regression Gate — block the rise, not the presence How Sentinel decides which...

Security Regression Gate Sentinel — block the rise, not the presence

How Sentinel decides which merge requests get stopped in CI: not "this file can run shell commands" (that's been true for months), but "this change just gave the file a power it did not have yesterday".

Where the numbers come from. Everything here was measured on 2026-10-12, on the master branch of the Sentinel repository, using Node 24.19.0. I used three sources and I name the source at each number: Unit tests, run for real with node --test. I did not count test( lines with grep. A replay of today's gate over all 118 merge requests ever merged into Sentinel's master. This is deterministic, offline and takes one command (see Captured output). An earlier evaluation on 16 public GitHub repositories and 5 GitLab ones, written up in the repo's design-partner notes. That one was produced by a throwaway script that lives outside the repo, so nobody has reproduced it independently yet. I say this again wherever I use those numbers. There are no CI pipeline statistics in this article (how often the job actually failed on real MRs). I didn't have read access to the pipeline API while writing, so the article doesn't claim any.

Imagine a smoke detector that goes off every time it sees a candle. Not smoke. Not fire. A candle that's been on the same table for three years.

The first day, you jump. The second day, you sigh. By the end of the week you've taken the battery out, and now you have no smoke detector at all.

Most "security scanners" in code review work this way. They read a file, see something dangerous-sounding ("this file can run other programs!"), and raise a flag. They raise it again the next time someone fixes a typo in that file, and the time after that. The file was always able to run other programs. The flag carries no new information, so people learn to ignore it. Once a team ignores the warnings, the scanner has stopped doing anything useful.

Sentinel's merge-request gate is built around the opposite question. It doesn't ask "is this file dangerous?" It asks:

That's the whole idea of this article. The rest is detail: how "more dangerous" is measured, what happens when the answer is yes, and the cases where the gate still doesn't see the problem. I list those too.

Sentinel is an autonomous agent that watches a JavaScript codebase (its own, mostly) and decides, file by file, whether to leave it alone or propose a change. An earlier article in this series covered how it avoids re-thinking the same thought (the Novelty Gate). This one leaves the agent's head and goes to the front door of the codebase: the merge request. That's the moment a human (or an agent) asks "please add my change to the main branch". The gate lives in CI, the automated checklist that runs on every merge request. If the gate says no, the merge button stays grey.

The gate uses no AI. No language model is asked whether the code "looks risky". It's a plain program that reads code structure, and it gives the same answer every time you run it on the same input. That matters for a reason I'll come back to: you can argue with a deterministic gate, and you can reproduce its behaviour. You can't reproduce a mood.

To say "more dangerous", you need a scale. Sentinel uses four levels, decided purely by what the code can do:

| level | in plain words | examples | |---|---|---| | low | only computes, or only reads | math, formatting, reading a config file | | medium | changes something outside itself | writing files, talking to the network, handling passwords or crypto | | high | can destroy things | deleting files | | critical | can do anything | running other programs, or running text as code |

That last row is the interesting one. A file that can start another program (a shell command, git, ffmpeg) or turn a string into running code (eval) has no meaningful upper limit on what it can do. So the ladder stops there. You can't be "more critical than critical".

Each changed file gets two readings: one before the merge request, one after. The gate compares the two.

A merge request gets blocked when one of its files ends up at critical and at least one of these is true: It climbed. It was low, medium or high before, and now it's critical. "This file couldn't run programs yesterday. Today it can." It was already critical and gained a new kind of power. Say it could already run programs, and now it can also turn text into code. Same rung on the ladder, new trick. "This file could already run programs. Now it can also execute arbitrary strings."

A merge request does not get blocked when: a critical file is edited without gaining any new dangerous power (fixing a typo, renaming a variable, adding a log line), a dangerous power is removed (going down the ladder is always fine), a file moves up the ladder but stays below critical. This one is a deliberate choice, explained under The honest part.

Put another way, the gate reacts to the candle being lit. It doesn't react to a candle that has been sitting on the table for three years.

Some files should run programs. Sentinel's own report script has to ask git for the old and new version of each file, and there's no way to do that without running git. Blocking that file forever would be silly.

For these files the repository keeps a small permission-slip file called .sentinel-gate.json. Each entry says which file, why, and exactly which powers are accepted:

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation