A campaign is the top-level unit of work in Agentic-AFL. It starts AFL++, co-launches the AgentLoop as an async daemon, monitors edge coverage, and — when a stall is detected — triggers the full Extract → Profile → Retrieve → Generate → Solve → Inject pipeline. Campaigns are driven by theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/AdithyaaSivamal/Agentic-AFL/llms.txt
Use this file to discover all available pages before exploring further.
agentic-afl fuzz subcommand and produce a JSON result file that captures every metric from baseline edges to bypass evidence.
Campaign Lifecycle
Every campaign passes through three phases:Warmup
AFL++ runs alone for the first few minutes with no agent intervention. This establishes the baseline edge count and lets AFL++ saturate the easy, shallow coverage that standard mutation handles well. The baseline is sampled in the first 10 seconds of the campaign.
Stall Detection
The AgentLoop’s
StallDetector polls fuzzer_stats on a configurable interval. When the edge count stops growing for --stall-minutes consecutive minutes (default 5), the stall is queued for agent processing. Stalls are prioritized by severity — CRITICAL stalls are processed before MEDIUM ones.Agent Intervention
The agent runs the full neuro-symbolic pipeline: Ghidra P-Code extraction → constraint profiling → CARM template retrieval → LLM-driven Z3 generation → sandbox execution → payload injection into AFL++‘s sync directory. If all ReAct turns are exhausted without a SAT result, the stall is deferred back to AFL++ for probabilistic mutation.
Basic Campaign Command
./harness with seeds from ./seeds. Progress is printed to the terminal every 25 seconds in a columnar format showing elapsed time, edge count, total executions, stall count, and injection count.
Using the TUI Dashboard
Pass--tui to launch the Rich terminal UI, which gives a live view of both AFL++ and the agent simultaneously:
The
--tui flag requires the rich package (pip install rich). The campaign runs identically with or without it — TUI is a pure display layer with no effect on fuzzing behavior.Fuzzer State
Live metrics read directly from AFL++‘s
fuzzer_stats: edge count, executions per second, corpus size, cycles done, and pending favorites. The baseline edge count is shown alongside the current count so you can see the net gain at a glance.Agent State
The agent pipeline displayed as a stage ladder:
detect → ghidra → profile → carm → probe → llm → z3 → inject → diverse → mutator. Each stage shows active (currently running) or done (completed this cycle), mapped in real time from the agent’s log output.Coverage Chart
A braille-dot sparkline of the edge-count history, updated every 30 seconds. A rising line during the warmup phase that flattens and then jumps after agent injection is the ideal campaign shape.
Event Log
A scrolling log of agent events — stall detections, Z3 verdicts, payload injections, and bypass confirmations — with color-coded severity indicators.
Key Campaign Flags
| Flag | Default | Description |
|---|---|---|
--duration | 1h | Campaign duration. Accepts 6h, 30m, 90s, or integer seconds. |
--stall-minutes | 5 | Minutes of edge plateau before the agent triggers. Lower values make the agent more aggressive; higher values give AFL++ more time to self-recover. |
--accept-marker | ACCEPT | The stdout/stderr string Agentic-AFL watches for to confirm a math wall bypass. Must match what your harness prints on success. |
--custom-mutator | (none) | Path to a Python AFL++ custom mutator deployed after bypass is detected. See Custom Mutator. |
--log-dir | (none) | Directory where the JSON result file is written. The filename is <target>_<timestamp>.json. |
--name | harness stem | Campaign name used in result filenames and the TUI header. Defaults to the harness binary’s filename without extension. |
--tui | off | Enable the Rich terminal dashboard. |
--debug | off | Enable debug logging. Saves every raw LLM completion and Z3 script to /tmp/agentic_afl_debug/ for post-mortem analysis. |
Print Dashboard Format
When--tui is not used, Agentic-AFL prints a columnar dashboard to stdout every 25 seconds with these columns:
Status column shows fuzzing at baseline, stall×N when stalls have been detected, and injected×N after payloads have been written to the AFL++ sync directory.
Campaign Result JSON
When--log-dir is specified, Agentic-AFL writes a JSON result file at campaign end. The file is named <target_name>_<timestamp>.json and is a serialization of the CampaignResult dataclass:
| Field | Description |
|---|---|
target_name | Campaign name (harness stem or --name value). |
baseline_edges | Edge count sampled in the first 10 seconds. |
final_edges | Edge count at campaign end. |
edge_gain | final_edges - baseline_edges. |
edge_gain_pct | Percentage gain relative to baseline. |
bypass_detected | true if the accept marker was observed in a queue entry. |
bypass_time_seconds | Seconds elapsed when bypass was first confirmed. null if no bypass. |
bypass_evidence | Filename of the queue entry that triggered the accept marker. |
payloads_injected | Total payloads written to the AFL++ sync directory (includes diversity variants). |
stalls_detected | Number of stall events queued for agent processing. |
llm_calls | Number of LLM generation requests made. |
react_turns | Total ReAct turns consumed across all stall processing cycles. |
elapsed_seconds | Actual wall-clock campaign duration. |
duration_seconds | Requested duration from --duration. |
timeline | 60-second snapshots of edges and agent activity for plotting. |
mutator_deployed | true if a custom mutator was deployed after bypass detection. |
Visualizing Coverage
Generate a coverage-over-time PNG from any result file with theplot subcommand:
--output is omitted, the image is saved alongside the JSON with a .png extension.
Interpreting Results
edge_gain_pct
The primary health metric. Values above 50% indicate meaningful new coverage unlocked by the agent. Gains above 200% typically mean the agent bypassed a dispatch-table gatekeeper that gates multiple handlers.
bypass_detected
Confirms the accept marker was printed by a queue entry. This is ground truth — a
true here means at least one payload in the AFL++ queue makes the target’s validation logic accept the input.payloads_injected
Includes both the primary solved payload and any diversity variants generated by the
DiversityGenerator after a successful solve. A high count relative to stalls_detected means the diversity generator ran, which is a good sign.The agent runs asynchronously — it never pauses AFL++. AFL++ continues fuzzing at full speed while the agent’s pipeline (Ghidra, LLM, Z3) runs in the background. In the TUI you can observe both running simultaneously: the exec/s counter keeps climbing while agent pipeline stages advance.