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.
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
# Basic autonomous scan
vigolium agent autopilot -t https://example.com
# With source code (auto-runs archon-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 budget caps
vigolium agent autopilot -t https://staging.example.com \
--intensity quick --token-budget 200000 --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 archon. |
--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 |
--archon | lite (with --source) | Archon 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-commands | 100 | Max LLM turns the agent can take |
--max-duration | 6h | Wall-clock cap |
--token-budget | 0 | Cap on cumulative input+output tokens (0 = no cap) |
--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
{
"target": "https://example.com",
"source": "/home/user/src/my-app",
"focus": "API injection",
"intensity": "balanced",
"archon": "balanced",
"max_commands": 100,
"max_duration": "6h",
"token_budget": 200000,
"browser": false,
"diff": "main...feature/payments",
"stream": true
}
EffectiveSourcePath() accepts either source or the legacy repo_path JSON field. Provider/model overrides are CLI-only — the server resolves them once from agent.olium.* and reuses across requests. 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:
- CLI override (
--provider)
- Config file (
agent.olium.provider in vigolium-configs.yaml)
- Auto-detect →
codex-oauth
Supported provider IDs:
| Provider | Default model | Credential |
|---|
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 |
claude-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 |
claude-code-cli | claude-opus-4-7 | The local claude binary on $PATH |
Prompt caching (EnablePromptCache: true) is set on the engine — providers that support it (Anthropic, Claude OAuth) cache the system prompt + tool list across turns.
Intensity presets
--intensity bundles several settings; explicit flags always override.
| Preset | MaxCommands | Timeout | ArchonMode | Browser |
|---|
quick | 30 | 1h | lite | off |
balanced (default) | 100 | 6h | balanced | off |
deep | 300 | 12h | deep | on |
MaxCommands becomes the engine’s MaxTurns cap (one LLM→tool cycle per turn). When the cap is hit the run ends with an error event — the model didn’t get to halt cleanly.
Halt conditions
The autopilot exits in one of four ways:
- 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.
- Quiet halt — model finishes a turn with no tool calls and no
halt_scan. Treated as a natural stop.
- Max turns — turn count hits
MaxCommands. Engine emits an EventError; autopilot returns a non-nil error.
- 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)
└── archon-audit/ # archon 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:
- 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.
- 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”).
- 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.
Archon-audit also runs first (foreground) when --source is set, freezing its findings into archon-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.