
Vigolium Agentic Scan
Recent shift: the previous subprocess-based SDK and ACP backends (claudesdk,codexsdk,opencodesdk, ACP bridges) have been removed. All AI dispatch now goes through an in-process Go runtime called olium (pkg/olium/). One unified provider interface, one conversation state, one place to reason about timeouts and retries.
1. Subcommand surface
vigolium agent is a parent command with informational flags only (--list-templates, --list-agents). Real work happens in subcommands.
query and triage are one-shot modes that do not orchestrate a scan (query runs a prompt with optional source-code context; triage re-evaluates one existing finding). autopilot and swarm are the two agentic scan modes.
2. Architecture layers
2.1 Engine (pkg/agent/engine.go)
The engine is the seam between orchestrators and the olium runtime. Its job is to:
- Preflight: validate provider/model selection.
- Build the prompt: load template, parse frontmatter, render with
TemplateData. - Enrich context: pull DB context (previous findings, discovered endpoints, high-risk endpoints, module list, scan stats) through a thread-safe LRU cache that lives for one swarm/autopilot run.
- Dispatch: call the olium engine.
- Retry: exponential backoff on transient errors (default 2 retries, 2-30s backoff with jitter).
- Parse: schema-aware JSON extraction tolerating fences, prose, and type coercion (string ↔ int, object ↔ string body).
- Ingest: write parsed findings/HTTP records to the DB repository.
Engine.Run(ctx, opts): one-shot prompt execution; creates a fresh olium engine.Engine.RunOnOliumEngine(ctx, opts, eng): runs against a shared engine instance, preserving conversation prefix for prompt-cache hits across phases.Engine.RunSourceAnalysisParallel(ctx, cfg): fan-out source analysis (single explore call → parallel format/extension sub-calls on the same engine).
agent.olium.max_concurrent uses a positive value as the cap, 0/unset as the default of 4, and a negative value for unbounded concurrency.
2.2 Olium runtime (pkg/olium/)
Native, in-process replacement for the old subprocess pool.
-
pkg/olium/engine:Engine.Run(ctx, prompt) <-chan Eventreturns a stream of events:EventTextDelta,EventThinkingDelta,EventToolCall,EventTurnDone(with token usage),EventError. Conversation state (system prompt, tool definitions, prior turns) lives on the engine and is reused across calls when phases share an engine. -
pkg/olium/tool: registry of built-in tools (bash, file ops, grep, fetch, …). Autopilot exposes the full set; swarm uses a smaller set per phase. -
pkg/olium/skill: optional skill files (Markdown SKILL.md packages) that augment the system prompt; loaded from embedded assets and~/.vigolium/skills/. -
pkg/olium/provider: provider dispatch (eleven drivers):
openai-compatible with gemma4:latest (a local Ollama endpoint). Configured under agent.olium in vigolium-configs.yaml. Per-call deadline defaults to 10 minutes (call_timeout_sec).
2.3 Prompt templates
Markdown files with YAML frontmatter, loaded from (in order):agent.templates_dir(config dir)~/.vigolium/prompts/- Embedded (
public/presets/prompts/baked into the binary)
Templates render against
TemplateData, which carries: source code snippets, directory tree, target URL, hostname, previous findings (DB), discovered endpoints (DB), module list/tags, scan stats, and a free-form Extra map for orchestrator-injected hints.
3. Swarm pipeline
vigolium agent swarm --target ... [--source ...] runs a state-machine pipeline. Each step implements swarmPhaseStep.Run(ctx, *swarmPipelineState).
native- are pure-Go (no LLM). The pipeline is gated by:
--only/--skip/--start-fromflags (with legacy aliases viaNormalizeSwarmPhase)- intensity preset (
SwarmPresets[Quick|Balanced|Deep]) cfg.SourcePath: empty source skips source-analysis and code-auditcfg.Discover,cfg.CodeAudit,cfg.Triagetoggles- checkpoint state for observability;
--start-fromcreates a new run with earlier phases marked complete
cfg.Audit != "") when source is provided, contributing source-code audit findings without blocking the swarm. Swarm uses the embedded vigolium-audit harness directly; the multi-driver agent audit command layers piolium support on top.
Plan & extension phases
The master agent receives input records (chunked intoMasterBatchSize, default 5) and returns a SwarmPlan:
<session>/extensions/ with sanitized filenames.
Triage loop
After the native scan, if findings exist and triage is enabled, the triage agent receives a fixture (truncated by detail tiers, 15 full-detail / 40 table-with-top-10 / etc.) and emits:FollowUpScans is non-empty and rescan is enabled, the pipeline loops back to native-scan with targeted modules. Loop bounded by MaxIterations (default 3); early-exits when all findings have “certain” confidence.
4. Autopilot pipeline
vigolium agent autopilot --target ... [--source ...] is simpler, no plan/extension phases. The agent itself decides what to run.
agent.olium.autopilot_mode: legacy preserves direct report_finding behavior. shadow rotates context while mirroring candidates; enforced replaces direct reports with propose_candidate and promotes only verifier-confirmed claims. Durable runs can continue with autopilot --resume <agentic-scan-uuid>.
Intensity presets (autopilot)
5. Session directories
Every swarm and autopilot run writes a session dir underagent.sessions_dir (default ~/.vigolium/agent-sessions/<run-uuid>/). Layout:
EnsureSessionDir(baseDir, agenticScanUUID) in pkg/agent/pipeline_types.go is the canonical creator.
6. Configuration
All agent settings live underagent in vigolium-configs.yaml:
--provider, --model, --oauth-cred, --oauth-token, --llm-api-key, --bridge-bin) override the config at runtime. The REST API also accepts per-request BYOK credentials.
7. Where things live
8. Quick mental model
- Engine turns a prompt template + DB context into a structured result. One LLM call.
- Orchestrator sequences many engine calls plus native steps (discovery, scan), checkpoints state, and writes a session directory.
- Olium is the agent runtime, it holds conversation state and dispatches to a provider. One olium engine can serve many engine calls cheaply (prompt cache hits).
- Swarm phases are controlled by
--only,--skip, and--start-from; swarm has no public--resumeflag. - Autopilot resume takes an AgenticScan UUID and restores durable scratchpad/candidate state; it is not phase-based.
- Intensity is a single knob that hydrates a bundle of toggles (commands, timeout, vigolium-audit mode, discover/audit/triage flags, browser/auth).
