Strobesstrobes
Platform
Solutions
Resources
Customers
Company
Pricing
Book a Demo
Strobesstrobes

Strobes connects every exposure signal to autonomous action, so security teams fix what matters, prove what works, and stop chasing noise.

Book a DemoTalk to an expert
ISO 27001SOC 2CREST
  • Platform
  • Platform Overview
  • Agentic Exposure Management
  • AI Agents
  • Integrations
  • API & Developers
  • Workflows & Automation
  • Analytics & Reporting
  • Solutions
  • Exposure Assessment (EAP)
  • Attack Surface Management
  • Application Security Posture
  • Risk-Based Vulnerability Management
  • Adversarial Exposure Validation (AEV)
  • AI Pentesting
  • Pentesting as a Service
  • CTEM Framework
  • By Industry
  • Financial Institutions
  • Technology
  • Retail
  • Healthcare
  • Manufacturing
  • By Roles
  • CISOs
  • Security Directors
  • Cloud Security Leaders
  • App Sec Leaders
  • Resources
  • Quick Agentic Pentest
  • Blog
  • Customer Stories
  • eBooks
  • Whitepapers
  • Datasheets
  • Videos & Demos
  • Exposure Management Academy
  • Pentesting ROI Calculator
  • Pentest Health Check
  • Security Tool ROI Calculator
  • Company
  • About Strobes
  • Meet the Team
  • Trust & Security
  • Contact Us
  • Careers
  • Become a Partner
  • Technology Partner
  • Partner Deal Registration
  • Press Release

Weekly insight for security leaders

CTEM research, agentic AI trends, and what's actually moving the needle.

© 2026 Strobes Security Inc. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyAccessibilitySitemap
Back to Blog
Tooling as Code and Structured Scratchpads
engineeringOffensive SecurityAI Security

Tooling as Code and Structured Scratchpads

Strobes SecurityAugust 3, 202615 min read

Table of Contents

  • Two changes that reshaped how our AI agents work
  • Part 1: Tooling as code
    • The old problem
    • What we did instead
    • What the agent gets for free
    • Second-order effects
  • Part 2: Structured scratchpads
    • The failure this fixes
    • The methodology
    • What a pad looks like
    • The checklist, and why it's answers, not prose
    • The gate: one classifier, three ways to fail
  • How the two compose
  • What actually changed

Authors

S
Strobes Security

Share

Table of Contents

  • Two changes that reshaped how our AI agents work
  • Part 1: Tooling as code
    • The old problem
    • What we did instead
    • What the agent gets for free
    • Second-order effects
  • Part 2: Structured scratchpads
    • The failure this fixes
    • The methodology
    • What a pad looks like
    • The checklist, and why it's answers, not prose
    • The gate: one classifier, three ways to fail
  • How the two compose
  • What actually changed

Authors

S
Strobes Security

Share

Two changes that reshaped how our AI agents work

Most of the conversation around AI agents in security is about which model is driving. That's the least interesting variable, honestly. The two changes that moved our agents the furthest this year had nothing to do with the model. They changed how the agent acts on the target, and how it records why it believes something.

We call them tooling as code and structured scratchpads. This post walks through both: what was broken before, what the setup looks like now, and what actually changes in practice.


Part 1: Tooling as code

The old problem

Give a web application pentest agent the usual toolset and on paper it looks fine:

  • http_request to send an HTTP request
  • graphql_request to send a GraphQL query
  • browser_click, browser_type, browser_snapshot
  • crawl_url, extract_endpoints, decode_jwt

Underneath, each of these is a thin wrapper around an HTTP library. The wrapper isn't pointless. It holds the session, keeps the cookie jar, sets a real browser TLS fingerprint, sends traffic from the right network identity, and records the exchange as evidence. That's real value, and it's the reason you don't just hand the agent curl.

The problem was never the wrapper. It was the calling convention.

One tool call per request: five hundred round trips through the model, five hundred response bodies pushed into context
One tool call per request: five hundred round trips through the model, five hundred response bodies pushed into context.

Say you're testing an object reference flaw and you need to sweep five hundred identifiers. With one tool call per request, that's five hundred round trips through the model, five hundred response bodies pushed into context, and a run that burns its whole budget during recon and never even reaches analysis.

Every obvious fix fails the same way:

  • Add an iterations argument. Works fine, right up until each iteration needs a different path, a different header, or a decision based on the previous response.
  • Add a range argument. Then you add filter, stop_on, vary_header, follow_redirect_if, and so on. Every real testing pattern becomes another field, and the tool schema keeps growing. Remember, you pay for that schema in tokens on every single request the agent makes, whether it uses the tool or not.
  • Add a dedicated tool per pattern. fuzz_parameter, swap_object_id, replay_as_role. Now you've got thirty tools, the model has to pick the right one every time, and the second a target does something slightly unusual, none of them fit.

