The Illusion of a Green Pipeline
There's a certain kind of comfort that comes from a passing pipeline. You push a change to a Detection Rule, the checks run, everything turns green, and you move on with your day feeling like you did it right. Detection as Code earned that comfort honestly. It gave us version control, peer review, automated testing, and repeatable deployments for detection logic that used to live in a console somewhere with no history and no accountability. It was a genuine leap forward, and it deserves the praise it gets.
But there's a quiet problem hiding behind that green checkmark. A passing pipeline tells you your rule is syntactically valid and that it deployed. It doesn't tell you the rule still works. And in Detection Engineering, "still works" is the only thing that actually matters.
The Problem: Detections Decay in the Dark
Here's the uncomfortable truth about a detection rule: the moment you deploy it, it starts drifting away from the threat it was built to catch. Nobody touches it, nobody breaks it on purpose, and yet its effectiveness quietly erodes over time. This is detection decay, and it's one of the most underappreciated risks in a modern detection program.
Decay happens for reasons that have nothing to do with the quality of your original rule. A vendor updates a log source and renames a field, so your parser silently stops populating the field your logic depends on. An adversary tweaks their tooling just enough to slip past a brittle string match. A cloud platform changes the schema of an event type. An endpoint agent gets upgraded and starts emitting a slightly different process command line. None of these events trip an alarm. None of them turn your pipeline red. Your rule still deploys, still validates, still looks perfectly healthy in the repo. It just doesn't fire anymore when it's supposed to.
This is the failure mode that keeps analysts and detection engineers up at night, because it's invisible by default. A rule that throws an error gets noticed. A rule that simply stops catching things fails silently, and you often don't find out until an incident review asks why the detection you were counting on never triggered.
Why Testing at Build Time Isn't Enough
The natural response is, "But we test our rules." And you should. The issue is what most Detection-as-Code testing actually proves.
Most CI/CD validation for detection rules confirms the things a compiler cares about. Does the syntax parse? Does the rule reference fields that exist in the schema? Does it deploy without throwing an error? Maybe you run the logic against a saved sample event and confirm it matches. That's all valuable, and it catches real mistakes before they reach production. But every one of those checks happens at build time, against a snapshot of the world as it looked the day you wrote the test.
The world doesn't hold still. The gap between "this rule was valid when we shipped it" and "this rule catches the threat today" only widens the longer the rule lives in production. Build-time testing proves your rule was correct once. Unfortunately, it doesn’t prove that it will work tomorrow. That's the blind spot, and no amount of additional unit testing closes it, because the problem isn't in your code. It's in the drift between your code and a reality that keeps moving.
The Next Step: Continuous Validation
If detections decay silently and build-time tests can't see it, the answer has to run continuously and against the live environment. That's continuous validation: routinely exercising your detections the way an adversary actually would, and confirming they still fire in the environment they're deployed in, not just the environment they were written for.
The mechanism that makes this real is adversary emulation. Instead of asking "does this rule parse," you ask "if I actually perform the technique this rule is supposed to catch, does an alert show up?" You safely execute the behavior, mapped to the same MITRE ATT&CK technique the rule is aligned to, and you wait for the detection to fire end to end, from log generation through your detection logic catching the activity and firing the alert. If it fires, you have evidence instead of assumption. If it doesn't, you've just caught a decayed detection before an adversary did.
This closes the loop that Detection as Code left open. Detection as Code got the change from an engineer's head into a governed, tested, deployed rule. Continuous validation confirms that the deployed rule keeps doing its job every day after, across every field rename, schema change, and tooling update the environment throws at it. One proves the rule was built right. The other proves it still works.
Piecing It All Together
Detection as Code was never the finish line. It was the foundation. It gave us the discipline to treat detection logic like real software, and that discipline is exactly what makes the next step possible. You can't continuously validate detections you can't version, deploy, and map to technique consistently. The maturity that Detection as Code built is the launchpad for continuous validation, not a competitor to it.
The shift lies in the question we ask. Detection as Code answered "did we build this rule correctly?" Continuous validation answers "is this rule still protecting us right now?" The first question is asked once, at deployment. The second has to be asked continuously, because the environment your detections live in never stops changing, and a detection that isn't validated against today's reality is just a detection you're hoping still works.
Hope isn't a detection strategy. Evidence is. That's the difference between a program that makes assumptions and one that provides evidence, and it's why continuous validation is the natural next evolution of Detection as Code.



