Agentic-AFL uses a strict dataclass pipeline. Each stage of the pipeline consumes the output of the previous stage, and no component reaches across stage boundaries. These types are the public data contracts between components — when adding a new field to any dataclass, update both the producer that populates it and the consumer that reads it.Documentation 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.
Data Flow
PCodeInstruction
A single Ghidra P-Code operation extracted from a basic block. P-Code is Ghidra’s architecture-neutral intermediate representation that preserves all semantic information from the original machine code.PCodeInstruction is frozen (immutable).
The original machine code address as a hex string (e.g.,
"0x08001234").The P-Code operation mnemonic (e.g.,
"INT_ADD", "CBRANCH", "LOAD").List of input varnodes as strings (e.g.,
["r0", "0x10", "(ram, 0x20001000, 4)"]).The output varnode, or
None for operations like BRANCH and STORE that produce no output varnode.The full Ghidra P-Code text line, preserved verbatim for debugging and prompt injection.
Resolved function name for
CALL operations (e.g., "crc16_modbus"). None for non-call operations or unresolved indirect calls.PCodeSlice
A taint-bounded backward slice of P-Code instructions from a stall site. The slice contains only P-Code instructions that are data-dependent on the fuzzer’s input buffer (taint source). Instructions resolving to global state not connected to the input are pruned. Produced by:extractor/pcode_slicer.pyConsumed by:
extractor/constraint_profiler.py, orchestrator/llm_client.py
Path to the analyzed binary.
The address where AFL++ coverage stalled (hex string, e.g.,
"0x00401a20").Ghidra’s decompiled function name. May be
"FUN_xxxxx" for stripped binaries.Entry point address of the function containing the stall site (hex string).
Ordered list of P-Code instructions in the backward slice.
Description of the taint origin, e.g.,
"RDI" (x86_64 first argument register) or "input_buffer @ 0x20001000".Number of basic blocks traversed backward to build this slice.
True if the slice was truncated (via assuming(0)) to fit within the LLM token budget.Target CPU architecture enum value. Determines BitVec widths in generated Z3 scripts.
Ghidra’s decompiled C pseudocode for the containing function. Best-effort; may be empty for obfuscated or heavily optimized binaries.
ConstraintProfile
A structural fingerprint of a stall site’s mathematical constraint type. Produced from P-Code analysis; consumed by CARM retrieval for Jaccard similarity matching. This is frozen (immutable) and hashable. Produced by:extractor/constraint_profiler.pyConsumed by:
orchestrator/retrieval_carm.py
Set of
ConstraintTag enum values identifying structural patterns observed in the P-Code slice (e.g., BITWISE_LOOP, CONSTANT_EQUALITY, CALLEE_DEPENDENCY). The full ontology is defined in constants.py.Ratio of bitwise operations (
XOR, AND, OR, shift) to total operations. Range: 0.0–1.0. High density indicates hash/CRC-style constraints.Ratio of arithmetic operations (
INT_ADD, INT_MUL, etc.) to total operations. Range: 0.0–1.0.Maximum nesting depth of loop structures detected in the slice. Used to flag
COUNTED_LOOP and INPUT_DEPENDENT_LOOP tags.Number of distinct symbolic registers (varnodes) referenced in the slice. Higher counts correlate with higher
estimated_complexity.Heuristic difficulty score from
0 (trivial constant equality) to 100 (deeply nested CRC with callee dependencies). Used to order stall processing and select CARM templates.VulnerabilitySpec
A self-contained, JSON-serializable specification for a single stall site. This is the primary data artifact stored in PostgreSQL. It bundles the P-Code slice, constraint profile, and all metadata needed for the Orchestrator to generate a Z3 script without re-running the Extractor. Produced by:extractor/spec_exporter.pyConsumed by:
database/spec_store.py, orchestrator/retrieval_carm.py
Unique 16-character identifier derived as the first 16 hex characters of
SHA-256(binary_path + stall_address). Deterministic — the same binary and address always produce the same ID.Absolute path to the analyzed binary.
The stall site address (hex string).
Containing function name from Ghidra.
The full extracted P-Code backward slice.
The structural constraint fingerprint computed from the slice.
Target CPU architecture.
A previously successful Z3 script for a structurally similar constraint profile, retrieved from CARM. Injected into the LLM prompt as a starting point.
Ordered list of past error→correction pairs accumulated across all ReAct turns for this stall. Fed to the LLM as negative examples to prevent repeated mistakes.
UTC timestamp when this spec was first created by
SpecExporter.UTC timestamp of the most recent solve attempt, or
None if never attempted.Number of times a payload has been successfully injected for this spec.
CorrectionEntry
A single error→correction pair from a past Z3 generation attempt. Stored inVulnerabilitySpec.correction_history to give the LLM a record of prior failures (negative examples) when generating repair prompts. CorrectionEntry is frozen.
The error string returned by the Z3 sandbox or the AgentLoop’s incomplete-model checker.
The full Z3Py script that was submitted when this error occurred (not necessarily a corrected version — it is the script that produced the error).
UTC timestamp when this correction entry was created.
StallReport
A report from the stall detector indicating a coverage plateau at a specific address. Placed on the AgentLoop’s priority queue for processing. Produced by:fuzzer_bridge/stall_detector.pyConsumed by:
orchestrator/agent_loop.py
The address where coverage stalled (hex string).
Path to the binary being fuzzed.
Priority classification:
CRITICAL, HIGH, MEDIUM, or LOW. Determines queue ordering — CRITICAL stalls are dequeued first.Number of AFL++ cycles that have passed with no new edges at this address.
Raw bytes of the AFL++ queue entry that most recently reached this address. Used as the concrete input context for the LLM prompt.
Filesystem path to the seed file in AFL++‘s
queue/ directory.Snapshot of AFL++‘s coverage bitmap for diffing.
None if not captured.UTC timestamp when the stall was first detected.
Z3GenerationRequest
A request to the LLM to generate Z3 scripts for a specific stall. Bundles all context the LLM needs: the P-Code slice (viaVulnerabilitySpec), seed input, retrieved templates, correction history, and GDB runtime state.
Produced by: orchestrator/agent_loop.pyConsumed by:
orchestrator/llm_client.py
The full vulnerability specification for the stall site, including P-Code slice and constraint profile.
The closest seed input from the AFL++ queue. Provides concrete byte context and determines the input length used for byte-variable counting.
Previously successful Z3 scripts retrieved from CARM for structurally similar stalls. Injected into the LLM prompt as positive examples.
Error→correction pairs from prior ReAct turns. Grows by one entry per failed turn.
Number of parallel Z3 script candidates to generate (K-way voting). Defaults to
settings.k_vote_count.File byte offset where the function’s
input pointer begins. Discovered by the REDQUEEN-style offset probe. When > 0, the LLM is told that input[0] maps to byte_{base_offset} in the full file.GDB-captured memory/register values at function entry, keyed by names such as
"rdi_ptr", "rdi_hex", "rsi_value". Used by the LLM to determine concrete struct field values invisible to static analysis.Z3Script
A Z3Py script generated by the LLM. OneZ3Script is produced per voting candidate per ReAct turn.
Produced by: orchestrator/llm_client.pyConsumed by:
orchestrator/z3_sandbox.py
The full Z3Py Python code, sanitized and ready for sandbox execution. The sandbox strips duplicate
from z3 import *, s = Solver(), and s.check() calls before wrapping.Which of the K voting candidates this script is (zero-indexed,
0 to k_vote_count - 1).Which ReAct turn produced this script (one-indexed).
1 for the initial generation; higher for repairs.Token count of the prompt submitted to the LLM. Used for API cost tracking.
Token count of the LLM’s response. Used for API cost tracking.
The LLM model identifier that produced this script (e.g.,
"gpt-4.1", "gemini-2.0-flash").Z3Result
The result of executing aZ3Script in the sandbox. Carries the solver verdict, the concrete variable model (if satisfiable), error details (if not), and timing.
Produced by: orchestrator/z3_sandbox.pyConsumed by:
orchestrator/agent_loop.py
One of
SAT, UNSAT, TIMEOUT, SYNTAX_ERROR, RUNTIME_ERROR, or UNKNOWN. See constants.Z3Verdict for semantics.When
verdict == Z3Verdict.SAT, a dict mapping Z3 variable names to concrete integer values. Variable names follow the byte_N convention so AgentLoop._model_to_payload() can reconstruct the input buffer. None for all non-SAT verdicts.Error string when verdict is not SAT. This string is fed back to the LLM in repair prompts.
None when verdict is SAT.Wall-clock seconds the sandbox subprocess ran (including subprocess startup overhead).
The
Z3Script that produced this result. Used for pairing errors with the scripts that caused them during the repair selection step.SolvedPayload
A concrete byte-array payload extracted from a SAT model and ready for injection into AFL++‘s sync directory. Produced by:orchestrator/agent_loop.py (via _model_to_payload())Consumed by:
fuzzer_bridge/payload_injector.py
The payload bytes to write to the sync directory. Constructed by overlaying Z3-solved
byte_N values onto the original seed input, preserving seed bytes at positions not covered by the model.The
VulnerabilitySpec.spec_id that this payload solves. Used by the CARM retriever to update the winning template.The stall address this payload is designed to bypass (hex string).
The raw Z3 model dict, preserved for audit logging and harvest-mode verification.
Score from
0.0 to 1.0 representing solve confidence. Currently 1.0 for all single-SAT accepts; future K-way agreement scoring will modulate this.