The real tension is simple. A tool schema is a fixed shape, and security testing is not a fixed-shape activity. You're always one loop, one conditional, or one intermediate transformation away from whatever the schema anticipated.

And sitting on top of all of it is one obvious fact: the model is already excellent at writing Python. Handing a fluent programmer thirty rigid buttons instead of a keyboard is a strange trade to make.

What we did instead

We stopped shipping actions and started shipping libraries.

Each discipline gets a Python SDK that the agent imports and drives inside a sandbox:

Discipline Library What it covers
Web / API pentest strobes_pt HTTP, GraphQL, sessions and login, browser control, crawling, injection oracles, authorization matrices, JWT
Source code review strobes_cr Repository entry points, taint tracing, dependency inventory, citation, coverage accounting
Network pentest strobes_net Host/port/service discovery, TLS inspection, content discovery, template scanning
Cloud / CSPM review strobes_cloud Account verification, prescan, public-exposure derivation, identity trust paths

The agent doesn't call a tool per request anymore. It calls one tool, "run this code," and the code does the work.

One tool call, run this code: the loop-and-filter work happens in the sandbox and only the anomalies come back
One tool call, run this code: the loop-and-filter work happens in the sandbox and only the anomalies come back.

Five hundred requests. One tool call. Three lines of output.

The filtering happens where the data is, not after it's been dragged back through the model. That's the whole economic argument, and it holds for every discipline. A dependency inventory, a port sweep, a cloud prescan, a taint trace across ten thousand files: all of it is loop-and-filter work that has no business being narrated one request at a time.

What the agent gets for free

The value the old tools provided didn't disappear. It moved inside the library, where it's stronger.

The value the old tools provided moves inside the library, where session handling and the evidence trail become structural
The value the old tools provided moves inside the library, where session handling and the evidence trail become structural.

Three properties matter here.

Egress identity is structural. All target traffic leaves from the sandbox, never from the worker. That isn't a convention we ask the agent to follow. It's a property of where the library runs.

Everything is recorded, automatically. Every request the web SDK sends, every analysis the code-review SDK runs, every scan the network SDK launches, every check the cloud SDK reads: each one appends a row to an evidence trail that gets drained into queryable tables. The agent doesn't opt in, and it can't forget.

This gives us something no findings list can. We get a record of what was examined, not just what was reported. "Was this host ever scanned, with what, and when" is a question a client asks the moment something gets missed, and you can't answer it from a report. You can answer it in one query from a coverage table.

Absence is loud, never empty. This is a rule we enforce across every SDK, and if I could keep only one design decision, it'd be this one.

A security tool that returns "no findings" because it couldn't run looks identical to one that ran and found the target clean. That confusion is the most dangerous failure mode in the whole domain, because "clean" is what gets reported to the customer.

So every function returns an explicit status. A missing binary, a dead credential, an unopened account, a scan killed by a timeout: all of them return ok: false with a reason. They never return an empty list.

We hit four separate instances of this while building the code-review toolkit alone. One static analysis engine analyses git-tracked files only by default, so point it at an untracked directory and it examines zero files, exits successfully, and reports nothing. Another silently skips tests/, vendor/ and build/. A single unparseable rule aborts a whole ruleset, so one broken pattern zeroes out every unrelated language's rules too, and the whole thing reads back as "no attack surface."

Through a naive tool, every one of those is a clean bill of health for code nobody looked at.

Second-order effects

A few things we didn't design for but got anyway:

  • The tool schema stopped growing. Adding a capability now means adding a function to a library, not a field to a schema the agent pays for on every request. Fixed cost per turn went down while capability went up.
  • The agent debugs itself. When code fails, the agent gets a Python traceback, which it's extremely good at reading, instead of a validation error about a tool argument.
  • Novel techniques need no platform change. If an engagement needs a request pattern nobody anticipated, the agent just writes it. Before, that meant shipping a tool.
  • Everything is reproducible. The code the agent ran is an artifact. You can read it, re-run it, and hand it to a client.

Part 2: Structured scratchpads

Tooling as code fixed how the agent acts. It did nothing for how the agent concludes.

The failure this fixes

Scratchpads aren't a new idea. Reasoning-and-acting agents have kept notes for years, and you'll see the same thing in Claude Code. What's new here is what the notes are for.

Think about how an agent actually reaches a finding. It probes forty endpoints. On the eleventh it sees something odd. It chases it across six more requests, gets a signal, and files a vulnerability. Between the observation and the submission sit thirty more requests worth of unrelated traffic.

By the time it writes the finding, the evidence that justified the claim has been diluted, truncated, or evicted from its working context. So the write-up isn't read from a record. It's reconstructed from a degraded memory.

