PATTERN Cited by 1 source
Split bug-and-reachability questions across agents¶
Intent¶
Don't ask one agent "is this a vulnerability?". Split the question into two narrower questions, asked of two separate agents with different scopes:
- Is this code buggy? — answered against the local code.
- Can attacker-controlled input reach this bug from outside the system? — answered against the system's call graph and trust boundaries.
A finding only graduates to vulnerability when both questions get a yes.
Canonical articulation¶
Cloudflare's verbatim formulation (Source: sources/2026-05-18-cloudflare-project-glasswing-what-mythos-showed-us):
"Asking 'Is this code buggy?' and 'Can an attacker actually reach this bug from outside the system?' are two different questions, and the model is better at each one when you ask them separately, because each question is narrower than the combined version."
Why splitting helps¶
The two questions live in different reasoning domains that don't share much context productively:
- "Is this code buggy?" — local code analysis, type reasoning, lifetime tracking, control-flow analysis. The tools needed are the function/file under inspection plus immediate dependencies.
- "Can an attacker reach this bug?" — call graph, cross-repository symbol resolution, request-flow analysis, trust-boundary identification. The tools needed are cross-repo symbol indexes and architecture documentation.
Asked together, the agent must hold both contexts simultaneously, burning context-window budget on each. Asked separately, each agent sees only the context it needs and runs at higher accuracy on a narrower question — exactly the narrow-scoped agent task discipline applied along the question axis.
Architectural shape in Cloudflare's harness¶
In Cloudflare's vulnerability discovery harness the split maps onto two distinct stages:
| Stage | Question | Agent input | Agent output |
|---|---|---|---|
| Hunt | Is this code buggy? | Local code + scope hint + architecture doc | Finding + PoC |
| Trace | Can an attacker reach it? | Cross-repo symbol index + consumer repos + trust boundaries | Reachable / unreachable annotation |
The Trace stage uses the cross-repo tracer fan-out pattern — one tracer agent per consumer repo — because the reachability question is itself parallel across consumers.
Why reachability is the stage that matters most¶
Cloudflare's verbatim — load-bearing for the harness's operational priorities:
"Turns 'there is a flaw' into 'there is a reachable vulnerability.' This is the stage that matters most."
A bug that no attacker-controlled input can reach is not a vulnerability, however severe its local properties. The Trace stage is what lets Cloudflare cross the gap from "hunters are finding plenty" to "how many of these can actually be exploited from outside?" — the prioritisation question security teams care about.
Anti-pattern: combined prompt¶
A single combined prompt — "investigate this function for remotely-exploitable vulnerabilities" — has two failure modes:
- Reachability is hand-waved. The agent inspects local code thoroughly and asserts reachability with weak evidence ("this looks like it would be called from the HTTP handler") because the cross-repo data isn't in scope. Per-finding noise rises.
- Local-bug analysis loses depth. Holding the reachability context costs tokens; the local analysis gets thinner.
The combined prompt produces worse output on both questions than either narrow prompt would.
Generalises beyond vulnerability research¶
The same split applies to several adjacent classes:
- Code-quality review: "Is this code wrong?" vs "Does this wrong code actually run in production paths?". A bug in a code path that's been dead for two years is a cleanup task, not a quality issue.
- Performance investigation: "Is this code slow?" vs "Is this code on the hot path?". A slow function that runs once per startup is irrelevant; the hot-path part is what matters. (See concepts/microbenchmark-vs-end-to-end-gap.)
- Compliance audit: "Does this code violate a rule?" vs "Does the violating path get exercised in scope of the rule?".
The pattern shape — split intrinsic-property analysis from operational-relevance analysis — generalises to any two-axis assessment.
When not to split¶
- When the two questions are genuinely entangled — e.g. an exploit that depends on a specific call-graph shape may require an agent that can reason about both at once.
- When the operational-relevance question is trivial (single- module repo, single entry point) — splitting adds orchestration overhead without information.
- When the cost of cross-stage queue management exceeds the per-agent accuracy gain — small-scale single-codebase audits.
Costs and requirements¶
- Cross-repo symbol index — the Trace stage needs cross-repo lookup. Without one, the reachability agent is guessing.
- Trust-boundary documentation — produced by Recon stage in Cloudflare's harness. Reachability needs to know what outside the system means.
- Per-finding cross-stage join — findings pair with reachability annotations downstream, requiring stable per-finding identifiers.
Seen in¶
- sources/2026-05-18-cloudflare-project-glasswing-what-mythos-showed-us — canonical wiki articulation; one of four design lessons in Cloudflare's harness.
Related¶
- patterns/multi-stage-vulnerability-discovery-harness — the harness that embeds the split as Hunt → Trace.
- patterns/cross-repo-tracer-fan-out — the reachability-side implementation.
- patterns/narrow-scoped-agent-task — the broader discipline this pattern is one axis of.
- patterns/specialized-agent-decomposition — meta-pattern.
- concepts/proof-of-exploitability — the bug-side proof that Hunt stage produces; reachability is what makes that proof a vulnerability.
- concepts/exploit-chain-construction — the bug-side chaining; reachability tells you whether the chain matters.
- concepts/transitive-dependency-reachability — sibling reachability concept on the dependency-graph axis.
- systems/cloudflare-vulnerability-discovery-harness — the canonical implementation.