> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vigolium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Autopilot

> The single-loop agentic scan: one long-running olium engine drives tools, reports findings, and halts on its own.

`vigolium agent autopilot` is the **single-loop agentic scan**, one long-running LLM session decides what to investigate, drives tools (bash, file I/O, web fetch, vigolium CLI commands), reports findings to the database as it confirms them, and halts on its own when it has nothing productive left to do.

It is the simplest of the agentic-scan modes, there is no master/worker pipeline, no plan/triage phase split, just one engine running until it calls `halt_scan`.

***

## Mental model

Think of it as a security analyst sitting at a terminal:

* The analyst is given a target URL, optionally a source tree, and a focus hint.
* They have shell access, file-read access, web access, and the vigolium CLI.
* They poke around, follow leads, write findings to a notebook as they confirm each bug, and stop when there is nothing more worth digging into.

The autopilot is exactly that, except the analyst is an LLM and the notebook is the vigolium `findings` table.

***

## Lifecycle (high-level)

```
                  ┌──────────────────────────────────────────────┐
 vigolium agent ─►│ 1. CLI flag parsing                          │
 autopilot …      │    intensity preset → max-cmds, timeout, …   │
                  │                                              │
                  │    --input → curl/HTTP/Burp/url normalize    │
                  │    --source → resolve git URL/diff/local     │
                  │    --provider/model → olium.ResolveProvider  │
                  └──────────────────────────────────────────────┘
                                       │
                                       ▼
                  ┌──────────────────────────────────────────────┐
                  │ 2. Session bootstrap                         │
                  │    EnsureSessionDir(~/.vigolium/agent-…/UUID)│
                  │    WriteRunPID, CleanupOrphanedProcesses     │
                  │    create AgenticScan row (status=running)   │
                  │    tee stdout → {session}/runtime.log        │
                  └──────────────────────────────────────────────┘
                                       │
                                       ▼
                  ┌──────────────────────────────────────────────┐
                  │ 3. autopilot.Run (pkg/olium/autopilot)       │
                  │    build system prompt + initial user prompt │
                  │    register tools: builtins + halt_scan +    │
                  │      report_finding + load_skill             │
                  │    engine.New + engine.Run(ctx, initial)     │
                  └──────────────────────────────────────────────┘
                                       │
                       ┌───────────────┴───────────────┐
                       ▼                               ▼
              ┌────────────────┐              ┌─────────────────┐
              │ provider       │  multi-turn  │ tool registry   │
              │ (codex /       │◄────────────►│ bash, read,     │
              │  anthropic /   │   tool calls │ write, edit,    │
              │  openai / …)   │              │ ls, grep, glob, │
              └────────────────┘              │ web_fetch,      │
                                              │ load_skill,     │
                                              │ halt_scan,      │
                                              │ report_finding  │
                                              └─────────────────┘
                                       │
                                       ▼
                  ┌──────────────────────────────────────────────┐
                  │ 4. Halt → finalize                           │
                  │    halt_scan called OR ctx done OR max turns │
                  │    UPDATE AgenticScan: status, duration,     │
                  │    finding_count, error_message              │
                  │    print summary, remove run.pid             │
                  └──────────────────────────────────────────────┘
```

***

## CLI

```bash theme={null}
# Basic autonomous scan
vigolium agent autopilot -t https://example.com

# With source code (auto-runs vigolium-audit first)
vigolium agent autopilot -t http://localhost:3000 --source ~/projects/my-app

# Tighter scope with intensity preset
vigolium agent autopilot -t https://example.com --intensity quick

# Deep pentest with browser-assisted auth
vigolium agent autopilot -t https://app.example.com --intensity deep \
  --browser --credentials "admin/admin123"

# Focus a specific area
vigolium agent autopilot -t https://api.example.com --focus "auth bypass"

# Pipe a curl command — target auto-derived
echo "curl -X POST https://example.com/api/login -d '{\"user\":\"admin\"}'" \
  | vigolium agent autopilot

# Raw HTTP / Burp pair input
vigolium agent autopilot --input "POST /api/search HTTP/1.1\r\nHost: example.com\r\n\r\nq=test"

# Source-aware on changed files only
vigolium agent autopilot -t https://example.com --source ./app \
  --diff main...feature/payments

# Last 5 commits as focus
vigolium agent autopilot -t https://example.com --source ./app --last-commits 5

# Use a different olium provider
vigolium agent autopilot -t https://example.com \
  --provider anthropic-api-key --model claude-opus-4-7

# Natural-language prompt (parsed by AI to extract target/source/focus)
vigolium agent autopilot "scan VAmPI source at ~/src/VAmPI on localhost:3005"

# Dry-run: preview the rendered system prompt
vigolium agent autopilot -t https://example.com --dry-run

# # CI scan with quick intensity
vigolium agent autopilot -t https://staging.example.com \
  --intensity quick --upload-results
```

