All lessons › Function E — The Agentic SOC › Discover — the Sensors, and the Agent-Shaped Hole in Them
E1.1

The sensor estate — EDR, DLP, CSPM and CNAPP against an agent

E1
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/E1.1.mp4
Risk

Four products are bought, the estate is assumed covered, and the agent's whole working day falls between them.

Control

A coverage matrix computed per sensor and per agent action, with the uncovered actions named rather than counted.

The lab

Score four sensor classes against nine real agent actions and read the column none of them covers.

◉Use case relevance

Four security products already watch the estate and every one of them was bought for a person on a host. Score them against what an agent actually does and four of its nine ordinary actions are seen by nothing at all — not seen badly, not alerted on late, simply outside the field of view.

At CyberTravels. soc/sensors.py derives the action list from config.TOOL_POLICY rather than from memory, then asks each product what it observes. With the agent's own telemetry onboarded, coverage is 1.0. Run it without={'agent telemetry'} — the estate as most teams have it — and it is 0.214: every tool call, the token mint, the approval, memory and every peer message are invisible. That is the agent's whole working day.

◴What this lesson is — Day 0, Day 1, Day 2

Changing the denominator of a coverage report from products deployed to agent actions observable, so the uncovered rows come back named rather than as a percentage — and each product states what it cannot see, in its own row.

Day 0 — why

Four products are bought, the estate is assumed covered, and the agent's whole working day falls between them.

Day 1 — how

Score each sensor class on visibility rather than alerting, per agent action, and read the rows nothing covers.

Day 2 — measure

Four of nine ordinary agent actions seen by no sensor class at all. That column is an architecture finding, not a tuning backlog.

Measure this

what to measuredenominator or target
ordinary agent actions seen by no sensor class at allfour of nine on the sample; an architecture finding, not a tuning backlog

▦The framework, and how it works

   what already watches the estate      what an agent does

   EDR    Wazuh agent          -----> writes a file        ##
   CNAPP  Falco + Trivy        -----> spawns a child       ##
   EDR    (partial)            -----> opens TLS to a model ..
   CSPM   Prowler              -----> assumes an IAM role  ..
   DLP    regex + FIM          -----> exfil to allowed SaaS ..

                                      reads a customer record
                                      puts it in a prompt
                                      calls a vendor MCP tool     <- NOTHING
                                      issues a refund

   the four uncovered rows are not badly tuned. no sensor class
   is in the path. they all happen inside the reasoning loop, or
   behind an API the host never observes.

Nobody starts an agentic SOC from nothing. Four classes of sensor are already deployed, already paid for, and already producing alerts:

classwhat it watchesopen-source reference
EDRprocesses, files and network on a hostWazuh agent
DLPsensitive content leaving a monitored channelregex + file integrity monitoring
CSPMcloud configuration, evaluated on a scheduleProwler, ScoutSuite
CNAPPcontainer runtime and image contentsFalco, Trivy

All four work. The question is not whether they are good — it is which parts of an agent's working day they are in the path of at all.

That is a matrix, and it is worth building before a roadmap rather than after, because the answer decides whether the next quarter is spent tuning or spent building a source that does not exist yet.

The distinction that makes the matrix honest is visibility, not alerting. "Would this fire" is a tuning question. "Is this sensor in the path" is a fact about architecture, and a sensor that is not in the path cannot be tuned into one that is.

Read the uncovered rows rather than the percentage. If they are arbitrary, tune. If they share a property — every one inside the reasoning loop, or behind an API the host never observes — then a fifth product of the same four kinds will not move them.

Anchor → E1.0. Discover has a floor, and this lesson measures it. Four of the nine actions have no sensor in their path at all, so for those the interval is not long — it is undefined, and no amount of tuning the four products you own changes that.

2 · Demo — four sensors against nine ordinary agent actions

3 · Where it breaks — the combined column, and the four rows in it

4 · The control — derive the next source from the uncovered set

5 · The procedure, as a skill

The skill takes nine things CyberTravels' agents do on an ordinary day, and four classes of sensor that might see them. It scores every pair.

It adds the rows up, not the columns. If three sensors each see the same action, that action is covered once, not three times. Summing the columns makes thin coverage look thick.

The useful output is the short list at the end: the actions that no sensor class sees at all.

▶Real time execution as skill

