July 30, 2026
From Zero to Report: Running One Real Engagement Through the Full Pipeline
Part 5 of the Aii-Aii Hunter series: scope setup through a delivered finding, walked through on one example engagement
By rohan badekan
5 min read
Part 5 of the Aii-Aii Hunter series: scope setup through a delivered finding, walked through on one example engagement
By Rohan Badekan
Part 5 of 6. Parts 2–4 built the individual layers: skills, hooks, MCP execution. This post assembles them into a state machine you can resume across sessions, and walks a single example engagement (aaa-corp) through every phase. Companion repo: aii-aii-hunter, config/scope.example.json.
Every layer built so far — skills that encode judgment, hooks that enforce scope, MCP that executes against real tools — is capability. None of it is process. Capability answers "can the agent test for IDOR correctly." Process answers a different question: "where am I in a six-week engagement, what have I already covered, and can I close my laptop tonight and pick this back up tomorrow without re-explaining any of it."
That's the job of the orchestrator layer, and the whole thing hinges on one design decision: everything lives in a single state file per engagement.
Why one state file changes everything
scope.json isn't just configuration — it's the entire memory of the engagement. Every phase reads it to know what's already done, writes to it when it finishes something, and a brand-new Claude Code session (tomorrow, next week, on a different machine) can pick the pipeline back up by reading exactly one file and continuing from the first incomplete phase. No conversation history required, no re-explaining the target. That's what "resumable" actually means in practice, and it's only possible because nothing about engagement state lives in the model's context — it lives on disk.
Let's walk aaa-corp through all six phases.
Phase 1 — Scope
The pipeline starts with an interactive questionnaire: engagement type (bug bounty, client pentest, red team), primary targets, out-of-scope exclusions, environment, access model. Nothing unusual so far — most tooling asks some version of these questions.
The part worth dwelling on: authorization has to be its own explicit, separate confirmation step — not something implied by the operator having answered the targeting questions. It's tempting to skip this as redundant ("I just told you the targets, obviously I'm authorized to test them"), but this single checkpoint is what every other phase in the pipeline trusts unconditionally. Recon runs without asking again. The scope guard from Part 3 enforces the targets you named, but nothing technical enforces that you were actually allowed to name them — that has to be a deliberate human attestation, made once, at the one point in the whole system where a human is unambiguously in the loop before anything active happens.
For aaa-corp, that looks like: targets aaa-corp.example + *.aaa-corp.example, one out-of-scope subdomain (staging.aaa-corp.example), bug bounty engagement type, no DoS testing per program rules. All of it lands in scope.json — see the full example schema in the repo — and phases.scope.status flips to complete only after the authorization question is answered explicitly, not implicitly.
Phase 2 — Recon
Recon behavior isn't uniform across engagement types, and this is a deliberate design choice, not an oversight. A bug bounty engagement runs aggressively by default — subdomain enumeration, DNS resolution, live-host probing, URL crawling, and an initial nuclei sweep, all sequentially, no checkpoints, because bounty programs generally expect and tolerate that noise level. A client pentest gates the noisier steps (brute-force subdomain discovery, port scanning) behind a confirmation prompt, because a client's infrastructure team might be actively watching alerts fire and you don't want to trigger a false incident response at 2am on day one. A red team engagement defaults to passive-only reconnaissance and requires an explicit ask before any active step, because the entire premise of red teaming is staying under detection thresholds.
Same phase, same code path, three different postures — selected automatically from engagement.type in scope.json, not something you have to remember to configure separately every time.
For aaa-corp (bounty), this runs unattended: subfinder → DNS resolution → live-host check → URL crawl → an initial gf-pattern classification pass that buckets candidate URLs by likely vulnerability class (XSS candidates, SSRF candidates, and so on) for the next phase to prioritize.
Phase 3 — Surface
Raw recon output is a pile of URLs and hostnames. Surface mapping turns that pile into a prioritized queue: match tech-stack fingerprints (from response headers, cookies, framework tells) against the skill library from Part 2, boost anything a nuclei template already flagged, and produce an ordered hunt_queue — which skills, against which URLs, in what order.
This is also where engagement-type awareness shows up again: a client pentest always includes a full OWASP baseline sweep regardless of what the fingerprinting suggests (a client is paying for coverage, not just signal-chasing), while a bounty hunt leans harder into whatever the tech stack actually surfaced, to spend limited time where a real finding is more likely.
For aaa-corp, fingerprinting turns up a Node.js/Express stack behind Cloudflare — which bumps prototype pollution and cache-poisoning skills up the queue, alongside whatever the URL classification pass already flagged as XSS or IDOR candidates.
Phase 4 — Testing track: Kali hunt, Burp, or both
Before active testing starts, there's one choice: run the Kali-driven hunt skills from Part 2, run the Burp-based pipeline (deeper request/response manipulation, Collaborator-confirmed blind classes, multi-step attack chains), or both and merge the results.
For a quick bounty triage pass, Kali alone is usually enough — fast, broad, skill-driven coverage. For a client engagement where depth matters more than speed, Burp's chain-testing and business-logic-focused workflow earns its extra time. aaa-corp runs both, since the goal here is to demonstrate the merge step in Phase 5 anyway.
Either way, this is where Part 4's MCP bridge actually earns its keep — this phase is nothing but skills issuing probe steps that turn into real tool calls, batch after batch, each producing draft findings.
One thing worth restating here because it's operationally relevant, not just philosophical: there's a real line between detecting that a vulnerability class might exist and exploiting it for maximum proof. Part 6 covers the validation discipline around this in full, but it starts mattering the moment testing begins, not just at write-up time — a probe step that escalates from "confirm the parameter is vulnerable" to "extract as much data as possible" is a different risk profile, and skills should default to the minimum needed to prove impact, not the maximum available.
Phase 5 — Validate
Findings from Kali and Burp (and, if you ran static analysis on available source, from that too) get merged and deduplicated by endpoint plus vulnerability class — the same underlying bug found two different ways shouldn't become two separate reports. Then every surviving finding passes through a validation gate before it's considered "confirmed" anything.
Part 6 is the full treatment of what that gate actually checks. The short version for now: a finding that can't clear it doesn't get reported, full stop, regardless of how technically real it looked during testing.
Phase 6 — Report
Confirmed findings route differently depending on engagement type: a bounty submission draft formatted for the platform in question, or a client-facing deliverable with an executive summary and remediation guidance. I'll say explicitly what I said in Part 1: the actual document-generation tooling — templates, formatting automation — isn't part of this series or the companion repo. What matters for this post is the methodology upstream of that: by the time you're at Phase 6, every finding in front of you has already cleared validation, so report-writing is assembly, not triage.
Checkpoints and resuming
Three paranoia levels control how often the pipeline pauses for a human: --paranoid stops after every phase and every individual finding, --normal stops after scope, surface, and validation (the three points where a bad automatic decision would be most expensive to unwind), and --yolo only stops before a report ships, because reports always need human sign-off regardless of how much else ran unattended.
And because everything really does live in scope.json, "resuming" isn't a special feature — it's just what happens when you point a new session at the same engagement directory. The pipeline reads the phase statuses, finds the first one that isn't complete, and continues. Close your laptop mid-recon on a Tuesday, come back Thursday from a different machine, and the only thing that changed is which phase runs next.
What's next
Every finding that reaches Phase 6 in this post got there by surviving a validation gate I've deferred twice now. That gate — what it actually checks, question by question, and why one "no" anywhere kills a finding outright — is the subject of the last post in this series.
A genericized example scope.json matching every phase referenced here is in the companion repo: config/scope.example.json.