Last week's issue made the claim that AI agents are doing vulnerability discovery work in an hour that used to take a researcher a week, and that the volume problem this creates is already breaking triage processes inside medical device companies. A few of you wrote back asking the same question, in different words. OK, but how does it actually work?
This issue is the answer. If you're going to defend against this, and you are, you need an accurate mental model of what's on the other side of the fence. Not the marketing version. The actual machine.
The short version is this. The model is not the product. The harness is the product. The model provides reasoning. The harness is everything around the model that turns reasoning into work against a real target. The harness is what decides which tools the model can call, what context it sees, what other agents it talks to, when to spawn a subagent, when to compact a context window that's filling up, where to write findings to durable memory, and how to recover when something fails. The harness is also where the domain knowledge lives. A harness for hunting bugs in a web app is not the same as a harness for hunting bugs in firmware that's running on a real device. The reasoning model in the middle can be the same. The harness around it is the entire difference.
This used to be the part of the work that was invisible. Until recently.
When Claude Code's harness became publicly visible last year, first through the Claude Agent SDK and then through a series of system prompt and tool definition leaks that circulated openly, it was treated by most of the press as a curiosity. A look behind the curtain. A few interesting prompts. The actual story was bigger.
What got exposed was not a prompt. It was a recipe. The exact tool surface the agent has access to. The way it spawns subagents with narrower context. The way it compacts memory when the context window fills. The way it uses a todo list and a plan file as durable state. The way it decides when to delegate to a search agent versus reading a file directly. The handoff patterns. The retry logic. The way the orchestrator keeps a goal in mind across hours of work.
That recipe was the moat. For two years the assumption inside the industry was that whoever had the best model would win. The leak showed that the model was not where the leverage was. The leverage was in the scaffolding. A frontier model with a thoughtful harness around it does work that the same model with a naive harness cannot do. The reasoning is identical. The output is not.
And once that scaffolding pattern was public, it was portable. The same orchestrator pattern, subagent pattern, compaction pattern, durable state pattern can be wrapped around any frontier model. The leak did not give anyone Claude. It gave everyone the blueprint for building an agent that approaches Claude Code's effectiveness on any reasoning engine they prefer.
For anyone watching the offensive security side, that was the moment the cost curve broke. The hard part of building a vulnerability discovery agent had been the harness. The harness was now reference material.
A code-scanning harness is comparatively easy. The target is a file system full of source. The tools the agent needs are grep, ast traversal, a decompiler if the target is binary, a way to call the model with a chunk of code and ask focused questions. Anyone can build a passable version of this in a weekend. Many people have.
A medical device harness is not that. A device is a physical asset. It has firmware that runs on a real microcontroller, sometimes on real-time OSes you cannot just emulate. It has hardware interfaces, USB, Bluetooth Low Energy, proprietary wireless, sometimes IR. It has a network surface with protocols that were designed in 2008 and never updated. It has a clinical use context that determines whether a finding is exploitable in a hospital or only on a bench. It has a regulatory submission and a postmarket surveillance obligation tied to it.
A harness that can do useful vulnerability discovery on a real device has to bridge all of that. It has to know how to drive the physical interfaces, not just read the code that handles them. It has to attach a debugger to a running process on the device, not on a Linux VM. It has to coordinate static analysis of the firmware with live behavior on the hardware, in real time, with the agents talking to each other and updating each other's plans.
Those of us who have spent the last decade testing these devices by hand have been building those harnesses for the last couple of years. Not because we expected the Claude Code leak. Because it was the only way to make the work scale. The leak validated the architectural bet for everyone else in the space.
Here is what one of those harnesses actually looks like when it runs.
To make this concrete, picture a network-connected infusion pump. Firmware you can pull. A small embedded Linux running custom service binaries. A proprietary protocol on the management port. A web UI for the clinical engineer. Standard enough.
A researcher kicks off the run with a one-paragraph goal. Find an exploitable vulnerability reachable from the management network, with a working PoC and evidence. That paragraph is the entire human input for the next several hours.
Then five agents wake up.
The first agent reads code. That's its whole world. It pulls the firmware, unpacks it, decompiles what it has to, and walks the source and binaries looking for the patterns that have historically gone wrong. Unchecked length fields. Strcpy in 2026. Format string sinks. Hand-rolled parsers. Places where a checksum is computed and then nobody actually validates it.
It doesn't run anything. It doesn't try to exploit anything. It produces a list of candidates with file, function, line, and a one-sentence theory for why each one is interesting. "Function parse_dicom_header at firmware/svc/dicom.c:412 reads a 16-bit length field from the network and passes it directly to memcpy without bounds checking against the destination buffer."
The scanner is fast and shallow. It will produce dozens of candidates per hour, most of which won't pan out. That's fine. Its job is to feed the rest of the team.
The second agent reads what the program actually does on the device. It attaches a debugger to the live service running on the real hardware, or on a high-fidelity emulator when the hardware isn't safe to crash. It watches syscalls, memory allocations, control flow. When the scanner says "this length field looks unchecked at line 412," the process agent puts a breakpoint there, sends traffic that should hit it, and watches what happens in the registers and on the heap.
This is where most of the scanner's candidates die. The line of code looks bad, but in practice the field is bounded somewhere upstream, or the function is never reached on the running build, or there's a length check three frames up that the scanner missed because it was looking at a different file. This is also where a pure code-scanning harness ends and a real device harness begins. You cannot get this signal from source alone.
The process agent produces a much shorter list. "Of the 47 candidates the scanner gave me, 6 are reachable on the running firmware. Here's the call stack for each." That list goes to the runtime agent.
The third agent has hands on the target. It speaks the protocol on the management port. It crafts inputs, sends them, and watches the response. The network response, the device behavior, and the trace coming out of the process agent.
It is doing what a pentester does with Burp or a fuzzing harness, except it's doing it for hours without stopping, and it's coordinating with two other agents that are telling it where to push. The process agent says "the length field at offset 0x4A is the one that's unchecked, and the parser only reaches it if you set magic byte 0x73 in the header." The runtime agent doesn't have to discover that. It just builds the input and fires.
When it gets a crash, or a hang, or an unexpected memory state, it captures the input and hands it upstream. When it gets stuck, and it always gets stuck, usually on a CRC or a session token or a state machine it doesn't understand, it asks the process agent why. The process agent looks at the trace and answers. The runtime agent updates and pushes again.
This is the feedback loop that makes the whole thing work. Static analysis alone is a list of maybes. Fuzzing alone is a wall of crashes you can't make sense of. The two together, talking in a tight loop, find things neither one finds independently.
A crash is not a vulnerability. A vulnerability is not an exploit. The fourth agent is the one that closes that gap.
When the runtime agent gets a clean crash, the exploit agent picks it up and tries to turn it into a working PoC. It looks at the corrupted state, decides what primitive it has (arbitrary write, controlled jump, info leak, denial of service) and tries to chain it into something that achieves the goal the researcher specified at the start. Code execution. Authentication bypass. Persistence on the device across reboots.
Most crashes don't get there. A lot of memory corruption on embedded devices ends at "the service restarted." That's still a finding, but it's a different finding than "the attacker can drop a shell." The exploit agent is what tells you which one you actually have.
When the exploit agent fails to produce a PoC after a budget of attempts, it writes that down too. "Reachable crash at parse_dicom_header, attempted control-flow hijack via length field overflow, blocked by stack canary. Primitive is denial of service, not RCE." That's a real finding with a real severity, and the report says so.
The last agent doesn't try to find anything. It collects evidence.
For every claimed finding, it pulls the artifacts from the other four agents and assembles a package. The crashing input. The exact firmware build and configuration. The stack trace at the moment of crash. The network capture of the exploit. The PoC if one exists, with reproduction steps. The disassembly of the affected function. The trace from the process agent showing the path from input to corruption.
Then it runs the PoC again, from clean state, on a clean device image, to confirm it reproduces. If it does, the finding ships. If it doesn't, it goes back to the exploit agent with a note.
This is the agent that matters most for the defensive side, and it's the one most people don't think about when they hear "AI found a vulnerability." A finding without reproducible evidence is an opinion. A finding with a packaged artifact that anyone can run is something a regulator, an engineer, or an auditor can act on.
None of these agents shares a context window with the others. Each one has its own. They communicate through two things. Short structured handoffs ("here are the 6 candidates that are reachable, ranked by exploitability potential, with traces attached") and a shared filesystem that holds the long memory of the run. The crash corpus, the coverage map, the findings list, the notes on what's been tried.
When any one agent's context fills up, the harness writes its state to the filesystem, compacts, reads its own notes back, and the agent continues. The orchestrator above them watches budget, progress, and whether the goal has been met. When one agent gets stuck, the orchestrator spawns a second instance of that agent with a narrower task, or kills the line of investigation entirely.
This is the same pattern that the Claude Code leak exposed, applied to a different domain. Tools, subagents, durable state, compaction, an orchestrator with a goal. The model in the middle is doing the reasoning. The harness is doing the work.
When someone tells you they're "using AI" for vulnerability discovery, the question is not which model they use. The model is interchangeable. The question is what their harness looks like. Which agents. Which tools each agent has. How they hand off. What durable state they keep. Whether the harness can drive a physical device, or only read source. What the validation agent actually produces.
If they can't draw that picture, they don't have a harness. They have a chatbot with a prompt. The gap between those two things is the entire story.