That reconstruction is what a false positive usually is. Not a hallucination in the dramatic sense. A confident summary of something the agent half-remembered.

You can try to fix this with prompting. We did. "Explain your reasoning before filing" gives you a paragraph of reasoning-shaped text written after the decision was already made. It's a rationalisation, not a record, and there's no way to falsify it.

Our own production data made the point pretty sharply. In one corpus we found findings whose own write-up said exploitation wasn't possible. The analysis was correct and sitting right there in the submission, and they got filed anyway, and every one was rejected by a human. The missing piece was never knowledge. It's that the analysis wasn't load-bearing on the decision to file.

The methodology

So we gave the agent a method, and then made the method structural instead of advisory:

Think, act, log, verdict: the pad opens before the probing starts, so the reasoning is recorded, not reconstructed
Think, act, log, verdict: the pad opens before the probing starts, so the reasoning is recorded, not reconstructed.

The pad opens before the probing starts, not after. That ordering is the whole point. A pad written afterwards is a summary. A pad written during is the reasoning.

What a pad looks like

A pad is just a plain markdown file in the workspace. The agent edits it with the normal file tools it already has, so it stays completely freeform. It can write anything, anywhere, at any point.

The shape is the same for every investigation, whatever the vulnerability class:

A pad is a plain markdown file: observations, cited evidence ids, a validation checklist answered in the agent's own words, and a verdict
A pad is a plain markdown file: observations, cited evidence ids, a validation checklist answered in the agent's own words, and a verdict.

One pad per finding, or per scenario. A pad covering four findings answers cleanly for none of them.

The Evidence section is where the two features meet. Every request the SDK sends gets recorded and stamped with a short, content-addressed id, handed straight back to the agent in its output:

[evidence] 2 exchange(s) recorded:
  ev-39ef025a66c8  GET /api/orders/1042 as bob -> 200
  ev-8ed4a9dfb1fa  same request unauthenticated -> 401   (the control)

The agent cites those ids inline as it reasons. A reader, human or machine, goes from "the control returned 401" straight to the actual bytes.

And because the ids come from the content of the exchange itself, an invented citation can't resolve. A hallucinated reference stops being an invisible problem and turns into a visible signal.

The checklist, and why it's answers, not prose

Here's the part that makes the pad more than a diary.

Every pad carries a validation checklist: the questions that actually decide whether the thing being claimed is a vulnerability. Four apply to any finding at all:

  • Reproduced. Did you observe this more than once, deterministically?
  • Control. What did you run to rule out the benign explanation, and what did it return? "Not run" is an honest answer.
  • Intended behaviour. Could this be documented product behaviour? What makes you confident it isn't?
  • Impact. One sentence: what does the attacker now hold that they didn't hold before?

Those four are where findings actually die in human review. We ask them of every finding, including the big chunk whose class we can't confidently identify. Not knowing what kind of flaw something is has never been a reason to ask nothing.

On top of that, each class adds its own discriminators. We maintain roughly three hundred class checklists across web, API, authorization, authentication, cloud posture, mobile, dependency, secrets and business-logic families.

The cross-origin sharing checklist is a good example, because it's the worst false-positive class we measure. In one judged sample, 89% of these findings were rejected by human reviewers, and every rejection had the same shape: someone saw a permissive header with a command-line client and called it data theft. Two facts kill most of them, and the checklist asks about exactly those two:

  • Which origin came back? Your attacker origin echoed, a literal wildcard, or an allowlist that excluded you?
  • Did credentials ride along?

Answer wildcard, and the checklist tells the agent, in plain language, why that isn't a disclosure. A browser refuses to attach cookies to a wildcard, so the attacker page receives exactly what anyone could fetch unauthenticated.

Two design decisions here matter more than the questions themselves.

The answer is a small controlled vocabulary; the reason is free text. Prose can't be validated. A one-word answer from a fixed set can. The why: line is where the agent says what it observed that makes the answer true, and a reason under a minimum length isn't a reason.

The questions get seeded into the pad, not stored in a document the agent is told to go read. A mandate inside a document nobody opened isn't a control. We measured this. On findings of one high-rejection class, the relevant guidance skill was loaded on 23% of them. The other 77% were filed by an agent that never saw the guidance. So the checklist arrives in the pad, at the moment the pad opens.

The gate: one classifier, three ways to fail

When the agent files, the pad travels with the finding. Before anything gets written, a gate reads it.

The submission gate: classify the claim, route it to a checklist, and corroborate the agent's answers against the recorded bytes
The submission gate: classify the claim, route it to a checklist, and corroborate the agent's answers against the recorded bytes.

Three things about this flow are deliberate.