### Key flags

| Flag                                               | Default                  | Description                                                                                                                                                           |
| -------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-t, --target`                                     | ,                        | Target URL (derived from `--input` if omitted)                                                                                                                        |
| `--input`                                          | ,                        | Raw input (curl, raw HTTP, Burp XML, base64, URL). Reads stdin if piped                                                                                               |
| `--record-uuid`                                    | ,                        | Use an HTTP record from the database as the seed input                                                                                                                |
| `--source`                                         | ,                        | Path to application source code (or git URL, auto-cloned). Auto-runs vigolium-audit.                                                                                  |
| `--files`                                          | ,                        | Specific files to include (relative to `--source`)                                                                                                                    |
| `--focus`                                          | ,                        | Focus area hint (e.g. `"auth bypass"`, `"API injection"`)                                                                                                             |
| `--instruction` / `--instruction-file`             | ,                        | Custom instruction appended to prompt                                                                                                                                 |
| `--intensity`                                      | `balanced`               | Preset bundle: `quick` / `balanced` / `deep`. Sets the command budget (quick=150, balanced=500, deep=1500 turns), audit mode, browser, and pre-scan strategy          |
| `--audit`                                          | `lite` (with `--source`) | Vigolium-audit mode: `lite` / `balanced` / `deep` / `mock` / `off`                                                                                                    |
| `--browser`                                        | false                    | Enable agent-browser for browser-based interactions                                                                                                                   |
| `--credentials`                                    | ,                        | Credentials for auth preflight (e.g. `"admin/admin123"`)                                                                                                              |
| `--auth-required`                                  | false                    | Require auth/session preparation before the operator starts                                                                                                           |
| `--requires-browser`                               | false                    | Require browser-assisted auth instead of HTTP-only preflight                                                                                                          |
| `--browser-start-url`                              | ,                        | Explicit browser/login start URL                                                                                                                                      |
| `--focus-routes`                                   | ,                        | Protected/browser-focused routes to prioritize                                                                                                                        |
| `--diff`                                           | ,                        | Focus on changed code (PR URL, `main...branch`, `HEAD~N`)                                                                                                             |
| `--last-commits`                                   | ,                        | Shorthand for `--diff HEAD~N`                                                                                                                                         |
| `--max-duration`                                   | 6h                       | Wall-clock cap (intensity preset sets this — quick=1h, balanced=6h, deep=12h)                                                                                         |
| `--triage`                                         | false                    | Run an AI triage pass over findings after the scan (confirm real issues vs false positives)                                                                           |
| `--skill`                                          | ,                        | Force-load these skills by name, bypassing the pre-flight selection (repeatable or comma-separated)                                                                   |
| `--skill-tag`                                      | ,                        | Force-load every skill carrying one of these tags (e.g. `xss,idor`)                                                                                                   |
| `--no-skill-filter`                                | false                    | Load the full skill set; skip the pre-flight skill selection                                                                                                          |
| `--db-isolate`                                     | false                    | Scan into a private temporary database, then merge results into `--db` at the end (lets parallel runs share one DB; SQLite only)                                      |
| `--plan-file`                                      | ,                        | Plan file mixing free-text guidance + raw HTTP request(s); owns the instruction + seed input (mutually exclusive with `--input`/`--instruction`/`--instruction-file`) |
| `--piolium`                                        | ,                        | Run piolium audit instead of vigolium-audit when `--source` is set (`lite`/`balanced`/`deep`/`longshot`/…); empty auto-picks piolium when `pi` is installed           |
| `--no-prescan`                                     | false                    | Skip the native pre-scan that seeds http\_records before the operator (target-only runs; no-op with `--source`)                                                       |
| `--upload-results`                                 | false                    | Upload session bundle to cloud storage on completion                                                                                                                  |
| `--provider`                                       | *(config)*               | Olium provider override                                                                                                                                               |
| `--model`                                          | *(config)*               | Model id override                                                                                                                                                     |
| `--oauth-cred` / `--oauth-token` / `--llm-api-key` | *(config)*               | Provider credential overrides                                                                                                                                         |
| `--system`                                         | ,                        | Extra text appended to the built-in system prompt                                                                                                                     |
| `--dry-run`                                        | false                    | Render prompt without launching agent                                                                                                                                 |
| `--show-prompt`                                    | false                    | Print rendered prompt to stderr before executing                                                                                                                      |

***

## API

```
POST /api/agent/run/autopilot
```

```json theme={null}
{
  "target": "https://example.com",
  "source": "/home/user/src/my-app",
  "focus": "API injection",
  "intensity": "balanced",
  "audit": "balanced",
  "max_commands": 500,
  "max_duration": "6h",
  "browser": false,
  "diff": "main...feature/payments",
  "stream": true
}
```

`EffectiveSourcePath()` accepts either `source` or the legacy `repo_path` JSON field. The server resolves provider/model from `agent.olium.*` by default; pass `api_key`, `oauth_token`, `oauth_cred_file`, or `oauth_cred_json` on the same request to override per call. Returns `202 Accepted` with `{agentic_scan_uuid, status}`. Set `stream: true` for an SSE response.

***

## What the agent actually has access to

The autopilot is **not** restricted to the vigolium CLI. The engine ships a generic agentic toolset; security-specific behavior comes from the system prompt and skills, not from the tool surface itself.

| Tool             | Notes                                                                     |
| ---------------- | ------------------------------------------------------------------------- |
| `bash`           | Unsandboxed shell. Catastrophic patterns (e.g. `rm -rf /`) hard-rejected. |
| `read_file`      | Read-only. Parallelizable.                                                |
| `write_file`     | Side-effect; serial only.                                                 |
| `edit_file`      | Side-effect; serial only.                                                 |
| `ls`             | Parallelizable.                                                           |
| `grep`           | Parallelizable.                                                           |
| `glob`           | Parallelizable.                                                           |
| `web_fetch`      | Parallelizable.                                                           |
| `load_skill`     | Pulls a skill body by name (skills are indexed in the system prompt).     |
| `halt_scan`      | Autopilot-only. Sets `HaltSignal`, engine exits naturally next turn.      |
| `report_finding` | Autopilot-only. Writes a `Finding` row scoped to the AgenticScan UUID.    |

The model decides when to invoke `vigolium scan-url`, `vigolium finding`, etc., those are **shell commands**, not first-class tools. The agent runs them via `bash` if it judges them useful.

***

## Provider selection

`olium.ResolveProvider` picks the backend in this order:

1. CLI override (`--provider`)
2. Config file (`agent.olium.provider` in `vigolium-configs.yaml`)
3. Default → `openai-compatible` with `gemma4:latest` (a local Ollama endpoint)

Supported provider IDs:

| Provider                      | Typical model                  | Credential                                                                                                   |
| ----------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `openai-codex-oauth`          | `gpt-5.5`                      | OAuth cred file (`--oauth-cred` / `agent.olium.oauth_cred_path`)                                             |
| `anthropic-api-key`           | `claude-opus-4-7`              | `--llm-api-key` / `$ANTHROPIC_API_KEY`                                                                       |
| `anthropic-oauth`             | `claude-opus-4-7`              | Bearer token from `claude setup-token` (`--oauth-token` / `$ANTHROPIC_API_KEY`)                              |
| `openai-api-key`              | `gpt-5.5`                      | `--llm-api-key` / `$OPENAI_API_KEY`                                                                          |
| `openai-responses`            | `gpt-5.5`                      | `--llm-api-key` / `$OPENAI_API_KEY` (public OpenAI Responses API, `/v1/responses`)                           |
| `anthropic-cli`               | `claude-opus-4-7`              | The local `claude` binary on `$PATH` (alias: `anthropic-claude-cli`)                                         |
| `anthropic-claude-sdk-bridge` | Claude Code default            | Logged-in Claude Code subscription via the `vigolium-audit bridge` sidecar (`--bridge-bin` override); no key |
| `anthropic-compatible`        | via `custom_provider.model_id` | `custom_provider.base_url` (Anthropic Messages `/v1/messages` gateway / proxy)                               |
| `anthropic-vertex`            | `claude-opus-4-6`              | GCP service-account JSON + project/location                                                                  |
| `google-vertex`               | `gemini-2.5-pro`               | Same GCP creds; routes `gemini-*` models                                                                     |
| `openai-compatible`           | `gemma4:latest`                | `custom_provider.base_url` (Ollama, OpenRouter, LM Studio, vLLM, …); `api_key` optional                      |

Prompt caching (`EnablePromptCache: true`) is set on the engine; only the Anthropic providers and the Codex OAuth provider actually emit cache markers — `openai-compatible` (including Ollama), `openai-api-key`, and `openai-responses` ignore them.

***

## Intensity presets

`--intensity` bundles several settings; explicit flags always override.

| Preset               | `MaxCommands` | `Timeout` | `Vigolium-audit mode` | `Browser` |
| -------------------- | ------------- | --------- | --------------------- | --------- |
| `quick`              | 150           | 1h        | `lite`                | on        |
| `balanced` (default) | 500           | 6h        | `balanced`            | on        |
| `deep`               | 1500          | 12h       | `deep`                | on        |

`MaxCommands` is the autopilot's own turn cap (the agent's `DefaultAutopilotMaxTurns` is 200; intensity overrides it). When the cap is hit the run ends with an error event — the model didn't get to halt cleanly. `agent.olium.max_turns` applies to the shorter, non-autopilot engine uses (swarm phases, source analysis, query), not to autopilot.

***

## Halt conditions

The autopilot exits in one of four ways:

1. **Natural halt**: model calls `halt_scan`. The current turn is allowed to finish; the engine then sees no further tool calls on the next turn and emits `EventRunDone`. `Result.Halted=true`, `HaltReason` populated.
2. **Quiet halt**: model finishes a turn with no tool calls and no `halt_scan`. Treated as a natural stop.
3. **Max turns**: turn count hits `MaxCommands`. Engine emits an `EventError`; autopilot returns a non-nil error.
4. **Context cancelled**: timeout or SIGINT/SIGTERM. Engine teardown cancels in-flight tools.

A separate **finding rate-limit** lives inside `report_finding`:

* soft warning at 50 findings (still saved)
* hard cap at 200 (rejected with an `IsError` result that nudges the model toward `halt_scan`)

***

## Findings persistence

Every successful `report_finding` call writes a row via `repo.SaveFindingDirect`. Key fields:

* `ProjectUUID`, `ScanUUID`, `AgenticScanUUID`, propagate the project/scan scope so `vigolium finding` and `vigolium agent sessions` can join back.
* `ModuleID = "olium-autopilot"`, `ModuleType = "ai-agent"`, `FindingSource = "autopilot"`, distinguishes agent-originated findings from scanner-module findings.
* `FindingHash`: SHA-256 over (title, severity, source\_file, url, description-fingerprint), or over an explicit `dedup_key` if the model supplies one. The DB's `ON CONFLICT` handler squashes duplicates.

Because the autopilot writes findings as it confirms them, partial results survive a crash or timeout, the parent `AgenticScan` row is just updated to `status=failed` with the error message, but everything saved before that point stays in the DB.

***

## Session artifacts

For each run, autopilot creates a UUID-named directory under `agent.sessions_dir` (default `~/.vigolium/agent-sessions/`):

```
~/.vigolium/agent-sessions/{run-uuid}/
  ├── run.pid          # pgid + start time; cleared on exit
  ├── runtime.log      # tee of stdout (assistant text stream)
  └── vigolium-audit/  # vigolium-audit subprocess output (when --source is provided)
