pentesting 0.100.5 → 0.100.7
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/ARCHITECTURE.md +512 -442
- package/LICENSE +28 -28
- package/README.md +266 -213
- package/bin/pentesting.mjs +36 -36
- package/lib/runtime.mjs +182 -183
- package/package.json +5 -5
- package/pentesting-logo.svg +13 -13
- package/scripts/postinstall.mjs +33 -33
package/ARCHITECTURE.md
CHANGED
|
@@ -1,447 +1,517 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
This document reflects the current `main` branch architecture. It is the single,
|
|
4
|
-
detailed reference for how the runtime is structured; the [README](README.md)
|
|
5
|
-
stays intentionally short and usage-focused.
|
|
6
|
-
|
|
7
|
-
> **Engine vs product.** The orchestration engine is **`builder`** — a
|
|
8
|
-
> general-purpose, local-first Rust agent runtime. **`pentesting`** is the
|
|
9
|
-
> published, security-focused distribution of that same engine: the npm package
|
|
10
|
-
> and the command you run. They share one binary
|
|
11
|
-
>
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document reflects the current `main` branch architecture. It is the single,
|
|
4
|
+
detailed reference for how the runtime is structured; the [README](README.md)
|
|
5
|
+
stays intentionally short and usage-focused.
|
|
6
|
+
|
|
7
|
+
> **Engine vs product.** The orchestration engine is **`builder`** — a
|
|
8
|
+
> general-purpose, local-first Rust agent runtime. **`pentesting`** is the
|
|
9
|
+
> published, security-focused distribution of that same engine: the npm package
|
|
10
|
+
> and the command you run. They share one binary. The model owns task reasoning;
|
|
11
|
+
> the Rust runtime owns protocol normalization, authorization, bounded execution,
|
|
12
|
+
> observations, and verified outcome provenance.
|
|
13
|
+
|
|
14
|
+
## 1. Architecture at a glance
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
user input
|
|
18
|
+
→ deterministic turn queue
|
|
19
|
+
→ model/provider adapter
|
|
20
|
+
→ one tool gateway
|
|
21
|
+
→ authorized, bounded execution
|
|
22
|
+
→ append observation to the turn
|
|
23
|
+
→ repeat until TurnExit
|
|
24
|
+
→ emit TurnCompleted
|
|
25
|
+
→ emit TaskComplete only for a verified MissionState
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The core is deliberately narrower than the complete product. Its append-only
|
|
29
|
+
`TurnEvent` trajectory contains model terminals, actions, observations, and
|
|
30
|
+
verification provenance. The complete trajectory is stored in the terminal
|
|
31
|
+
`RunOutcome`; the request-time `TurnSnapshot` is its bounded O(1) projection.
|
|
32
|
+
Memory, MCP,
|
|
33
|
+
delegation, CTF exploration, and security sessions use the same tool boundary.
|
|
34
|
+
Engagement context changes instructions, not tool reachability; resource caps
|
|
35
|
+
bound expensive operations.
|
|
36
|
+
|
|
37
|
+
## 2. Design pillars
|
|
38
|
+
|
|
39
|
+
- **Model-Driven Work** — The model chooses plans, probes, commands, and ordinary
|
|
40
|
+
recovery. The runtime does not duplicate that reasoning with hot-path LLM judges.
|
|
41
|
+
- **Hard Boundaries, Not Hard Opinions** — Schema, scope, permission, secrets,
|
|
42
|
+
cancellation, time, output, memory, and process limits are deterministic.
|
|
43
|
+
- **Typed Turn Lifecycle** — Provider terminal state, `TurnExit`, and
|
|
44
|
+
`MissionState` are separate. Stop is never proof of success.
|
|
45
|
+
- **One Tool Entry Boundary** — Built-in, delegated, and MCP tools share
|
|
46
|
+
allowlist, provenance, registered-contract, and schema validation. Hooks are
|
|
47
|
+
orchestrator-owned; permission checks apply only when a tool produces a
|
|
48
|
+
policy operation. Ordinary/MCP tools use configured timeouts, while
|
|
49
|
+
delegation uses its own runtime budget.
|
|
50
|
+
- **Append-Oriented Observation** — Trajectory and evidence are local-first;
|
|
51
|
+
prior-run information is linked by reference rather than copied.
|
|
52
|
+
- **Deterministic Queuing** — FIFO revisions support amend-next and explicit
|
|
53
|
+
replace without auxiliary LLM prioritization.
|
|
54
|
+
- **One Security Surface** — Session, process, finding, flag verification, and
|
|
55
|
+
frontier operations are ordinary tools. Engagement context, permission,
|
|
56
|
+
resource budget, and proof remain separate responsibilities.
|
|
30
57
|
- **Prompt Ownership** — Prompt mode owns Enter submission. Buffered replay may
|
|
31
58
|
preserve typed-ahead input, but live terminal control responses, redraws, and
|
|
32
59
|
resize noise are not allowed to turn a normal Enter into a pasted newline.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- **Ebbinghaus-Inspired Memory** — Memories carry a *strength* that fades like
|
|
40
|
-
human memory and reinforces on recall. Faded notes are de-referenced, never
|
|
41
|
-
destroyed.
|
|
42
|
-
- **Git-Backed Rewind** — Working-tree checkpoint/restore keeps autonomous edits
|
|
43
|
-
reversible.
|
|
44
|
-
|
|
45
|
-
## Runtime
|
|
46
|
-
|
|
47
|
-
```mermaid
|
|
48
|
-
flowchart TD
|
|
49
|
-
U[User request] --> CLI[builder_main CLI / TUI]
|
|
50
|
-
CLI --> API[builder_api facade]
|
|
51
|
-
API --> APP[builder_app coordination]
|
|
52
|
-
APP -->
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
->
|
|
72
|
-
->
|
|
73
|
-
->
|
|
74
|
-
->
|
|
75
|
-
->
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
default
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
G -->
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
60
|
+
Modal return restores the transcript scroll region and its pre-modal saved
|
|
61
|
+
cursor before the fixed bottom UI is redrawn.
|
|
62
|
+
- **Lab Session Multiplexing** — `shell-listener` runs multiple authorized TCP,
|
|
63
|
+
local PTY, and local pipe sessions. A single actor exclusively owns each
|
|
64
|
+
session's descriptors, command queue, transcript, raw log, and child
|
|
65
|
+
lifecycle; the registry keeps only a bounded sender and projection.
|
|
66
|
+
- **Ebbinghaus-Inspired Memory** — Memories carry a *strength* that fades like
|
|
67
|
+
human memory and reinforces on recall. Faded notes are de-referenced, never
|
|
68
|
+
destroyed.
|
|
69
|
+
- **Git-Backed Rewind** — Working-tree checkpoint/restore keeps autonomous edits
|
|
70
|
+
reversible.
|
|
71
|
+
|
|
72
|
+
## 3. Runtime flow, one level deeper
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
flowchart TD
|
|
76
|
+
U[User request] --> CLI[builder_main CLI / TUI]
|
|
77
|
+
CLI --> API[builder_api facade]
|
|
78
|
+
API --> APP[builder_app coordination]
|
|
79
|
+
APP --> TURN[Turn kernel]
|
|
80
|
+
TURN --> MODEL[Provider adapter]
|
|
81
|
+
MODEL --> GW[Tool entry boundary]
|
|
82
|
+
GW --> POLICY[Schema + applicable policy/resource boundary]
|
|
83
|
+
POLICY --> EXEC[Tool / environment execution]
|
|
84
|
+
EXEC --> OBS[Observation + artifact refs]
|
|
85
|
+
OBS --> TURN
|
|
86
|
+
TURN --> EXIT[Typed TurnExit]
|
|
87
|
+
EXIT --> VERIFY[Outcome verifier]
|
|
88
|
+
VERIFY --> OUT[TurnCompleted / verified TaskComplete]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Plain view:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
user input
|
|
95
|
+
-> CLI / interactive prompt loop
|
|
96
|
+
-> terminal-session prompt ownership + buffered replay boundary
|
|
97
|
+
-> BuilderAPI facade
|
|
98
|
+
-> BuilderApp turn kernel and provider adapter
|
|
99
|
+
-> registered tool contract and common entry boundary
|
|
100
|
+
-> policy-gated, resource-bounded execution
|
|
101
|
+
-> observation and artifact references
|
|
102
|
+
-> typed turn exit and optional verified mission outcome
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Builder is a domain-neutral runtime with a security-focused distribution.
|
|
106
|
+
Development, pentesting, CTF, audit, and release behavior layers in through
|
|
107
|
+
context, tools, and skills rather than new core strategy kinds.
|
|
108
|
+
|
|
109
|
+
### Runtime persistence ports
|
|
110
|
+
|
|
111
|
+
Hot-path consumers depend on ten cohesive persistence ports:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
run/objective/evidence/task/execution/outcome
|
|
115
|
+
audit/observation/lineage/conversation-memory
|
|
116
|
+
|
|
|
117
|
+
local persistence composition root
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Each producer/consumer depends on the smallest relevant port. The methodless
|
|
121
|
+
`ControlPlaneRepository` marker composes those ports only at construction and
|
|
122
|
+
dynamic storage boundaries. Implementations and test fakes implement the
|
|
123
|
+
physical ports directly; there are no blanket forwarding adapters, fallback
|
|
124
|
+
methods, alternate schemas, or second runtime state.
|
|
125
|
+
|
|
126
|
+
## 4. Engagement context and bounded CTF exploration
|
|
127
|
+
|
|
128
|
+
There is no model-backed intent classifier or weak/standard model mode in the
|
|
129
|
+
request hot path. Explicit event metadata is routed deterministically; absent
|
|
130
|
+
metadata receives one general strategy. Named profiles may add context, but
|
|
131
|
+
coarse labels do not authorize or reject tool calls.
|
|
132
|
+
|
|
133
|
+
CTF engagement metadata may select `ctf-competition` prompt context, and
|
|
134
|
+
`flag_check` remains a verification tool and evidence source rather than a
|
|
135
|
+
default completion gate. `explore` is always available; `[exploration]` only
|
|
136
|
+
sets node and fan-out caps. See `docs/config/ctf.toml`,
|
|
137
|
+
`docs/plans/2026/07/08/PLAN_CtfFrontierExploration_2026-07-08.md`, and the
|
|
138
|
+
decision record beside it.
|
|
139
|
+
|
|
140
|
+
The shipped exploration tool does not replace the core execution strategy.
|
|
141
|
+
It provides a bounded `EvidenceKind::Lead` ledger and explicit dispatch. Stable
|
|
142
|
+
generated identity is separate from semantic deduplication. Dead probes suppress
|
|
143
|
+
an execution branch without rejecting its knowledge hypothesis, and fresh
|
|
144
|
+
evidence reopens scheduling. There is no passive `/frontier` command, detached
|
|
145
|
+
task registry, or second scheduler. `orch_spec::exploration_e2e` pins the off
|
|
146
|
+
path and the explicit breadth/depth/pivot/reseed/merge behavior.
|
|
147
|
+
|
|
148
|
+
Reliability guards sit below the profile layer. Provider protocol capabilities
|
|
149
|
+
default native tool support for OpenAI/Anthropic-compatible responses on
|
|
150
|
+
registry misses, unparsed tool-shaped markup becomes retryable instead of a
|
|
151
|
+
false completion, raw control markup is scrubbed from the stream, and the
|
|
152
|
+
markdown renderer flushes long no-newline prose at soft boundaries while still
|
|
153
|
+
bounding very large buffers.
|
|
154
|
+
|
|
155
|
+
```mermaid
|
|
156
|
+
flowchart LR
|
|
157
|
+
R[Request] --> GEN["Resolve<br/>task-shaped defaults"]
|
|
158
|
+
GEN --> REC["Optional<br/>named profile / pack"]
|
|
159
|
+
REC --> USE["Bound<br/>tool scope and budget"]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Request to closure:
|
|
163
|
+
|
|
164
|
+
```mermaid
|
|
165
|
+
flowchart TD
|
|
166
|
+
U[User request] --> A[Agent turn]
|
|
167
|
+
A --> M[Model output]
|
|
168
|
+
M --> T{Registered action?}
|
|
169
|
+
T -- no --> X[Typed turn exit]
|
|
170
|
+
T -- yes --> G[Common tool gateway]
|
|
171
|
+
G --> O[Observation]
|
|
172
|
+
O --> A
|
|
173
|
+
X --> V{Verified artifact?}
|
|
174
|
+
V -- no --> TC[TurnCompleted]
|
|
175
|
+
V -- yes --> MC[TaskComplete + provenance]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Agent Team
|
|
179
|
+
|
|
180
|
+
The core agent team is domain-neutral. Each agent ships as a markdown persona
|
|
181
|
+
definition under `crates/builder_repo/src/agents/`.
|
|
182
|
+
|
|
183
|
+
Subagents are retained as an explicit, bounded capability. The default is one
|
|
184
|
+
agent turn loop; the model delegates only work that is independently scoped or
|
|
185
|
+
benefits from parallel exploration. A delegated child receives a focused
|
|
186
|
+
overlay and budget, runs through the same tool/policy gateway, records
|
|
187
|
+
parent-child lineage, and returns evidence references for conservative merge.
|
|
188
|
+
Removing always-on classifier/judge agents did not remove the `task` tool,
|
|
189
|
+
child conversations, specialist agents, or frontier fan-out.
|
|
190
|
+
|
|
191
|
+
| Agent | Default role | Runtime profile |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| `builder` | Hands-on implementation, refactoring, local file changes, tests | Implement + broad local write |
|
|
194
|
+
| `planner` | Implementation plans and risk breakdowns | Plan + read-only |
|
|
195
|
+
| `researcher` | Read-only codebase and reference research | Investigate + read-only |
|
|
196
|
+
| `coordinator` | Splits broad work into owned packets and consolidates results | Coordinate + broad local write |
|
|
197
|
+
| `investigator` | Evidence gathering across code, logs, commands, APIs, and behavior | Investigate + shell diagnostics |
|
|
198
|
+
| `operator` | Builds, tests, packaging, service startup, and runtime workflows | Implement + broad local write |
|
|
199
|
+
| `reviewer` | Findings-first technical review | Review + strict read-only |
|
|
200
|
+
| `verifier` | Reproduction, build/test proof, and completion claim checks | Verify + strict read-only |
|
|
201
|
+
| `report-writer` | Reports, handoffs, release notes, and reproducibility records | Implement + bounded write |
|
|
202
|
+
|
|
203
|
+
> Distinct tool-scope is runtime-enforced for `builder`, `planner`, and
|
|
204
|
+
> `researcher`; the remaining personas share a task-shaped generic profile
|
|
205
|
+
> (read-only when the task shape is review/verify, broad local write otherwise)
|
|
206
|
+
> and differ by their prompt instructions.
|
|
207
|
+
|
|
208
|
+
## Named Autonomy Profiles
|
|
209
|
+
|
|
172
210
|
Optionally pin the top-level profile (`autonomy_profile = "ctf-competition"`);
|
|
173
|
-
leave unset for
|
|
174
|
-
|
|
175
|
-
stay intact. Defined in
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
U --
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
F --
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Q -->
|
|
229
|
-
Q -->
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
RUN -->
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
|
278
|
-
|
|
|
279
|
-
|
|
|
280
|
-
|
|
|
281
|
-
|
|
|
282
|
-
|
|
|
283
|
-
|
|
|
284
|
-
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
- `
|
|
295
|
-
- `
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
211
|
+
leave unset for the deterministic general default. CTF engagement config may
|
|
212
|
+
select CTF prompt context when no explicit profile is set, but it never changes
|
|
213
|
+
tool reachability. Delegated subagent contracts stay intact. Defined in
|
|
214
|
+
`crates/builder_domain/src/autonomy_profile.rs`.
|
|
215
|
+
|
|
216
|
+
| Profile | Purpose |
|
|
217
|
+
| --- | --- |
|
|
218
|
+
| `general-agent` | Broad autonomous local orchestration for mixed tasks |
|
|
219
|
+
| `local-builder` | Hands-on implementation with fresh evidence retrieval |
|
|
220
|
+
| `ctf-competition` | Competition/lab workflow backed by `ctf-competition` and `pentesting-methodology` skills |
|
|
221
|
+
| `enterprise-review` | Strict, review-heavy profile with read-only dynamic scope |
|
|
222
|
+
|
|
223
|
+
## Engagement Metadata
|
|
224
|
+
|
|
225
|
+
Runs can attach typed engagement context — scope, phase, tags, flag format,
|
|
226
|
+
flag-evidence requirement, and standard refs (PTES, MITRE ATT&CK, OWASP,
|
|
227
|
+
CWE/CAPEC, NIST CSF, CIS Controls) — to workflow metadata. `/workflow report`
|
|
228
|
+
exports it as a Markdown handoff.
|
|
229
|
+
|
|
230
|
+
## Memory & Knowledge
|
|
231
|
+
|
|
232
|
+
Local-first and split across two complementary layers, no vector DB, no cloud:
|
|
233
|
+
|
|
234
|
+
- **Conversation memories** — facts/preferences/gotchas distilled from sessions,
|
|
235
|
+
persisted in local runtime state and recalled into each prompt by hybrid
|
|
236
|
+
retrieval. These carry a *strength* that fades like human memory, so the store
|
|
237
|
+
stays sharp instead of rotting.
|
|
238
|
+
- **Knowledge vault** — an optional Obsidian-style set of markdown notes under
|
|
239
|
+
`.pentesting/knowledge` (wiki-links, backlinks, tags). The agent reads it on every
|
|
240
|
+
turn and grows it with the `write` tool; it is never auto-deleted.
|
|
241
|
+
|
|
242
|
+
Both layers feed the same strength-weighted hybrid retrieval.
|
|
243
|
+
|
|
244
|
+
**Storage** — Ebbinghaus lifecycle (decay · reinforce · floor, never deleted):
|
|
245
|
+
|
|
246
|
+
```mermaid
|
|
247
|
+
flowchart TD
|
|
248
|
+
N[New memory] --> S["strength = quality × recall × e^-λ·age"]
|
|
249
|
+
S --> U{recalled?}
|
|
250
|
+
U -- yes --> RE[reinforce ↑ · reset age]
|
|
251
|
+
U -- no --> D[decay over time]
|
|
252
|
+
RE --> S
|
|
253
|
+
D --> F{below floor?}
|
|
254
|
+
F -- no --> S
|
|
255
|
+
F -- yes --> AR[de-reference: archive / tombstone]
|
|
256
|
+
AR -. recoverable on disk .-> N
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Kinds fade at different speeds (procedural outlives episodic); bi-temporal
|
|
260
|
+
`event_time` vs `ingestion_time` lets newer facts supersede stale ones.
|
|
261
|
+
|
|
262
|
+
**Retrieval** — hybrid fuse, strength-weighted, read-only:
|
|
263
|
+
|
|
264
|
+
```mermaid
|
|
265
|
+
flowchart LR
|
|
266
|
+
Q[Query] --> L[Lexical]
|
|
267
|
+
Q --> SE[Semantic]
|
|
268
|
+
Q --> G[Graph]
|
|
269
|
+
L --> RRF[RRF fuse]
|
|
270
|
+
SE --> RRF
|
|
271
|
+
G --> RRF
|
|
272
|
+
RRF --> RR[rerank: phase · recency · task]
|
|
273
|
+
RR --> W[weight by strength]
|
|
274
|
+
W --> P[Prompt context]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Faded, private, or unsafe memories are held back from the prompt. Lookups never
|
|
278
|
+
write — reinforce/archive/supersede are explicit, never search side effects.
|
|
279
|
+
|
|
280
|
+
## Storage Strategy
|
|
281
|
+
|
|
282
|
+
Builder uses one operational storage strategy: local on-disk runtime state plus
|
|
283
|
+
markdown-native knowledge artifacts.
|
|
284
|
+
|
|
285
|
+
```mermaid
|
|
286
|
+
flowchart LR
|
|
287
|
+
W[Workspace files] --> AD[Source adapters]
|
|
288
|
+
S[Skills] --> AD
|
|
289
|
+
M[Conversation memories] --> AD
|
|
290
|
+
N[Markdown notes] --> AD
|
|
291
|
+
AD --> IDX[Local lexical + semantic + graph index]
|
|
292
|
+
IDX --> RR[Contextual reranker]
|
|
293
|
+
RR --> PC[Prompt context]
|
|
294
|
+
PC --> RUN[Agent run]
|
|
295
|
+
RUN --> LS[.pentesting local state]
|
|
296
|
+
RUN --> ART[Local artifacts and reports]
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Key invariants:
|
|
300
|
+
|
|
301
|
+
- Runtime state is local-first and does not require an external data service.
|
|
302
|
+
- The markdown knowledge graph is derived from local facts: notes, skills,
|
|
303
|
+
conversation memory, wiki-links, backlinks, and run artifacts.
|
|
304
|
+
- Graph data is a derived retrieval view, not a second source of truth.
|
|
305
|
+
- Evidence, workflow runs, state cards, and verified artifacts persist through
|
|
306
|
+
local repositories. Removed semantic-verdict, recovery-route, completion
|
|
307
|
+
bundle, replay-archive, and curation projections cannot redirect the active
|
|
308
|
+
model loop because they no longer exist in the runtime model.
|
|
309
|
+
- Domain methods such as development, CTF practice, pentesting methodology,
|
|
310
|
+
audits, and release work live in skills and task instructions; they do not
|
|
311
|
+
change the core runtime identity.
|
|
312
|
+
|
|
313
|
+
## Crate Map
|
|
314
|
+
|
|
315
|
+
| Layer | Crates | Responsibility |
|
|
316
|
+
| --- | --- | --- |
|
|
317
|
+
| Interaction | `builder_main`, `builder_ratatui`, `builder_select`, `builder_markdown_stream` | CLI, TUI, prompt flow, rendering, selector fallback |
|
|
318
|
+
| Facade | `builder_api` | Thin application boundary used by entry points |
|
|
319
|
+
| Coordination | `builder_app` | turn loop, provider adaptation, common tool gateway, observations, verified outcome |
|
|
320
|
+
| Contracts | `builder_domain` | typed IDs, tools, workflow records, engagement metadata, policies |
|
|
321
|
+
| Capabilities | `builder_services` | tool services, auth, provider support, file/search/shell/fetch operations |
|
|
322
|
+
| Persistence | `builder_repo`, `builder_provider_repo` | local repositories, provider catalog, chat repository |
|
|
323
|
+
| Knowledge | `builder_knowledge`, `builder_workspace_index`, `builder_embed` | markdown note adapters, graph parsing, hybrid retrieval, local semantic scoring |
|
|
324
|
+
| Infrastructure | `builder_config`, `builder_infra`, `builder_fs`, `builder_walker` | config, environment, filesystem, process/runtime helpers |
|
|
325
|
+
| Support | `builder_display`, `builder_stream`, `builder_template`, `builder_json_repair`, `builder_snaps`, `builder_brand`, `builder_tracker`, `builder_test_kit`, `builder_tool_macros` | formatting, streaming, templates, JSON repair, snapshots, branding/theming, version tracking, tests, tool macros |
|
|
326
|
+
|
|
327
|
+
## Tool Surface
|
|
328
|
+
|
|
329
|
+
The runtime tool catalog is file, shell, network-fetch, planning, skill, todo,
|
|
330
|
+
and delegation oriented. Core tools:
|
|
331
|
+
|
|
332
|
+
- `read`, `write`, `patch`, `multi_patch`, `undo`, `remove`
|
|
333
|
+
- `fs_search`, `sem_search`
|
|
334
|
+
- `shell`, `fetch`
|
|
335
|
+
- `plan`, `skill`, `todo_read`, `todo_write`
|
|
336
|
+
- `task` and dynamically registered agent tools
|
|
337
|
+
|
|
338
|
+
The full catalog (`builder_domain/src/tools/catalog.rs`) also includes web
|
|
339
|
+
search, memory, verification primitives, session/process control, and
|
|
340
|
+
compaction tools. Security-session primitives, `flag_check`, and `explore` are
|
|
341
|
+
all present on the same surface. Engagement metadata supplies context;
|
|
342
|
+
permission and resource budgets constrain execution. Direct raw storage-query
|
|
343
|
+
tooling is not part of the active runtime surface.
|
|
344
|
+
|
|
345
|
+
## Verification And Completion
|
|
346
|
+
|
|
347
|
+
Turn closure and mission closure are separate:
|
|
348
|
+
|
|
349
|
+
```text
|
|
350
|
+
provider terminal
|
|
351
|
+
-> TurnExit
|
|
352
|
+
-> TurnCompleted
|
|
353
|
+
|
|
354
|
+
candidate outcome + trusted artifact
|
|
355
|
+
-> bind objective + target + verifier + artifact + freshness
|
|
356
|
+
-> MissionState::Verified
|
|
357
|
+
-> TaskComplete
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The key rule is that a model response may finish a turn but cannot prove the
|
|
361
|
+
mission. The former completion-adjudicator, semantic self-review, consensus
|
|
362
|
+
panel, recovery synthesis, and hot-path replay export have been removed. A
|
|
363
|
+
trusted verifier with explicit provenance is the only mission-promotion path;
|
|
364
|
+
`flag_check` is the direct CTF fast path.
|
|
365
|
+
|
|
366
|
+
## Diagnostic UI boundary
|
|
367
|
+
|
|
368
|
+
The default TUI renders the response stream and deterministic input queue. It
|
|
369
|
+
does not maintain a second workflow engine. `/status` consumes one immutable
|
|
370
|
+
`RunStatusProjection`; `/workflow report` is the explicit offline export. The
|
|
371
|
+
former bare `/workflow` alias has been removed. The live status row deliberately
|
|
372
|
+
shows only actionable progress/wait state; frontier JSON is not parsed into
|
|
373
|
+
hidden chrome state, and full run/tool detail remains in explicit output and
|
|
374
|
+
`/status`.
|
|
375
|
+
|
|
376
|
+
## Distribution — single source, two surfaces
|
|
377
|
+
|
|
378
|
+
Pentesting and Builder share the **same Rust runtime binary**. The `pentesting`
|
|
379
|
+
npm package is a thin distribution facade:
|
|
380
|
+
|
|
381
|
+
```text
|
|
382
|
+
npm install -g pentesting
|
|
383
|
+
│
|
|
384
|
+
▼
|
|
385
|
+
pentesting CLI (Node.js shim)
|
|
386
|
+
│ resolves or downloads the matching Builder release asset
|
|
387
|
+
▼
|
|
388
|
+
Builder binary (Rust) ← single runtime engine
|
|
389
|
+
│ PENTESTING_PRODUCT_NAME=pentesting
|
|
390
|
+
▼
|
|
391
|
+
Interactive TUI with "pentesting" banner
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
- The npm package installs a launcher, **not** a second agent runtime.
|
|
395
|
+
- It resolves or downloads the correct release asset from
|
|
396
|
+
`agnusdei1207/pentesting-public`.
|
|
397
|
+
- It forwards arguments directly into the Rust binary — no command translation
|
|
398
|
+
or compatibility shims.
|
|
399
|
+
- If a change would add orchestration, memory, or prompt logic into the npm
|
|
400
|
+
layer, that change belongs upstream in the Rust runtime.
|
|
401
|
+
|
|
402
|
+
## Supported Runtime Targets
|
|
403
|
+
|
|
346
404
|
The npm launcher currently resolves a managed native release asset for Linux
|
|
347
|
-
x64.
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
|
353
|
-
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
|
387
|
-
|
|
|
388
|
-
|
|
|
389
|
-
|
|
|
390
|
-
|
|
|
391
|
-
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
405
|
+
x64. Docker is the recommended runtime on Windows and macOS. Published Docker
|
|
406
|
+
images support `linux/amd64` only; Apple Silicon Macs use Docker Desktop's amd64
|
|
407
|
+
emulation. Native ARM64 images and binaries are not supported. Advanced users
|
|
408
|
+
may set `PENTESTING_BIN` to a locally supplied compatible binary.
|
|
409
|
+
|
|
410
|
+
| OS | CPU | Release asset |
|
|
411
|
+
| --- | --- | --- |
|
|
412
|
+
| Linux | x64 | `pentesting-x86_64-unknown-linux-musl` |
|
|
413
|
+
|
|
414
|
+
`/update` (and the npm postinstall) resolves the matching asset for the current
|
|
415
|
+
supported OS/CPU target from `agnusdei1207/pentesting-public`.
|
|
416
|
+
|
|
417
|
+
## Build containment boundary
|
|
418
|
+
|
|
419
|
+
Compilation is outside the application runtime boundary and is always executed
|
|
420
|
+
through resource-capped Docker wrappers. Host Cargo is not an emergency
|
|
421
|
+
fallback. `dbuild.sh` owns individual Cargo commands, `dverify.sh` owns
|
|
422
|
+
sequential gate profiles, and `dbuild-image.sh` owns BuildKit. Each path shares
|
|
423
|
+
storage admission, effective-limit inspection, a machine-wide lock, watchdogs,
|
|
424
|
+
and structured failure reports. CI invokes the same container boundary. The
|
|
425
|
+
normative contract is [Docker-only build safety](https://github.com/agnusdei1207/pentesting/blob/main/docs/BUILD_SAFETY.md).
|
|
426
|
+
|
|
427
|
+
The measured next-stage simplification and deletion plan is indexed at
|
|
428
|
+
[Minimal Core plan](https://github.com/agnusdei1207/pentesting/blob/main/docs/plans/2026/07/10/minimal-core/README.md).
|
|
429
|
+
The concrete PTY actor, unified security-tool surface, turn-trajectory, and dead-path reduction is
|
|
430
|
+
recorded in [the 2026-07-10 implementation report](docs/plans/2026/07/10/IMPLEMENTATION_LightweightCoreRefactor_2026-07-10.md).
|
|
431
|
+
|
|
432
|
+
## Configuration
|
|
433
|
+
|
|
434
|
+
Pentesting reads a user-global config from `~/.pentesting/.pentesting.toml`,
|
|
435
|
+
overridden by project-local `.pentesting.toml` files discovered by walking up
|
|
436
|
+
from the working directory. Local storage is the default; normal setup only
|
|
437
|
+
needs the public model endpoint environment.
|
|
438
|
+
|
|
439
|
+
The same shape is represented in `builder.schema.json`, `.pentesting.toml`, and
|
|
440
|
+
the interactive `/config` UI. Set `PENTESTING_CONFIG` to override the global
|
|
441
|
+
config directory.
|
|
442
|
+
|
|
443
|
+
| Variable | Description |
|
|
444
|
+
| --- | --- |
|
|
445
|
+
| `OPENAI_API_KEY` | API key or gateway token for OpenAI-compatible providers. |
|
|
446
|
+
| `OPENAI_BASE_URL` | OpenAI-compatible base URL, for example `https://api.openai.com/v1` or a self-hosted gateway. |
|
|
447
|
+
| `OPENAI_MODEL` | Default model id. |
|
|
448
|
+
| `OPENAI_MAX_TOKENS` | Optional output-token override; accepts values like `4096`, `32k`, or `1M`. |
|
|
449
|
+
| `PENTESTING_BIN` | Use an already-installed Builder binary instead of the managed download. |
|
|
450
|
+
| `PENTESTING_PRODUCT_NAME` | Runtime banner label. The `pentesting` launcher sets this to `pentesting` automatically. |
|
|
451
|
+
| `PENTESTING_REPO` | Override the public release repo used for binary downloads. Defaults to `agnusdei1207/pentesting-public`. |
|
|
452
|
+
| `PENTESTING_SKIP_DOWNLOAD` | Skip the postinstall binary download. Useful in CI or when `PENTESTING_BIN` will be provided later. |
|
|
453
|
+
| `PENTESTING_CONFIG` | Override the global config directory. |
|
|
454
|
+
|
|
455
|
+
### Canonical configuration contract
|
|
456
|
+
|
|
457
|
+
The next-generation runtime accepts one product namespace. Configuration uses
|
|
458
|
+
`PENTESTING_*`, `~/.pentesting/.pentesting.toml`, and project-local
|
|
459
|
+
`.pentesting.toml`. `BUILDER_*`, `.builder.toml`, `.builder/`, JSON config
|
|
460
|
+
fallbacks, and runtime alias translation have been removed. Existing users must
|
|
461
|
+
move data explicitly before upgrading; the runtime does not carry a permanent
|
|
462
|
+
old/new branch.
|
|
463
|
+
|
|
464
|
+
## Interactive Commands
|
|
465
|
+
|
|
466
|
+
Inside an interactive session, these commands inspect and drive runtime state
|
|
467
|
+
(`/help` lists the full set):
|
|
468
|
+
|
|
469
|
+
```text
|
|
470
|
+
/status Show the current run phase, active tasks, hooks, and budget signals
|
|
471
|
+
/workflow report
|
|
472
|
+
Export the active run, engagement metadata, evidence, and large outputs to Markdown
|
|
473
|
+
/context Show recent context-budget snapshots for the current conversation
|
|
474
|
+
/memory Show stored conversation memories for the current conversation
|
|
475
|
+
/tools List the currently available tools and schemas
|
|
476
|
+
/agent Switch the active agent
|
|
477
|
+
/conversation Browse conversations for the active workspace
|
|
478
|
+
/goal <task> Set the active goal without enabling autonomous mode
|
|
479
|
+
/auto Explicitly toggle autonomous mode for the current goal (default: off)
|
|
480
|
+
/update Download and apply the latest public release asset for supported native targets
|
|
481
|
+
/help Show all commands
|
|
482
|
+
/exit Quit
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Security Domain Skills
|
|
486
|
+
|
|
487
|
+
The `ctf-competition` and `pentesting-methodology` skills map authorized
|
|
488
|
+
assessments to standard frameworks:
|
|
489
|
+
|
|
490
|
+
- **PTES** (Penetration Testing Execution Standard)
|
|
491
|
+
- **MITRE ATT&CK** tactics and techniques
|
|
492
|
+
- **OWASP** Top 10 and Testing Guide
|
|
493
|
+
- **CWE/CAPEC** weakness and attack pattern catalogs
|
|
494
|
+
- **NIST CSF** and **CIS Controls**
|
|
495
|
+
|
|
496
|
+
### Shell listener for authorized labs
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
pentesting shell-listener --bind 127.0.0.1 --port 4444
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Manages multiple accepted TCP sessions with per-session routing, buffered
|
|
503
|
+
output, raw byte logging, full-duplex transcripts, command history, attach /
|
|
504
|
+
detach events, replay, and evidence manifests. `pty-upgrade` sends the helper
|
|
505
|
+
only; `upgrade` runs the helper plus a probe and records `pty_state` as verified
|
|
506
|
+
or failed. The upgrade helper is drawn from a named technique catalog
|
|
507
|
+
(`python3`, `python`, `python2`, `script`, `expect`) selectable per request —
|
|
508
|
+
there is no default, so the request is rejected unless the caller picks a
|
|
509
|
+
technique or supplies a full custom command, forcing the agent to recon the
|
|
510
|
+
target and match what it actually has instead of assuming one interpreter; a
|
|
511
|
+
missing tool is recorded as `pty_state=failed` with reason `<technique> helper
|
|
512
|
+
unavailable`. Raw logs and transcripts are capped per session and closed sessions
|
|
513
|
+
are archived automatically so a noisy peer cannot grow memory or disk without
|
|
514
|
+
bound. Secret redaction is applied before new raw/transcript/display records are
|
|
515
|
+
written; it is not retroactive for output that arrived before the secret value
|
|
516
|
+
was registered. Bound to loopback by default; `--allow-remote` is an explicit
|
|
517
|
+
opt-in gate.
|