Corroboration checks the reasoning against the bytes. The checklist proves the agent reasoned. It doesn't prove the reasoning was true. An agent can answer "the origin was reflected" about an endpoint whose recorded response says wildcard, and every rule in the validator would pass, because the validator only ever saw the answer.

So for the mechanical questions (what header came back, what status was returned, how many distinct requests were actually made) the answer isn't a matter of judgement at all. It's in the evidence the SDK already recorded. Where the claim and the bytes disagree, the agent gets told exactly how. A claim the evidence contradicts is a stronger false-positive signal than any unanswered item, because the agent has asserted something the data it collected doesn't support.

This only works because of tooling as code. The evidence trail exists, in a queryable form, with no cooperation required from the agent.

A "stop" answer doesn't delete the work. When the agent's own answers say this isn't exploitable, there's nothing to correct. But the observation is often still worth keeping. A permissive header is worth a hardening note. So the finding isn't discarded. It's refused at that severity and recorded as an observation. The problem was never that hardening notes existed. It was that they showed up at Medium and above, which is the band humans dismiss.

The gate can't lose findings. This is the constraint every other decision bends around:

  • It only engages for classes that have a checklist. Every other class takes the exact path it did before.
  • The agent gets a bounded number of correction rounds. After that the finding files anyway, with its unresolved items written onto it, where a human can read them. An agent stuck in a correction loop is a worse outcome than a flagged finding.
  • There's an explicit, attributable override. If the routed checklist genuinely can't be answered (a cloud posture issue routed to a checklist that wants a browser session), the agent states why, in a sentence, and the finding files immediately. The reason and the unresolved items get written into the evidence. It doesn't hide the doubt. It records it, with attribution.
  • If the gate itself errors, the submission proceeds exactly as it would have without it. A gate that can fail closed loses findings to its own bugs.

How the two compose

Neither feature is that interesting alone. Together they close a loop.

How the two features compose into a finding someone who was not there can check instead of trust
How the two features compose into a finding someone who was not there can check instead of trust.

Tooling as code produces a durable, citable record of everything the agent did, as a side effect of the agent doing it. Structured scratchpads make the agent reason against that record while it works, and make the conclusion checkable before it gets filed.

Without the SDKs, the pad has nothing solid to cite and the gate has nothing to corroborate against. It can only check that the agent answered, not that the answer was true. Without the pad, the evidence trail is just a pile of exchanges nobody connected to a claim.


What actually changed

On cost and reach. Sweeps that used to be unaffordable (five hundred identifiers, an authorization matrix across four roles, a dependency inventory across a monorepo, a full cloud prescan) are now single operations that return a summary. The budget goes into analysis instead of narration.

On honesty. The interesting shift isn't that fewer false positives get filed. It's that the agent's uncertainty became visible. "Control not run" is now a recorded answer instead of an absence nobody noticed. "Filed with unresolved items" is a state a reviewer can see. An unproven claim gets capped instead of dressed up.

On what a finding is. A finding used to be a paragraph the agent wrote. Now it's a paragraph, plus the notes written while the work happened, plus the specific questions that decide the class with the agent's own answers, plus the exact exchanges that prove it. All bound together so someone who wasn't there can check the reasoning instead of trusting it.

On what "we found nothing" means. With a coverage record, "no vulnerabilities found" is finally a claim with content behind it: here's what was examined, here's what was tried, here's what got explicitly ruled out and why. Without it, that sentence means nothing at all, and it's the sentence customers act on.


Both features are live across the Strobes agent platform: web and API pentest, source code review, network assessment, and cloud posture review.

Tags
Agentic PentestingTooling as CodeStructured ScratchpadsAI SecurityOffensive SecurityAI AgentsPenetration Testing

Stop chasing vulnerabilities Start reducing exposure

See how Strobes AI agents validate and fix your most critical exposures automatically.

Book a Demo
Continue Reading

Related Posts

Top data breaches July 2026
Data BreachesAI Security

Top 8 Data Breaches and Exposures of July 2026

The 8 confirmed data breaches of July 2026, from a 78-million-account Suno leak to rogue AI agents breaching Hugging Face and Anthropic. What happened and how to defend.

Aug 1, 202620 min
What to Evaluate Before You Let an AI Agent Exploit Your Systems
AI SecurityPenetration Testing

What to Evaluate Before You Let an AI Agent Exploit Your Systems

An AI agent that can exploit your systems does an attacker's work. Here are the seven governance checks to clear before you authorize agentic pentesting in production.

Jul 24, 202615 min
Human-in-the-loop security: why AI findings need human validation
AI SecurityPenetration Testing

Human-in-the-loop security: why AI findings need human validation

An AI pentester can hand you a critical finding in minutes. The only question that matters is whether you believe it. Here is why human validation turns a claim into proof.

Jul 24, 202611 min