```

The run UUID matches the `AgenticScan.uuid` row, so `vigolium agent sessions` and `vigolium log <uuid>` both work without extra plumbing. Stale dirs older than 48h are swept on startup; orphan PID files (from SIGKILL'd runs) are cleared via `agent.CleanupOrphanedProcesses`.

***

## Source-aware mode

When `--source` is set, three things change:

1. **Source resolution**: accepts local paths, git URLs (cloned to a temp dir), `--diff PR-url|ref...ref|HEAD~N`, and `--last-commits N`. The agent gets a local path and (optionally) a list of changed files.
2. **Initial prompt mode hint**: the prompt switches between blackbox ("probe the live target"), whitebox ("navigate the source tree"), or a greybox blend ("read the code to find what's risky, then probe").
3. **Skill scope**: embedded skills + `~/.vigolium/skills/` are indexed in the system prompt; scan-specific skills like `audit-auth` and `triage-finding` are loadable via `load_skill`.

Vigolium-audit also runs first (foreground) when `--source` is set, freezing its findings into `vigolium-audit/` for the operator to consult.

***

## Multi-app fan-out

When the positional prompt parses to **multiple** apps (`vigolium agent autopilot "scan source at ~/src/A, ~/src/B"`), the package-level autopilot flags are snapshotted and reapplied per app, then `runAutopilotOlium` is invoked sequentially for each. Each app gets its own session dir, AgenticScan row, and provider session.

A single-app prompt re-enters `runAgentAutopilot` directly with the parsed flags, same code path as a flag-driven invocation.

***

## REST API workflow

```
POST /api/agent/run/autopilot   # async kickoff, returns run UUID
GET  /api/agent/status/list     # list active/recent runs
GET  /api/agent/status/:id      # poll a single run
GET  /api/agent/sessions/:id/logs  # tail runtime.log (SSE supported)
GET  /api/agent/sessions/:id/artifacts  # browse session directory
```

The HTTP request body mirrors the CLI flags. The handler resolves provider/source the same way the CLI does, then enters `autopilot.Run` on a goroutine; the run UUID is returned immediately.

***

## TL;DR

Autopilot is a single LLM agent on a leash made of `MaxCommands` turns and `Timeout` wall-clock. It gets shell, files, and the web; vigolium-specific behavior is encoded entirely in the system prompt, two custom tools (`halt_scan`, `report_finding`), and the optional skills under `~/.vigolium/skills/`. Findings are written as it goes; the run ends when the model halts itself, hits the turn cap, or gets cancelled.