The skill — skills/detection/sensor-coverage-matrix/SKILL.md

name: sensor-coverage-matrix
description: >-
  Score the sensor classes an estate already owns — EDR, DLP, CSPM, CNAPP —
  against what an agent actually does, and name the actions no sensor sees. Use
  before buying detection tooling for an agent estate, or when someone claims
  the estate is already covered.
allowed-tools: Read, Grep, Glob

Coverage is a column, not a percentage

Every estate that runs agents already owns four classes of sensor, bought for people and hosts. The question is not whether they work — they do, at what they were built for — but which parts of an agent's working day are inside their field of view at all.

Answer it as a matrix and one number falls out that no product page will give you: the actions seen by nothing.

When to use this

Before a detection roadmap, before a tooling purchase, and any time "we already have visibility" is offered as an answer about an agent estate.

Procedure

1 — List the sensor classes you own, with the product behind each. Naming the product keeps the conversation checkable. The open-source references are Wazuh for EDR, regex plus file integrity monitoring for the DLP that most teams actually have, Prowler or ScoutSuite for CSPM, and Falco plus Trivy for CNAPP.

2 — List what the agents do, not what you fear. An ordinary day: files written, an outbound session to a model API, a customer record read through an internal API, tokens placed in a prompt, a vendor tool called, money moved, a role assumed, a child process spawned.

3 — Score each cell as full, partial or none — on visibility, not alerting. "Would this sensor alert" is a tuning question and comes later. "Is this sensor in the path" is a fact about architecture, and it is the one that decides whether tuning is even possible.

4 — Read the uncovered rows, and read what they have in common. If the uncovered set is arbitrary, tune. If it is coherent — every action inside the reasoning loop, or behind an API the host never observes — then a fifth product of the same four kinds will not move it, and the answer is a new source rather than a better rule.

Example

per-sensor coverage of the agent's day
  EDR     3.0 / 9   33%
  DLP     0.5 / 9   6%
  CSPM    0.5 / 9   6%
  CNAPP   3.0 / 9   33%

  best single sensor   EDR
  all four combined    3.5 / 9   39%

The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.

Output contract

{
  "sensors": [{"name": "str", "product": "str", "sees": "str"}],
  "actions": [{"action": "str", "coverage": {"EDR": "full|partial|none"}}],
  "per_sensor": [{"name": "str", "score": 0.0, "of": 0}],
  "combined": {"score": 0.0, "of": 0},
  "uncovered": ["str"]
}

Failure modes

  • Scoring alerting rather than visibility. A sensor that is not in the path cannot be tuned into one that is.
  • Summing the columns. Four sensors covering the same three actions is still three actions; take the union per row, which is what the script does.
  • Reporting the combined percentage alone. 39% sounds like a tuning problem. The four named rows are the finding.
  • Treating a partial as a full. Seeing a TLS session open is not seeing what crossed it.

Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.

1In your AI agent — you are taught

The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.

Install it, once. From the folder you cloned. --all does every agent it finds on your machine:

python3 scripts/install_skills.py --all --lessons E1.1

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick e1-1-the-sensor-estate:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E1.1type /e1-1-the-sensor-estate
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E1.1type /e1-1-the-sensor-estate in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E1.1type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E1.1type $e1-1-the-sensor-estate, or run /skills

2As one Python command — you just run it

No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.

python3 scripts/lesson.py E1.1

3Read the code, and the difference — nothing runs

Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.

python3 scripts/checkpoint.py --at E1.1 --out work/cybertravels
python3 scripts/checkpoint.py --at E1.1 --diff

On Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.

Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.

Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.

If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.

✓What you just proved

EDR and CNAPP each cover about a third of the agent's day, DLP and CSPM almost none of it, and all four combined still leave four of the nine actions seen by nothing: reading a customer record through an internal API, placing it in a prompt, calling a vendor MCP tool, and issuing a refund. Those four share a property, and it is the argument for E1.3 and E2.1 rather than for a fifth product.

✎Your turn

Build the same matrix for your estate with your own actions in the rows. The number that matters is not the percentage — it is whether the uncovered rows have something in common.

Tools used

WazuhProwlerFalco

Skill source: skills/detection/sensor-coverage-matrix

← PreviousE1.0 · Start here — the agentic SOC, and the stack that runs it