Ravage is a source-checkout research workspace for autonomous web application testing on controlled, authorized targets. The core design is evidence-first: models propose work, but scoped tools, typed observations, deterministic control, evidence gates, and reports decide what executes and what becomes a finding.
This page describes the current implemented architecture, not an old execution plan. It deliberately distinguishes the frozen evaluated base from the post-evaluation graph route. The published 85/104 XBEN run exercised the base hybrid proposal/selection loop and its bounded specialists; it did not exercise the newer graph or remote HTTP route.
Think of Ravage as five control layers:
The model is useful for planning, but it is not trusted as policy or proof. Tool output is evidence input. Reports are accepted only after the evidence path is recorded and the applicable proof gate passes.
The current checkout exposes two execution lanes:
Text fallback:
authorized brief
+-> local: frozen base -> eligible unsolved stop -> opt-in graph -> local tools
`-> remote: explicit authorization -> direct graph -> structured HTTP only
both -> typed observations -> proof gate -> durable audit and terminal outcome
packages/ravage: runtime package, CLI, agent loop, tools, benchmarks, labs,
reports, source-guided workflows, and the additive autonomous graph.packages/schemas: shared schema package published as ravage-schemas,
imported as pentest_schemas.packages/agents/*: early specialist-agent packages.packages/mcp_servers/*: MCP wrappers for external tools.ravage xben: XBEN runner used for controlled benchmark execution.The console command is ravage, implemented by
packages/ravage/src/ravage/__main__.py.
Primary operator commands:
ravage attack: model-driven ai-web execution.
--autonomous-route --autonomous-route-engine agent-graph opts into the
bounded graph route. Remote HTTP additionally requires
--authorized-remote-target.ravage scan: deterministic DAST without model calls.ravage tools: tool-runtime list/check helpers. Tool installation lives in
scripts/install_tools.sh.ravage lab: local lab management helpers.ravage observe: live dashboard for an existing run.ravage audit verify: audit hash-chain verification.ravage competitors: isolated competitor-harness workflows.Benchmark entry points:
ravage xben ...: official-style XBEN validation benchmark runs.ravage benchmark ...: compatibility alias for ravage xben.scripts/run_memory_eval.py: memory off/read comparison.scripts/grade_xben_failures.py: post-run failure categorization.The ai-web loop builds a prompt from the brief, scope, discovered target state,
available tools, memory hints, source-guided observations, planner
recommendations, and prior findings.
The model must return one JSON action. The runtime validates the action, checks scope, executes the tool, records the observation, and appends the observation to the next model turn. Tool output is wrapped as untrusted observation data so target-controlled text cannot masquerade as agent instructions.
The agent supports two modes:
hybrid: normal local/manual operation with runtime recommendations,
deterministic proof support, and evidence gates.ctf-free-roam: benchmark/CTF mode that encourages bounded autonomous
exploration and flag capture.The frozen 2026-07-12 XBEN result came from this base architecture. It used one stateful planner, deterministic proposal selection, persistent mission state, 23 evidence-promotion rules, 26 bounded specialists, repetition control, and a tool-origin proof gate. The base remains the local first stage and retains its 40-request default. The graph route does not silently replace or enlarge that budget.
The additive agent-graph route is a durable execution graph, not a prompt that
merely tells one agent to try harder. Its default hard limits are six nodes, two
concurrent nodes, 24 model requests, 96 tool calls, a 20-minute wall clock, and
four model requests reserved for proof work. A configured cost ceiling is also
global. These limits are persisted with graph identity and checked in code.
The route has the following control structure:
Budget growth is graduated rather than granted up front. The most constrained global budget controls the phase:
| Pressure | Phase | Enforced behavior |
|---|---|---|
| below 70% | Explore | finite, objective-scoped exploration is allowed |
| 70–85% | Focus | stop broad recon; admit only named evidence-backed work |
| 85–100% | Close | admit only proof or closure work |
| 100% | Exhausted | only submit proof or finish |
The graph is run-local adaptive control, not online model training. Coverage, failures, observations, and decisions improve later choices in the same durable run. Cross-run or cross-target learning is not silently applied.
For a local target, --autonomous-route always starts with the base unless
valid base artifacts already exist for a resume. The graph enters only when the
base has no confirmed proof and terminates through request-budget or exploration
exhaustion. A solved base, cost stop, error, or interruption does not
automatically open more work.
The graph reuses the verified local runtime handoff and can call the existing
bounded probes, proof validators, command/Python actions, and structured HTTP
executor under the brief’s scope. Its state lives below
workspace/autonomous-route/agent-graph/, separate from base artifacts.
Remote operation is a separate production boundary:
ravage attack brief.yaml \
--authorized-remote-target \
--autonomous-route \
--autonomous-route-engine agent-graph \
--operational-profile low-noise \
--autonomous-route-max-requests 24 \
--run-dir runs/authorized-remote
All target origins must still be declared in the brief. The acknowledgement flag does not expand scope; it only allows a declared non-local target to pass the remote-entry guard.
The remote route deliberately exposes only http_request. It does not expose a
shell, browser, process runtime, external scanner, or arbitrary proxy. Every
request and redirect hop is same-origin/scope checked, DNS identity is pinned
for the run and fails closed on change, sensitive headers are removed on
scoped cross-origin redirects, and request counts survive resume. Methods,
headers, body size, response size, timeout, redirects, and total requests are
bounded. Each hop produces a receipt, and proof recognition uses the target
response rather than model prose.
Remote HTTP defaults to the low-noise profile:
This is traffic restraint and auditability, not stealth, fingerprint evasion, WAF bypass, persistence, or an assurance that testing will be undetected.
Structured actions include:
http_request, http_get, http_post_json, form_post,
graphql_request, xml_request, set_cookie, set_header.browser_open, browser_fill, browser_click,
browser_submit, browser_login, browser_extract_forms,
browser_snapshot, browser_cookies, browser_local_storage.nmap, whatweb, ffuf, katana, nuclei, sqlmap,
nikto, DNS lookup, and terminal sessions for approved commands.run_command and run_python actions.The runtime can execute external tools on the host, in Docker, or in auto mode.
Briefs can declare required and optional capabilities. Missing required
capabilities fail closed unless --allow-degraded is explicit.
These broad tools describe the local base and local graph runtime. They are not available through the remote HTTP-only route.
When source context is available, Ravage parses routes, parameters, sinks, headers, credentials, JWT/session logic, upload flows, GraphQL shapes, and framework-specific patterns. Source-guided workflows then attempt bounded dynamic proof against the running target.
Implemented workflow areas include:
These workflows are not benchmark shortcuts. They are reusable proof loops that turn source signals into scoped runtime attempts and still require live target evidence before reporting.
Ravage separates hints, attempts, and accepted findings:
capture_flag is accepted.Runs write:
audit.db: tamper-evident audit rows.workspace/events.jsonl: runtime events.workspace/transcript.jsonl: model and observation transcript.workspace/artifacts/: large outputs.report.json: machine-readable report.report.html: rendered report when available.ravage scan, the default ravage attack, and the broad local tool runtime
remain localhost-first. A non-local attack is rejected unless the operator
explicitly acknowledges authorization and selects the HTTP-only agent graph.
The target must still match the brief’s declared scope and rules of engagement.
Local HTTP, browser, and external-tool actions are scope checked. Docker-backed tools apply scoped egress firewall rules where supported. The remote graph has a narrower capability surface and independently checks every request and redirect before transport.
The system is designed for authorized research, local labs, controlled benchmarks, and explicitly scoped assessments. It is not designed for persistence, broad internet scanning, detection bypass, or unsanctioned exploitation.
Important limits still remain:
See Technical Guide for implementation pointers.