Agent Loop
0 runs assessments by putting a model in a loop with tools. The model reads the task, proposes tool calls, receives their results, and decides what to do next. Deterministic tool policies, budget checks, and verification constrain that process; model reasoning alone is not evidence.
Loop overview
Section titled “Loop overview”runNativeAgentLoop in packages/core/src/agent/native-loop.ts exchanges
structured messages and tool calls through the configured runtime. Provider
adapters translate its tool_use / tool_result representation to the
appropriate wire protocol. Applicable process runtimes use a legacy text loop.
Each iteration is one turn. The caller supplies maxTurns; budgets differ
by workflow, role, and depth. The loop can finish on done, a qualifying
text-only completion, a limit, cancellation, or an error. Optional compaction,
loop detection, and budget warnings operate around this cycle.
Strategy racing and EGATS are separate opt-in orchestration paths, not steps
every normal loop executes. scan --race is benchmark/CTF-oriented, not a
recommended setting for ordinary live-target audits.
What the agent sees
Section titled “What the agent sees”The system prompt defines the role, available tools, and target approach:
shellPentestPrompt(web) — emphasizesbash,save_findinganddone, with curl/python3/CLI probing. The caller can still expose structured network tools; a prompt’s preferred approach is not the executor’s complete tool list.discoveryPrompt/attackPrompt(LLM/AI) — probing endpoints, extracting system prompts, testing jailbreaks.researchPrompt(source) — map the codebase, trace input → sink, write PoCs.
The prompt includes concrete target details: URL, known endpoints, detected features, and (for attack agents) discovery results.
Tool results append stdout/stderr, HTTP responses, or structured output as
tool_result messages.
Budget prompts continue a turn after a text-only response, escalating with the budget consumed:
| Budget used | Prompt |
|---|---|
| < 30% | Role-specific nudge: interact with the target, or use scoped source tools for review/audit |
| 30-50% | “Summarize what you learned. Top hypothesis?“ |
| 50-70% | “HALFWAY. List every approach tried. Most promising untested vector?“ |
| 70-85% | “URGENCY. If the current approach isn’t working, SWITCH NOW.” |
| 85-100% | “FINAL PUSH. Highest-confidence exploit path ONLY.” |
Strategy changes depend on the model. Feature-gated warnings also apply during tool-call turns. See Budget Management.
Tool execution
Section titled “Tool execution”ToolExecutor in packages/core/src/agent/tools.ts handles tool calls. Web mode uses:
bash— runs shell commands and returns execution output. It is subject to scope and tool policy; by default it executes on the host, not in an OS sandbox.save_finding— records a candidate and its evidence; where database persistence is configured the finding survives beyond the loop. Saving alone is not independent verification.done— signals completion with a summary; setsstate.done = trueand exits.
Other tools by mode: http_request/submit_form (structured HTTP),
send_prompt (LLM), read_file/run_command (source), crawl (spidering),
browser (Playwright). spawn_agent creates one sub-agent with fresh context
to dig into a specific vuln; spawn_agents launches a bounded batch of such
sub-agents with bounded concurrency and their own turn budgets. Their successful
findings merge into the parent after the batch joins. Child errors do not erase
sibling results. Descendants can delegate recursively while retaining the parent’s
role, scope, advertised tool restrictions, shared accounting, and cancellation tree.
They inherit root policy plus their own task, not an accumulating stack of ancestor
tasks. Separate contexts do not mean isolated host filesystems or providers.
Cross-run hunt memory is off by default for local native runs. Embedded callers
can explicitly opt in through codebaseLearning or an injected memory store;
ZERO_DISABLE_HUNT_MEMORY=1 or true vetoes either. Managed source research opts
in only with a configured Cloud sink; managed verification does not. Ordinary
conversation/session history is separate from cross-run learning.
Advisory browser exploration
Section titled “Advisory browser exploration”When Jev browser assistance is explicitly enabled, browser action observe
exposes a compact link snapshot and assist can follow a bounded sequence of
operator-approved read-only URLs. It requires scope and the exact URL allowlist;
the evaluator cannot invent actions, approve a write, fill forms, handle MFA or
confirm a vulnerability. Changed pages, uncertain choices and unavailable
evaluation return a handoff to the main agent. See
Features for setup and data-egress limits.
Model roles and completion signals
Section titled “Model roles and completion signals”The workflow selects the main runtime; child role-model overrides remain subject to that runtime’s supported route and single-model policy. A fresh child context is not an automatic switch of provider credentials.
Tool completion and task success are different signals. A child lifecycle
completed event means its loop returned normally, which can include reaching a
turn budget; inspect its findings and result rather than treating that event as
verified exploit success.
How it decides
Section titled “How it decides”The model chooses hypotheses and actions within the task and available tools. Deterministic policy, scope, playbooks, and evidence gates constrain execution.
Walk-through: IDOR exploitation
Section titled “Walk-through: IDOR exploitation”Illustrative sequence in an authorized disposable lab at http://target:8080
(not a recorded run or a promised turn count):
- Recon.
curl -i http://target:8080/returns a login form and a footer: “Demo credentials: demo / demo”. - Auth.
curl -c /tmp/jar -b /tmp/jar -d 'username=demo&password=demo' -L .../login→ 302 to/dashboardwith a session cookie. - Enumerate.
/profileloads/api/users/1, showing"id": 1, "username": "demo". - IDOR probe.
curl -b /tmp/jar .../api/users/2returns another user:"id": 2, "username": "admin", …, "flag": "FLAG{idor_1a2b3c}". - Save + finish.
save_findingwith the request, the leaking response, and analysis; thendone.
Verify cross-user access under known test identities before accepting the finding.
Debugging
Section titled “Debugging”Use supported --verbose flags for progress and tool detail. Output varies by
workflow and can omit provider-transcript details. Redact logs before sharing.
Common patterns:
- Loops on one payload — inspect repeated tool results, scope denials, and access failures before increasing the budget.
- Provider errors or empty responses — check the reported provider/model, credentials, availability, and rate limits; see Troubleshooting.
- Exits too early — text-only completion requires at least
min(4, maxTurns)turns, nonempty text andend_turn. An accepteddonecan finish sooner; errors, cancellation and limits can also stop the loop. Do not infer a prematuredonefrom turn count alone. - No findings saved — the agent may be finding vulns but not calling
save_finding. Check verbose output.
Saved history and timeline — list runs, then inspect the event timeline for a known scan ID:
0 history --limit 100 timeline <scan-id> --db-path ~/.0/runs/<scan-id>/state.dbtimeline reads the selected database; it does not search every run-local
database by scan ID. Adjust the path if you use a different state directory.
The native loop checkpoints SQLite session state every 2 turns when a database is configured, and persists again at completion. Journal-backed continuation and console transcript resume are different mechanisms. Follow Scan Workflows for scan recovery and Console for chat-session resume; do not assume an interrupted tool can be safely rerun.