Detection verification · Read-only
Which of your detections can't fire right now?
In 90 minutes, on four files your team exports, we show you every rule that cannot fire and exactly why. No agent. Nothing installed. No attacks run. Your engineers verify every finding in their own console.
Specimen data220 rules assessed · 61 cannot fire · evidence attached to every row
After a SIEM migration.
After an MDR handoff.
When you inherit an estate someone else built.
Before a renewal you have to defend.
Before the board asks if you're covered.
Don't take our word for it. Check five rules by hand.
Pick the five rules you are counting on most. For each one, run three searches. Paste them as written.
These searches catch the loud failures. The session adjudicates every rule, with evidence.
Take the index and sourcetype the rule searches, then:
| tstats count where index=<INDEX> sourcetype=<SOURCETYPE> earliest=-7d by _time span=1d
Empty result, or days at zero: everything downstream of this source is dead.
Take the table the rule queries, then:
<TableName> | where TimeGenerated > ago(7d) | summarize events = count() by bin(TimeGenerated, 1d)
Empty result, or days at zero: everything downstream of this table is dead.
Run the rule's base search (index/sourcetype only, no conditions), then:
index=<INDEX> sourcetype=<SOURCETYPE> earliest=-24h | fieldsummary | search field IN (<every field the rule filters or stats on>) | table field count distinct_count
Any field missing from this table, or at count 0: the rule can no longer match what it was written to match.
Run once per field the rule filters or aggregates on:
<TableName>
| where TimeGenerated > ago(24h)
| summarize total = count(),
populated = countif(isnotempty(<FieldName>))
Populated at zero while total is high: the rule can no longer match what it was written to match. Schema-level checks like getschema show the column exists even when nothing populates it, which is exactly the trap.
index=_internal sourcetype=scheduler savedsearch_name="<RULE NAME>" earliest=-90d | stats sum(result_count) as results_90d count as runs_90d
Zero results in ninety days means either quiet or dead, and this check cannot tell you which. Checks 1 and 2 can.
SecurityAlert | where TimeGenerated > ago(90d) | where AlertName == "<RULE NAME>" | summarize alerts_90d = count()
Zero results in ninety days means either quiet or dead, and this check cannot tell you which. Checks 1 and 2 can.
SentinelHealth can confirm the rule is running, but only with health diagnostics enabled. A footnote, not a dependency.
If all three pass on all five, you've verified five rules. The session does the rest. If one fails, you have found a dead rule your console has been calling green, and you have the evidence in hand.
Found one? gyan@dectyl.io
Different stack? Reply with your SIEM and the five rules. We'll send you the equivalent checks.
What we do
Free 90-minute finding session, on your own exports.
Be first to know, not read about it later.
90 minutes. Your environment. Your exports. Your findings.
You leave with the list: every rule that cannot fire, and why.
A read-only pilot is available afterward if you want the full estate on cadence.
Gyan Suri, founder. Ex-tech lead in Google's enterprise security engineering organization, working on large-scale detection and response: systems that turn high-volume security telemetry into reliable, actionable signal. Dectyl applies that same standard to the rules you already run: verified, or not.