argus-pentest 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +645 -2
- package/package.json +51 -4
- package/src/cli.ts +559 -0
- package/src/core/agent.ts +4432 -0
- package/src/core/authorization.ts +83 -0
- package/src/core/browser.ts +355 -0
- package/src/core/config.ts +142 -0
- package/src/core/connectors.ts +260 -0
- package/src/core/cvss.ts +186 -0
- package/src/core/dependencies.ts +417 -0
- package/src/core/diff.ts +193 -0
- package/src/core/engine.ts +355 -0
- package/src/core/events.ts +83 -0
- package/src/core/http.ts +373 -0
- package/src/core/installer.ts +371 -0
- package/src/core/journal.ts +106 -0
- package/src/core/jwt.ts +176 -0
- package/src/core/mcp.ts +343 -0
- package/src/core/memory.ts +158 -0
- package/src/core/osv.ts +201 -0
- package/src/core/packages.ts +168 -0
- package/src/core/patches.ts +139 -0
- package/src/core/permissions.ts +132 -0
- package/src/core/pipeline.ts +327 -0
- package/src/core/planner.ts +149 -0
- package/src/core/probes/attacks.ts +1062 -0
- package/src/core/probes/network.ts +543 -0
- package/src/core/probes/repo.ts +522 -0
- package/src/core/probes/web.ts +1341 -0
- package/src/core/prompt-scope.ts +338 -0
- package/src/core/proxy.ts +380 -0
- package/src/core/recon-utils.ts +368 -0
- package/src/core/remediation.ts +71 -0
- package/src/core/report.ts +465 -0
- package/src/core/sandbox.ts +173 -0
- package/src/core/scope.ts +597 -0
- package/src/core/scratch.ts +29 -0
- package/src/core/session.ts +247 -0
- package/src/core/signatures.ts +326 -0
- package/src/core/skills.ts +243 -0
- package/src/core/store.ts +135 -0
- package/src/core/tools.ts +1197 -0
- package/src/core/traffic.ts +122 -0
- package/src/core/types.ts +331 -0
- package/src/core/util.ts +186 -0
- package/src/core/vectormemory.ts +173 -0
- package/src/core/web.ts +396 -0
- package/src/core/wsl.ts +189 -0
- package/src/tui/agent-runner.ts +369 -0
- package/src/tui/app.tsx +1474 -0
- package/src/tui/catalog.ts +179 -0
- package/src/tui/clipboard.ts +168 -0
- package/src/tui/commands.ts +1326 -0
- package/src/tui/credentials.ts +58 -0
- package/src/tui/dashboard.ts +369 -0
- package/src/tui/doctor.ts +278 -0
- package/src/tui/hooks.ts +59 -0
- package/src/tui/index.tsx +68 -0
- package/src/tui/intent.ts +162 -0
- package/src/tui/modals.tsx +1375 -0
- package/src/tui/preview.ts +171 -0
- package/src/tui/providers.ts +250 -0
- package/src/tui/state.ts +397 -0
- package/src/tui/terminal-spec.ts +59 -0
- package/src/tui/terminal.tsx +104 -0
- package/src/tui/theme.ts +121 -0
package/README.md
CHANGED
|
@@ -1,3 +1,646 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ARGUS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/argus-pentest)
|
|
4
|
+
|
|
5
|
+
Terminal-first, authorization-gated security assessment harness. Ask it in plain
|
|
6
|
+
English and a grounded agent plans scans, reads the source, searches the workspace and
|
|
7
|
+
reports only findings that real tools produced. It runs native probes plus optional
|
|
8
|
+
external adapters, saves every event and finding, and writes reports.
|
|
9
|
+
|
|
10
|
+
> Only assess systems you have written permission to test. Naming a target in the
|
|
11
|
+
> prompt is the authorization record; a manual scope file remains available for teams
|
|
12
|
+
> that need one.
|
|
13
|
+
|
|
14
|
+
## Install and run
|
|
15
|
+
|
|
16
|
+
Global install (the npm name `argus` belongs to an unrelated package, so the package
|
|
17
|
+
is `argus-pentest`; the installed command is `argus`):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g argus-pentest # needs Bun >= 1.3.14 on PATH
|
|
21
|
+
argus --version
|
|
22
|
+
argus # terminal UI
|
|
23
|
+
argus --help # command-line interface
|
|
24
|
+
argus doctor # environment and toolchain check
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
From a checkout:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun install
|
|
31
|
+
bun run tui # terminal UI (alias: bun run dev)
|
|
32
|
+
bun run cli --help # command-line interface
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Terminal UI
|
|
36
|
+
|
|
37
|
+
The TUI is a normal prompt-driven terminal, laid out like a quiet instrument panel:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
▌ ARGUS security assessment OpenAI · gpt-4.1-mini
|
|
41
|
+
scope example.com · valid · TICKET-42 scope.json
|
|
42
|
+
──────────────────────────────────────────────────────────────────────────
|
|
43
|
+
❯ audit example.com and rank what you find
|
|
44
|
+
|
|
45
|
+
RESULT ──────────────────────────────────────────────────────────────────
|
|
46
|
+
...
|
|
47
|
+
FINDINGS ────────────────────────────────────────────────────────────────
|
|
48
|
+
MED SPF record missing · example.com
|
|
49
|
+
|
|
50
|
+
⠹ HTTP baseline & technology fingerprint ███████░░░░░ 3/7 00:12
|
|
51
|
+
╭──────────────────────────────────────────────────────────────────────╮
|
|
52
|
+
│ ❯ ask in plain English, or / for commands │
|
|
53
|
+
╰──────────────────────────────────────────────────────────────────────╯
|
|
54
|
+
/help tab complete esc interrupt ctrl+c exit key from OPENAI_API_KEY
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The masthead carries the identity, the active provider/model and the authorization in
|
|
58
|
+
play. Operator prompts use the accent `❯`, findings render as coloured severity chips,
|
|
59
|
+
section headings get a hairline, and one status line above the prompt shows the live
|
|
60
|
+
phase with a block progress meter or the session's finding counts. Everything is a
|
|
61
|
+
single column, so narrow terminals keep the same layout. Panels and lists use a solid
|
|
62
|
+
`▌` selection bar (k9s/lazygit convention), and all markers are terminal glyphs — no
|
|
63
|
+
emoji, no bracketed tags, nothing that needs a Nerd Font. Plain text goes to the agent (`audit example.com and find real bugs`). Type `/`
|
|
64
|
+
to open the command menu; `Up`/`Down` select, `tab` completes, `enter` opens the highlighted
|
|
65
|
+
picker or runs the command. `esc` closes a modal, aborts the agent or clears the prompt.
|
|
66
|
+
|
|
67
|
+
Drag across transcript text to select it, then press `ctrl+c` to copy; the selection is
|
|
68
|
+
highlighted by the renderer and copying works through OSC 52 plus the native platform
|
|
69
|
+
clipboard, so it also works over SSH in terminals such as Windows Terminal, iTerm2,
|
|
70
|
+
kitty and WezTerm. `/copy` copies the last agent answer and `/copy all` copies the
|
|
71
|
+
whole transcript. With no selection, `ctrl+c` still aborts a running job or exits.
|
|
72
|
+
|
|
73
|
+
Mouse support is enabled by default: click the prompt to focus it, click a command
|
|
74
|
+
suggestion or a provider/model/MCP row to act on it, click `esc to close` in a modal,
|
|
75
|
+
and use the wheel over the transcript or a modal list. Dragging still selects text for
|
|
76
|
+
copying.
|
|
77
|
+
|
|
78
|
+
| Command | What it does |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `/help` | list every command and scan flag |
|
|
81
|
+
| `/doctor [--chat]` | preflight provider, key, model, scope, memory, store and adapters; `--chat` sends one tiny completion |
|
|
82
|
+
| `/scan <target>` | start an assessment; scope follows the target (defaults to the `deep` profile) |
|
|
83
|
+
| `/dashboard` | overview, risk gauge, severity and category bars, probe coverage, dependency graph, outdated packages, fix plan and findings |
|
|
84
|
+
| `/providers` | provider picker modal |
|
|
85
|
+
| `/models` | model picker grouped by provider, with live discovery and search across providers and models |
|
|
86
|
+
| `/connect` | provider and MCP picker with search; `enter` activates a provider or opens key entry, or connects an MCP server |
|
|
87
|
+
| `/key [provider]` | add or replace an API key in one step (active provider by default) |
|
|
88
|
+
| `/copy [last\|all]` | copy the last answer or the whole transcript |
|
|
89
|
+
| `/memory` | show the AGENTS.md memory file and its newest entries |
|
|
90
|
+
| `/runs` | recent assessments |
|
|
91
|
+
| `/findings [runId]` | review findings for the last or a specific run |
|
|
92
|
+
| `/preview <path> [--start N] [--end N]` | read-only preview panel: numbered lines, scrollable, never writes |
|
|
93
|
+
| `/report [runId] [format]` | write markdown, json, sarif, csv or html reports |
|
|
94
|
+
| `/tools` | external adapter inventory and install hints |
|
|
95
|
+
| `/install [tool...] [--all] [--yes]` | plan platform-specific adapter installs; `--yes` runs only user-level plans |
|
|
96
|
+
| `/web <query>` / `/web read <url>` | keyless web search or one public page, with SSRF and size checks |
|
|
97
|
+
| `/http <url> ...` | send one request; scope follows the URL |
|
|
98
|
+
| `/jwt <token>` | decode a JWT locally and flag session risks without sending it anywhere |
|
|
99
|
+
| `/scope [path\|init\|target]` | show, derive or validate the active scope |
|
|
100
|
+
| `/config` | effective configuration, with key names but never key values |
|
|
101
|
+
| `/authorize` | one-time authorized-use agreement (`accept <name>`, `revoke`, status) |
|
|
102
|
+
| `/vim [file]` | edit a file (or the project) in the embedded terminal, using Kali's vim when WSL is present |
|
|
103
|
+
| `/terminal [cmd]` | open an interactive shell or run a command in the embedded terminal |
|
|
104
|
+
| `/clear`, `/quit` | clear the transcript, exit |
|
|
105
|
+
|
|
106
|
+
Scan flags: `--profile quick|recon|web|api|network|deep|repo`, `--scope <file>`,
|
|
107
|
+
`--passive`, `--intrusive`, `--no-external`, `--formats md,json,sarif`, `--retries 0-5`.
|
|
108
|
+
Scope is derived from the target you name; a manual `--scope` file is still honored.
|
|
109
|
+
|
|
110
|
+
### Preflight
|
|
111
|
+
|
|
112
|
+
Run `/doctor` before a session when something looks wrong. It checks the active provider's
|
|
113
|
+
`/models` endpoint and reports whether the key was rejected, the server is down, the base
|
|
114
|
+
URL is missing, or the selected model is absent from the live catalog. It also validates
|
|
115
|
+
the active scope, reports the AGENTS.md path and entry count, checks that the data directory
|
|
116
|
+
is writable, inventories external adapters, reports the web-research mode, and lists
|
|
117
|
+
configured MCP servers. By default
|
|
118
|
+
it never sends a chat completion, so a preflight does not spend credits. Add `--chat` to
|
|
119
|
+
send one minimal completion and prove the exact chat endpoint, model and key work; that
|
|
120
|
+
option uses a small amount of credit and reports the round-trip latency. Status lines use plain ASCII tags: `[+]` ok,
|
|
121
|
+
`[!]` warning, `[-]` error, `[..]` in progress. No emoji or Nerd Font glyph is required.
|
|
122
|
+
|
|
123
|
+
### Providers and models
|
|
124
|
+
|
|
125
|
+
`/providers` covers OpenAI, OpenRouter, Groq, DeepSeek, Together, Mistral, xAI, NVIDIA
|
|
126
|
+
NIM, local Ollama and LM Studio, plus any custom OpenAI-compatible endpoint
|
|
127
|
+
(`/providers url https://host/v1`). `/models` renders every provider as a group with
|
|
128
|
+
its models underneath, puts the active provider first, queries the active endpoint's
|
|
129
|
+
`/models` API, and keeps a known catalog as fallback. Typing filters both provider
|
|
130
|
+
names and model ids; `Up`/`Down` select, `enter` switches provider and model. Queries are
|
|
131
|
+
skipped when the provider still needs a key, so the picker never stalls on a request
|
|
132
|
+
that cannot succeed.
|
|
133
|
+
|
|
134
|
+
Adding a key takes one command: `/key` opens key entry for the active provider and
|
|
135
|
+
`/key nvidia` for a named one. From `/connect`, pressing `enter` on a provider that
|
|
136
|
+
has no key opens the same entry; on a provider that has a key it activates it
|
|
137
|
+
immediately. Paste with `ctrl+v` (or your terminal's paste shortcut), or type the key,
|
|
138
|
+
then press `enter` - it is saved to
|
|
139
|
+
`<dataDir>/credentials.json` with owner-only permissions, applied to the current
|
|
140
|
+
process, and the provider is activated in the same step. Key entry shows the
|
|
141
|
+
provider's key page (`https://platform.openai.com/api-keys`, `https://build.nvidia.com/settings/api-keys`,
|
|
142
|
+
and so on) so you can create one without leaving the flow. Keys render as bullets and
|
|
143
|
+
never enter the transcript. You can still export the environment variable named in
|
|
144
|
+
the config (`OPENAI_API_KEY` and friends) before launching. Use `r` on a provider
|
|
145
|
+
detail only if you want a manual endpoint check; activation itself does no network
|
|
146
|
+
request, so switching providers is instant. No secret value is ever printed by the
|
|
147
|
+
harness.
|
|
148
|
+
|
|
149
|
+
NVIDIA NIM is included as a first-class provider at
|
|
150
|
+
`https://integrate.api.nvidia.com/v1` (`NVIDIA_API_KEY`). Its `GET /v1/models`
|
|
151
|
+
endpoint exposes the whole hosted catalog - Nemotron, Llama, DeepSeek, Mistral, GLM,
|
|
152
|
+
Kimi and more - so `/models` lists the live set when NVIDIA is active, with a curated
|
|
153
|
+
fallback of chat/coding/reasoning ids before the key exists.
|
|
154
|
+
|
|
155
|
+
Selections persist to `argus.config.json` (or the file named by `ARGUS_CONFIG`).
|
|
156
|
+
|
|
157
|
+
### The agent
|
|
158
|
+
|
|
159
|
+
Plain text starts a grounded loop - no magic words. "check example.com", "is my site
|
|
160
|
+
safe?", "look at this repo for bugs", "what is broken here?" and "harden this" are all
|
|
161
|
+
assessment requests. The interpreter understands:
|
|
162
|
+
|
|
163
|
+
- a literal domain, URL, IP, `localhost:port` or existing path;
|
|
164
|
+
- "my site", "this app" or "the target" when the active scope has exactly one entry;
|
|
165
|
+
- "my code", "this repo", "the code base", "the source tree" or "this project" as the workspace;
|
|
166
|
+
- a whole-codebase request such as "scan the whole code base and rank the vulns" without a target;
|
|
167
|
+
|
|
168
|
+
Scope is **prompt-derived**. When you name a URL, host, IP, CIDR, `localhost:port` or
|
|
169
|
+
existing path, Argus records exactly that surface and starts. A generated scope grows as
|
|
170
|
+
you name new targets; a manual scope file is preserved in place and a prompt-derived
|
|
171
|
+
sibling is used instead. `passive` / `read-only` / `offline` suppress active requests;
|
|
172
|
+
`full` / `aggressive` / `intrusive` widen checks; `no external` disables registry, OSV
|
|
173
|
+
and subdomain intelligence. A local-only request is reviewed as the workspace without
|
|
174
|
+
pretending it authorized a network target. A pure factual question with no target is
|
|
175
|
+
answered as conversation, not a scan.
|
|
176
|
+
|
|
177
|
+
A greeting, a question or an ordinary coding request needs no authorization at all:
|
|
178
|
+
that turn runs **unscoped** - reading, search, edits and shell keep working - and no
|
|
179
|
+
scope file is written. Naming a target, or asking for an assessment, derives the scope
|
|
180
|
+
for that turn. An existing scope file is reused as-is and is never rewritten for an
|
|
181
|
+
ordinary prompt, so "Hi" can no longer mint or update an authorization record.
|
|
182
|
+
|
|
183
|
+
Unambiguous natural-language shortcuts run locally, without a model call: `check
|
|
184
|
+
example.com`, `scan my app`, `find bugs in this repo`, `show findings`, `dashboard`,
|
|
185
|
+
`preview src/core/http.ts`, `add nvidia api key`, `search the web for a CVE`,
|
|
186
|
+
`jwt <token>` and `http <url>`.
|
|
187
|
+
That keeps common actions fast and lets them work before a key is configured. Local
|
|
188
|
+
scans derive scope from the target and start immediately; anything that needs reasoning
|
|
189
|
+
goes to the model.
|
|
190
|
+
|
|
191
|
+
If no provider key is configured, a free-form prompt now explains how to add one with
|
|
192
|
+
`/key` and lists the no-key actions instead of failing silently. If the model endpoint
|
|
193
|
+
is unreachable and the prompt maps to a local action, Argus runs that action instead of
|
|
194
|
+
dead-ending.
|
|
195
|
+
|
|
196
|
+
If the target is genuinely ambiguous (for example two scope rules and "the target"),
|
|
197
|
+
the agent asks one short question instead of guessing. The model gets thirty-one real
|
|
198
|
+
tools: the assessment tools `scan_target`, `get_findings`, `list_runs`, `web_search`,
|
|
199
|
+
`read_url`, `http_request`, `http_history`, `browser`, `analyze_jwt` and
|
|
200
|
+
`security_tools`; the
|
|
201
|
+
workspace tools `list_dir`, `glob`, `read_file`, `preview`, `search_code`, `write_file`,
|
|
202
|
+
`edit_file`, `apply_patch` and `run_command`; the package tools `install_package` and
|
|
203
|
+
`install_tool`; plus `todo_write`, `spawn_subagents`, `report_finding`, `remember` and
|
|
204
|
+
`load_skill`. It can scan, read findings, inspect and
|
|
205
|
+
edit source, run tests, install a dependency, list missing security adapters, research
|
|
206
|
+
current advisories, probe an authorized endpoint, load a per-class playbook, review the
|
|
207
|
+
traffic it already sent, review a token and run a second pass
|
|
208
|
+
where coverage was weak. On Windows it can also drive the host's Kali Linux through
|
|
209
|
+
`wsl`, including installing missing Kali tooling, and it asks for approval first when
|
|
210
|
+
the policy requires it. Its system prompt carries an explicit attacker-mindset layer:
|
|
211
|
+
start from trust boundaries and trace input to sink, work in falsifiable hypotheses,
|
|
212
|
+
compare account/role/request pairs, chain primitives instead of listing issues, and
|
|
213
|
+
rank by exploitability rather than count.
|
|
214
|
+
There is no fixed tool-step budget. The loop continues until the model finalizes, the
|
|
215
|
+
operator aborts, or it repeats the same call or produces invalid output. Failed probes
|
|
216
|
+
are still retried (three extra attempts for agent scans).
|
|
217
|
+
|
|
218
|
+
The read-only `preview` tool is a UI surface as well: when the model previews a file or
|
|
219
|
+
the exact diff a write would create, the preview panel opens on top with line numbers,
|
|
220
|
+
add/remove colouring and a short staggered reveal, and the transcript keeps the same
|
|
221
|
+
path. `/preview <path> [--start N] [--end N]` opens the same panel by hand. Nothing in it
|
|
222
|
+
writes, it is confined to the workspace and the authorized local roots, and `esc` closes
|
|
223
|
+
it.
|
|
224
|
+
|
|
225
|
+
Workspace tools behave like a normal terminal agent. Reads and writes are confined to
|
|
226
|
+
the workspace plus directories named in the active prompt scope; `.git`, `.ssh`, `.aws`
|
|
227
|
+
and `.gnupg` are never writable. `run_command` executes non-interactive `bash -lc`
|
|
228
|
+
inside an authorized root with a 120-second cap and truncated output. Privilege
|
|
229
|
+
escalation and host-destructive commands are refused. A command that can delete or
|
|
230
|
+
rewrite (`rm -rf`, `git reset --hard`, `git clean -fd`, a publish or a piped remote
|
|
231
|
+
script) opens an approval prompt: `y` allows once, `a` allows that action for the rest
|
|
232
|
+
of the run (high-risk actions still ask), `n` or `esc` denies. Approval is interactive
|
|
233
|
+
in the TUI and defaults to deny when no operator is attached.
|
|
234
|
+
|
|
235
|
+
The default posture is prompt-independent. Scoped network work follows the authorization
|
|
236
|
+
derived from the target; local writes, shell commands and package installs ask the
|
|
237
|
+
operator. The agent does not guess from words like "fix", "scan" or "review". Only an
|
|
238
|
+
explicit operator directive changes the posture: `read-only`, `don't change anything`
|
|
239
|
+
or `explain only` refuses local changes; `just do it`, `without asking` or `no questions`
|
|
240
|
+
pre-approves them for that turn. The policy is printed as `- perm | ...` at the start of
|
|
241
|
+
the run, and hard blocks still win: privilege escalation and host-destructive commands
|
|
242
|
+
are never available.
|
|
243
|
+
|
|
244
|
+
`install_package` detects the repository's manager from its lockfile, validates the
|
|
245
|
+
package name and version, and runs an argv-only install (`bun add`, `npm install`,
|
|
246
|
+
`pnpm add`, `yarn add`, `uv add`, `pip`, `cargo add`, `go get`, `composer require` or
|
|
247
|
+
`bundle add`). It never interpolates a shell string. `security_tools` returns installed
|
|
248
|
+
and missing adapters with versions and install commands; `scan_target` automatically
|
|
249
|
+
uses the installed ones for the selected profile.
|
|
250
|
+
|
|
251
|
+
The plan is visible while the agent works. `todo_write` publishes `[done]`, `[active]`
|
|
252
|
+
and `[queued]` rows above the status bar, and the same plan is included in the final
|
|
253
|
+
answer. A write or edit returns a unified diff so the transcript shows exactly what
|
|
254
|
+
changed, and the approval prompt for a write, edit or patch shows the same diff before
|
|
255
|
+
the operator decides.
|
|
256
|
+
|
|
257
|
+
`preview` is the read-only counterpart: `{"path":"src/a.ts"}` returns numbered lines,
|
|
258
|
+
and `{"path":"src/a.ts","content":"..."}` or `{"path":"src/a.ts","patch":"..."}`
|
|
259
|
+
returns the exact unified diff the change would produce with an `unchanged` flag when
|
|
260
|
+
there is nothing to do. It never writes and needs no approval, so the agent can inspect
|
|
261
|
+
a change - or show a file to the operator - before touching anything.
|
|
262
|
+
|
|
263
|
+
Transcript status lines use terminal marker glyphs instead of bracketed tags: `::` for
|
|
264
|
+
steps, `>` for a running tool or subagent, `+` for done, `!` for failed or refused, `-`
|
|
265
|
+
for notes, and `$` for the `argus resume -session` command. Everything is plain ASCII:
|
|
266
|
+
no emoji and no Nerd Font glyphs.
|
|
267
|
+
|
|
268
|
+
`spawn_subagents` runs one to three focused agents in parallel with explicit roles:
|
|
269
|
+
`recon`, `auth`, `input`, `secrets`, `deps`, `config`, `web` and `verify`. Each child
|
|
270
|
+
gets a role checklist, its parent's scope, permission posture and tools, and no fixed
|
|
271
|
+
step budget of its own. A child that needs to write or install raises the same operator
|
|
272
|
+
approval prompt as the parent. Duplicate assignments are rejected,
|
|
273
|
+
nested subagents are refused, and overlapping findings are deduped by title, target,
|
|
274
|
+
category and CWE before merging.
|
|
275
|
+
A timed-out child returns its partial verified findings and a gap instead of stalling
|
|
276
|
+
the whole run.
|
|
277
|
+
|
|
278
|
+
The agent talks to the provider the way a normal coding harness does: the tool list is
|
|
279
|
+
sent as native function schemas, and `tool_calls` in the reply are executed directly,
|
|
280
|
+
several per turn, with the results returned as `role: "tool"` messages. A model that
|
|
281
|
+
answers in plain text with no tool call is finished — that text is the answer. If a
|
|
282
|
+
provider rejects function calling (400/404/405/415/422/501 mentioning tools or
|
|
283
|
+
functions), the client downgrades itself to the JSON protocol for the rest of the
|
|
284
|
+
session and retries, so text-only servers, Ollama builds and gateways keep working.
|
|
285
|
+
|
|
286
|
+
Every model response is checked. If a provider ignores the JSON protocol, the raw
|
|
287
|
+
reply is shown immediately, and after a second prose reply it is rendered as the
|
|
288
|
+
answer (with its finding ids still passed through the anti-hallucination gate) rather
|
|
289
|
+
than dead-ending. Transient provider failures (429 and 5xx) are retried with backoff,
|
|
290
|
+
and errors name the endpoint and explain whether the key, URL or model is the problem.
|
|
291
|
+
|
|
292
|
+
### Web research
|
|
293
|
+
|
|
294
|
+
Agents can search the web without a separate API key. `web_search` uses DuckDuckGo's
|
|
295
|
+
public HTML results; set `ARGUS_SEARCH_URL` to a SearXNG-compatible JSON endpoint for
|
|
296
|
+
a private or rate-limit-free instance. `read_url` reads a page through DNS,
|
|
297
|
+
private-address, redirect, content-type and size checks, so it cannot be pointed at
|
|
298
|
+
localhost, link-local metadata or a private network. Search snippets and page text
|
|
299
|
+
are explicitly marked untrusted: they can guide research, but they can never create a
|
|
300
|
+
finding or override the scope. The operator shortcuts are `/web <query>` and
|
|
301
|
+
`/web read <url>`.
|
|
302
|
+
|
|
303
|
+
### Manual request testing
|
|
304
|
+
|
|
305
|
+
`/http` sends one request you specify, without spending a model call. The URL you name
|
|
306
|
+
is the authorization; a manual `--scope` file is still honored and redirects cannot
|
|
307
|
+
leave the active scope. Examples:
|
|
308
|
+
|
|
309
|
+
```text
|
|
310
|
+
/http https://staging.example.com/api/me --bearer $TOKEN
|
|
311
|
+
/http https://staging.example.com/api/items --method POST --json '{"name":"x"}' --header "X-Trace: 1"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Supported options: `--method GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS`, `--header "Name: value"`,
|
|
315
|
+
`--bearer <token>`, `--json <body>`, `--form <body>`, `--body <text>` and `--scope <file>`.
|
|
316
|
+
`POST` runs with prompt-derived active mode; `PUT`, `PATCH` and `DELETE` additionally
|
|
317
|
+
need `intrusive` / `full` language or a manual scope that allows them. Port rules and
|
|
318
|
+
deny rules are enforced on every hop. The
|
|
319
|
+
response prints status, latency, size, redirect chain, headers, TLS facts and a 12-line
|
|
320
|
+
body preview. `set-cookie` values are hidden. The agent exposes the same capability as
|
|
321
|
+
its `http_request` tool.
|
|
322
|
+
|
|
323
|
+
`/jwt <token>` decodes a JWT locally with no network call or provider key. It reports
|
|
324
|
+
`alg`, expiry, remote-key headers (`jku`/`x5u`/`jwk`), missing `iss`/`aud`/`sub`, and
|
|
325
|
+
sensitive claims with their values redacted. It never verifies the signature - confirm
|
|
326
|
+
each flag against the live service. Add `--json` for a machine-readable analysis.
|
|
327
|
+
|
|
328
|
+
### Adapter installation
|
|
329
|
+
|
|
330
|
+
`/install` builds a platform-aware plan for every missing adapter. It prefers user-level
|
|
331
|
+
managers (`go install`, `pip`, `gem`, `brew`, `winget`) and prints admin plans
|
|
332
|
+
(`apt-get`, `dnf`, `pacman`, `choco`) with the exact `sudo` command but never executes
|
|
333
|
+
them. `/install --yes` alone shows the plan and refuses a mass install; add `--all` or
|
|
334
|
+
name the tools. `/install subfinder nuclei --yes` runs only those available user-level
|
|
335
|
+
plans, sequentially, with a five-minute cap per plan. Afterward, run `/tools` to confirm
|
|
336
|
+
and restart the shell if `PATH` changed.
|
|
337
|
+
|
|
338
|
+
### Memory
|
|
339
|
+
|
|
340
|
+
Argus maintains `AGENTS.md` in the working directory. It is created automatically on
|
|
341
|
+
first launch, read before every agent turn, and appended after a run that produced
|
|
342
|
+
scans or verified findings. The agent can also add a durable note with `remember`.
|
|
343
|
+
The file is capped and pruned, credentials are redacted before writing, and the
|
|
344
|
+
content is injected as untrusted data explicitly above the hard rules, so a memory
|
|
345
|
+
entry can never override scope or authorization. Use `/memory` to inspect it or edit
|
|
346
|
+
it by hand to give the agent durable project context; never put secrets in it.
|
|
347
|
+
|
|
348
|
+
Hallucination is blocked deterministically, not by asking the model nicely:
|
|
349
|
+
|
|
350
|
+
- a scan target must be literally named or unambiguously inferred from a single active scope entry / the workspace;
|
|
351
|
+
- every claimed vulnerability must cite a finding id returned by a tool this turn;
|
|
352
|
+
- unknown ids and invented citations in the prose are removed and counted;
|
|
353
|
+
- if the model cites no finding ids, all real tool-observed findings are still shown with a warning;
|
|
354
|
+
- tool output is the only evidence source; web pages are untrusted research, never evidence;
|
|
355
|
+
- failures are reported as gaps; a named-target assessment must use at least one real tool before it may answer;
|
|
356
|
+
- subagents inherit the same allowed targets, are deduped, and merge through the same gate.
|
|
357
|
+
|
|
358
|
+
Source excerpts returned by `read_file` and `search_code` are sent to the configured
|
|
359
|
+
model provider. Keep that in mind when auditing code you cannot share; API keys stay
|
|
360
|
+
local and are never included in prompts.
|
|
361
|
+
|
|
362
|
+
### Ruthless execution
|
|
363
|
+
|
|
364
|
+
Assessments are meant to be thorough: `/scan` defaults to the `deep` profile, retries
|
|
365
|
+
each failed probe twice with backoff, prints every retry and failure instead of hiding
|
|
366
|
+
it, streams phases and findings into the transcript as they land (not just at the end),
|
|
367
|
+
and reports the run directory and generated reports. The agent has no fixed step
|
|
368
|
+
ceiling; it must produce a final report from the evidence it already has instead of
|
|
369
|
+
stopping without an answer. An optional per-run cap can still be supplied by callers,
|
|
370
|
+
and it warns before that cap is reached. Findings are ordered
|
|
371
|
+
by a transparent risk score (severity, confidence and high-impact category), and the
|
|
372
|
+
terminal output shows that score. After the findings, a `FIXES` plan groups findings
|
|
373
|
+
that share a remediation, orders them P1/P2/P3 and names the concrete change to make;
|
|
374
|
+
`/findings` and markdown reports include the same summary. Scope is derived from the
|
|
375
|
+
request: a named target is authorization enough. Passive-only, intrusive and external
|
|
376
|
+
behavior follow plain-English switches (`passive`, `full`, `aggressive`, `offline`),
|
|
377
|
+
and a manual scope file is still honored and never overwritten.
|
|
378
|
+
|
|
379
|
+
The active web pass covers more than headers and CORS. In scope, it reviews client
|
|
380
|
+
JavaScript bundles for committed credentials, path traversal and local file disclosure,
|
|
381
|
+
error-based SQL injection, command injection (arithmetic echo plus an intrusive timing
|
|
382
|
+
check), SSRF against cloud metadata endpoints, CRLF and Host header injection, login
|
|
383
|
+
forms that submit credentials over GET/HTTP or lack CSRF protection, and default
|
|
384
|
+
administrator credentials with login-throttling checks. Default-credential and timing
|
|
385
|
+
checks require both `allowIntrusive` and an explicit `full`/`aggressive` request; the
|
|
386
|
+
ordinary pass is read-only and sends one request per payload. The credential check is
|
|
387
|
+
limited to three well-known default pairs, and the throttling check uses only a
|
|
388
|
+
non-existent account name - there is no credential dictionary. Every detected issue
|
|
389
|
+
arrives with a concrete remediation, and the `FIXES` plan groups related issues into
|
|
390
|
+
P1/P2/P3 actions.
|
|
391
|
+
|
|
392
|
+
### Context and resume
|
|
393
|
+
|
|
394
|
+
Each successful or aborted agent turn is written to a per-workspace session file under
|
|
395
|
+
`<dataDir>/sessions/`. Source reviews are also folded into `AGENTS.md`, so a fresh
|
|
396
|
+
process remembers what was already inspected. Every turn ends with its session id and
|
|
397
|
+
the exact command to continue: `$ argus resume -session ses-...`. That command
|
|
398
|
+
reopens the recorded workspace, reloads the last objective, targets, verified findings,
|
|
399
|
+
gaps and next steps, and asks the agent to continue from the captured state. Inside the
|
|
400
|
+
TUI, `continue`, `resume`, `keep going` or `carry on` do the same thing without leaving
|
|
401
|
+
the process. The agent is told to call `get_findings` or `list_runs` before repeating a
|
|
402
|
+
completed scan. Session notes are untrusted historical data, never evidence, and
|
|
403
|
+
credentials are redacted before they are written.
|
|
404
|
+
|
|
405
|
+
`/dashboard` visualises what has been found so far: a weighted risk gauge, severity
|
|
406
|
+
and category bars, confidence split, probe coverage per phase, the dependency graph,
|
|
407
|
+
outdated direct packages, a prioritized fix plan and the finding list. It uses the live
|
|
408
|
+
session findings, or loads the most recent stored run. Bars are plain ASCII gaugessuch as `[=========-----]` with percentage labels and `+` / `!` status markers; no emoji,
|
|
409
|
+
hashtags or Nerd Font glyphs are required.
|
|
410
|
+
|
|
411
|
+
Dependency inventory is built locally from `package.json`, `package-lock.json`,
|
|
412
|
+
`bun.lock`, `requirements.txt`, `go.mod`, `Cargo.toml`, Maven and Gradle manifests.
|
|
413
|
+
The dashboard shows direct and transitive node counts, graph edges and a compact tree.
|
|
414
|
+
When the scope allows external intelligence, direct npm packages are compared with the
|
|
415
|
+
npm registry and version drift becomes a low/info finding with an upgrade command. With
|
|
416
|
+
`allowExternal: false`, the graph is still built and the latest-version check is marked
|
|
417
|
+
skipped; Argus never bypasses the scope to reach the registry.
|
|
418
|
+
|
|
419
|
+
## Scope
|
|
420
|
+
|
|
421
|
+
There is no setup step. Name the target in plain English and Argus derives the active
|
|
422
|
+
scope from that sentence:
|
|
423
|
+
|
|
424
|
+
```text
|
|
425
|
+
check example.com
|
|
426
|
+
scan the whole code base
|
|
427
|
+
review C:\work\api for auth bugs
|
|
428
|
+
full assessment of staging.example.com and its subdomains
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Argus writes the derived scope to `scope.json` (or `scope.prompt.json` when an operator
|
|
432
|
+
file already exists) and updates it as new targets are named. `prompt` mode is active
|
|
433
|
+
by default; say `passive`, `read-only` or `offline` to suppress active requests, or
|
|
434
|
+
`full`, `aggressive` or `intrusive` to widen checks. `no external` disables registry,
|
|
435
|
+
OSV and subdomain intelligence.
|
|
436
|
+
|
|
437
|
+
A manual scope file is still supported and is never overwritten:
|
|
438
|
+
|
|
439
|
+
```json
|
|
440
|
+
{
|
|
441
|
+
"version": 1,
|
|
442
|
+
"name": "Example authorized assessment",
|
|
443
|
+
"authorizedBy": "Security Team",
|
|
444
|
+
"authorizationRef": "TICKET-SEC-0001 / signed rules of engagement",
|
|
445
|
+
"expiresAt": "2026-12-31T00:00:00.000Z",
|
|
446
|
+
"allow": ["https://staging.example.com", "*.example.com", "10.0.0.0/24"],
|
|
447
|
+
"deny": ["https://example.com/account/delete"],
|
|
448
|
+
"maxRps": 20,
|
|
449
|
+
"allowedPorts": [80, 443],
|
|
450
|
+
"allowActive": true,
|
|
451
|
+
"allowIntrusive": false,
|
|
452
|
+
"allowExternal": false
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
`--scope <file>` uses that file strictly. Without it, the target you name is the scope.
|
|
457
|
+
Cloud metadata endpoints remain hard-blocked and deny rules still win for a manual
|
|
458
|
+
scope; those are safety boundaries, not configuration puzzles.
|
|
459
|
+
|
|
460
|
+
## CLI
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
argus init [--force]
|
|
464
|
+
argus authorize [--accept <name> | --revoke | --status]
|
|
465
|
+
argus scope init [path]
|
|
466
|
+
argus scope validate scope.json [target]
|
|
467
|
+
argus scan <target> [--scope scope.json] [--profile deep] [--retries 2]
|
|
468
|
+
argus resume --session <id>
|
|
469
|
+
argus tools [--json]
|
|
470
|
+
argus runs [--json]
|
|
471
|
+
argus report <runId> [--format md|json|sarif|csv|html] [--stdout]
|
|
472
|
+
argus mcp serve | tools | call <server> <tool> [json]
|
|
473
|
+
argus connectors list | send <runId>
|
|
474
|
+
argus config show | path
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
## Assessment pipeline
|
|
478
|
+
|
|
479
|
+
Every run is reported through the same stages, and the state is derived from real
|
|
480
|
+
evidence rather than declared:
|
|
481
|
+
|
|
482
|
+
```
|
|
483
|
+
vulnerability discovery -> candidate findings
|
|
484
|
+
dynamic validation -> validated reports (evidence + confirmed/likely)
|
|
485
|
+
exploitability -> confirmed impact (and LPEs when the surface is local)
|
|
486
|
+
patch generation -> candidate patches (never applied)
|
|
487
|
+
human researchers -> final review gate
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Candidate patches are concrete for validated repository findings: each carries the
|
|
491
|
+
file, the line and the exact change, with a one-line unified diff where the fix is
|
|
492
|
+
mechanical (for example `innerHTML -> textContent`, `privileged: true -> false`).
|
|
493
|
+
Rules that need design work are listed as file/line instructions instead of invented
|
|
494
|
+
code, and nothing is written to disk.
|
|
495
|
+
|
|
496
|
+
`/pipeline [runId] [--all]` prints the stages for a stored run, the dashboard shows
|
|
497
|
+
a compact summary, and the markdown/JSON/HTML/SARIF reports include the full block.
|
|
498
|
+
Findings that never reach validation stay labelled as candidates.
|
|
499
|
+
|
|
500
|
+
### Skill packs and traffic history
|
|
501
|
+
|
|
502
|
+
Two capabilities come from the open-source agentic-pentest landscape (Strix, PentAGI,
|
|
503
|
+
CAI): a per-class playbook the agent loads on demand, and structured access to the
|
|
504
|
+
traffic it already produced.
|
|
505
|
+
|
|
506
|
+
`load_skill` returns a concrete, non-destructive playbook for one vulnerability class -
|
|
507
|
+
IDOR, SQL injection, XSS, SSRF, authentication, JWT, path traversal, command
|
|
508
|
+
injection, file upload and secrets - with the smallest proof, the differential that
|
|
509
|
+
confirms it, and what not to touch. The playbooks live in `src/core/skills.ts`; aliases
|
|
510
|
+
such as `bola`, `rce`, `lfi` and `blind sqli` resolve to the same pack. A skill is a
|
|
511
|
+
plan, never evidence: the finding still needs a tool-observed reproduction and
|
|
512
|
+
`report_finding`.
|
|
513
|
+
|
|
514
|
+
`browser` drives a Chrome, Edge or Chromium that is already installed on the
|
|
515
|
+
machine, over its DevTools protocol - no Playwright dependency and no browser
|
|
516
|
+
download. Actions are `open`/`navigate`, `snapshot` (title, visible text, links,
|
|
517
|
+
forms, buttons), `click`, `type` (with optional submit), `screenshot` (PNG inside
|
|
518
|
+
the workspace) and `evaluate`. This is the authenticated-UI path: log in, walk a
|
|
519
|
+
JS-rendered route, then record what only the browser can see. URLs go through the
|
|
520
|
+
same prompt-scope host check as `http_request`, `ARGUS_BROWSER` can point at a
|
|
521
|
+
specific executable, and the process is closed at the end of every turn. The
|
|
522
|
+
`playwright`, `chrome` and `headless` aliases resolve to the same tool.
|
|
523
|
+
|
|
524
|
+
Findings accept CVSS. `report_finding` takes `cvss` as a v3.1 vector or a 0-10
|
|
525
|
+
score; base, temporal (`E`/`RL`/`RC`) and environmental (`CR`/`IR`/`AR` and the
|
|
526
|
+
modified metrics) scores are computed locally (`src/core/cvss.ts`), stored on the
|
|
527
|
+
finding, shown in `get_findings`, and rendered in the markdown and HTML reports.
|
|
528
|
+
Severity, confidence and the risk score are unchanged - CVSS is an additional,
|
|
529
|
+
standardised number rather than a replacement.
|
|
530
|
+
|
|
531
|
+
`sandbox` runs offensive tooling in an opt-in Docker container instead of on the
|
|
532
|
+
host. It mounts the workspace at `/work`, turns the network off by default, adds
|
|
533
|
+
`NET_RAW`/`NET_ADMIN` and `host.docker.internal` only when a network is requested,
|
|
534
|
+
and bounds container logs and PIDs so a runaway tool cannot take the machine down.
|
|
535
|
+
`status` reports Docker and the image, `pull` is an explicit (confirmed) action,
|
|
536
|
+
and `exec` is permission-gated like `run_command`. The image defaults to
|
|
537
|
+
`kalilinux/kali-rolling` and can be set with `ARGUS_SANDBOX_IMAGE` or per call.
|
|
538
|
+
|
|
539
|
+
`wsl` uses a real WSL distribution when Argus runs on Windows, so the host's own
|
|
540
|
+
Kali toolchain is available without Docker. `status` reports WSL availability,
|
|
541
|
+
every installed distro and whether Kali is present; `exec` runs any command inside
|
|
542
|
+
the Kali distro (nmap, sqlmap, nuclei, ffuf, impacket, netexec, msfconsole, or an
|
|
543
|
+
`apt-get install` of something missing) as the operator's WSL user. Set `root: true`
|
|
544
|
+
when a command must install packages or run privileged tooling; then the command runs
|
|
545
|
+
as root inside the distro without a sudo prompt. There is no fixed tool list - the
|
|
546
|
+
agent installs whatever the mission needs and uses it. `install` runs
|
|
547
|
+
`wsl --install -d kali-linux` only after the install approval prompt. Kali is
|
|
548
|
+
detected by name (`kali-linux` first, then any distro containing "kali"), a distro
|
|
549
|
+
can be forced per call, and `ARGUS_WSL_DISTRO`/`ARGUS_WSL` override the default and
|
|
550
|
+
the `wsl.exe` path. WSL commands share the operator's privileges, so the prompt
|
|
551
|
+
scope - not a container - is what bounds which hosts they may touch.
|
|
552
|
+
|
|
553
|
+
While an agent turn runs, the right-hand `LIVE` panel shows a `TERMINAL` section with
|
|
554
|
+
stdout/stderr streamed from `run_command` and `wsl exec` as the process writes it, so
|
|
555
|
+
a long nmap, sqlmap or install run is visible instead of arriving only at the end.
|
|
556
|
+
The full output is still returned to the model. The tail keeps the last lines; the
|
|
557
|
+
complete text stays in the tool result and the transcript.
|
|
558
|
+
|
|
559
|
+
The agent gets a dedicated scratch folder, `argus-workspace/`, created inside the
|
|
560
|
+
project on the first turn. Its system prompt tells it to keep scripts, wordlists,
|
|
561
|
+
payloads and generated artifacts there in subfolders (`recon/`, `payloads/`,
|
|
562
|
+
`notes/`) instead of dropping scratch files at the project root. The folder is inside
|
|
563
|
+
the authorized workspace root, so reads, edits and command `cwd` work there without a
|
|
564
|
+
second permission, and it can be inspected or deleted like any project directory.
|
|
565
|
+
`ARGUS_SCRATCH_DIR` renames it.
|
|
566
|
+
|
|
567
|
+
`/vim [file]` and `/terminal [command]` open a real interactive PTY inside Argus,
|
|
568
|
+
rendered with OpenTUI's embedded terminal: vim (Kali's vim through WSL when it is
|
|
569
|
+
installed, otherwise the host's), less, msfconsole or a plain login shell all get
|
|
570
|
+
full keyboard input, colours and resizing. While the terminal is focused every key
|
|
571
|
+
belongs to the program, so Enter, Esc and arrows work exactly as they do in a normal
|
|
572
|
+
terminal; leave the program (`:q`, `exit`) to return to Argus. `ctrl+shift+q` closes
|
|
573
|
+
the panel as an emergency escape.
|
|
574
|
+
|
|
575
|
+
`proxy` starts a loopback intercepting proxy (`http://127.0.0.1:<port>`). Point
|
|
576
|
+
curl, a scanner or the browser at it, then read `history`, and with `intercept`
|
|
577
|
+
on held requests wait for `allow` (which can rewrite the URL, headers or body) or
|
|
578
|
+
`drop`. Plain HTTP is fully inspectable; HTTPS is tunnelled with `CONNECT` and
|
|
579
|
+
recorded as metadata only - Argus does not install a CA or decrypt TLS. The
|
|
580
|
+
proxy stops with the turn, and captures stay in memory.
|
|
581
|
+
|
|
582
|
+
`vuln_lookup` researches packages and toolchains: it queries OSV.dev (no key) for a
|
|
583
|
+
package/version in npm, PyPI, crates.io, Go, Maven, NuGet, Packagist, RubyGems,
|
|
584
|
+
Hex, Pub or SwiftURL, and returns published advisories with CVE aliases, CVSS
|
|
585
|
+
vectors and fixed versions. `packagesFromLockfile` extracts `package@version`
|
|
586
|
+
pairs so a lockfile audit is one pass, not guesswork from model memory.
|
|
587
|
+
|
|
588
|
+
`export_report` writes a report for the current (or a named) run. `format:
|
|
589
|
+
"research"` is the narrative deliverable: executive summary, engagement facts,
|
|
590
|
+
validation state, supply chain, per-finding evidence and CVSS, coverage limits and
|
|
591
|
+
a finding index. It is also available as `argus report <runId> --format research`
|
|
592
|
+
and through MCP.
|
|
593
|
+
|
|
594
|
+
### Authorized-use agreement and operator mode
|
|
595
|
+
|
|
596
|
+
Before the first network assessment, the agent shows a one-time agreement: written
|
|
597
|
+
permission for every target you name, no third parties or cloud metadata, no
|
|
598
|
+
destructive or persistence actions, and responsibility for what runs. Accept it
|
|
599
|
+
once with `/authorize accept <your name>` in the TUI or
|
|
600
|
+
`argus authorize --accept <your name>` from a shell; `--status` shows the record
|
|
601
|
+
and `--revoke` removes it. Acceptance is stored locally in
|
|
602
|
+
`<dataDir>/authorization.json` with a timestamp and turns on operator mode: local
|
|
603
|
+
writes, shell, installs, network and subagents run without confirmation prompts,
|
|
604
|
+
and the agent is told the agreement is in force. It does **not** widen scope — a
|
|
605
|
+
host you did not name is still refused, and read-only instructions still win.
|
|
606
|
+
|
|
607
|
+
Aggression is a setting, not a mystery: saying "do anything", "full hands",
|
|
608
|
+
"ruthless" or "no confirmation" switches the run to the auto approval policy
|
|
609
|
+
(write/shell/install/network/agents), while the prompt-scope guard and deny rules
|
|
610
|
+
still decide which hosts are reachable. The agent is told to chain tools, install
|
|
611
|
+
what it needs, run offensive tooling in the sandbox or WSL, push confirmed weaknesses
|
|
612
|
+
to real impact, and finish with the research report. It works toward the goal rather
|
|
613
|
+
than a checklist: scans are only the map, and it keeps going until the goal is reached
|
|
614
|
+
or a concrete blocker is named.
|
|
615
|
+
|
|
616
|
+
Every tool call is recorded automatically in an attack journal (tool, target or
|
|
617
|
+
package, and whether it worked). Confirmed breaks are pushed to `report_finding` the
|
|
618
|
+
moment they happen, and the research report appends a journal section listing tools
|
|
619
|
+
used, surfaces/packages touched and every attempt with its result - so the deliverable
|
|
620
|
+
names exactly what made the target break, not just the final finding count.
|
|
621
|
+
|
|
622
|
+
`recall` is local vector memory: verified notes and recorded findings are
|
|
623
|
+
indexed with hashed TF-IDF vectors and searched by cosine similarity. It is
|
|
624
|
+
lexical, not an embedding service, and a hit is a lead from earlier work rather
|
|
625
|
+
than new evidence.
|
|
626
|
+
|
|
627
|
+
`http_history` is the session's traffic record. Every `http_request` result is stored
|
|
628
|
+
with method, URL, host, path, status, size, duration and content type, and the tool
|
|
629
|
+
serves either a filtered list (host, status, method, substring, limit) or a per-host
|
|
630
|
+
sitemap of observed endpoints. It prevents blind re-firing of requests and gives the
|
|
631
|
+
model the endpoint map that a proxy-backed agent gets from its intercepting proxy. It
|
|
632
|
+
is in-memory for the session, not a capture file.
|
|
633
|
+
|
|
634
|
+
The agent drives the same pipeline. It works the kill chain
|
|
635
|
+
(map -> hypothesize -> probe -> validate -> exploit -> patch), and `report_finding`
|
|
636
|
+
records a reproduced vulnerability on the current run so it gets a real finding id,
|
|
637
|
+
appears in `get_findings`, `/pipeline` and the reports, and can be cited in the final
|
|
638
|
+
answer. After a scan the loop enforces one continuation when candidates are still
|
|
639
|
+
unvalidated or no exploit path was attempted, instead of accepting the first scan
|
|
640
|
+
as the answer.
|
|
641
|
+
|
|
642
|
+
## Output
|
|
643
|
+
|
|
644
|
+
Each run is stored under `<dataDir>/runs/<runId>/` with `run.json`, `events.jsonl`,
|
|
645
|
+
`findings.jsonl` and reports. `dataDir` defaults to `~/.argus` and can be overridden
|
|
646
|
+
with `argus.config.json` or `ARGUS_DATA_DIR`.
|