pentesting 0.100.5 → 0.100.10

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 CHANGED
@@ -1,447 +1,523 @@
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; `pentesting` is `builder` with
11
- > a security skill set and banner. The model proposes actions, while the Rust
12
- > runtime owns routing, tool policy, evidence capture, verification, and
13
- > completion adjudication.
14
-
15
- ## Design Pillars
16
-
17
- - **Runtime-Owned Adjudication** — Model output is a *candidate* until a runtime
18
- acceptance-gate lattice verifies and closes the task (outcome: complete /
19
- replan / blocked).
20
- - **Local-First State** — Runtime state and a markdown knowledge graph live on
21
- disk. No external storage service.
22
- - **Weak-Model Hardening** Rust-enforced classifiers, validators, and
23
- self-reviews guard against hallucination.
24
- - **Lineage & Horizons** — Run lineage, objective IDs, and horizon-aware memory
25
- reuse, all in local state.
26
- - **Policy-Gated Tools** — `Allow/Deny/Confirm` gates shell, file, and network
27
- access (policy-based today; OS sandboxing is roadmap).
28
- - **Intelligent Queuing** Queued inputs are deduplicated and prioritized live;
29
- obsolete tasks are preempted, not FIFO-replayed.
30
- - **Prompt Ownership** Prompt mode owns Enter submission. Buffered replay may
31
- preserve typed-ahead input, but live terminal control responses, redraws, and
32
- resize noise are not allowed to turn a normal Enter into a pasted newline.
33
- - **Lab Session Multiplexing** `shell-listener` runs multiple authorized TCP
34
- sessions with per-session routing, identity tags, verified PTY upgrade state,
35
- transcripts, command ledgers, replay, and orphaned evidence recovery.
36
- - **Dynamic Agent Profiles** — No fixed persona: the runtime *derives* a profile
37
- per request from the prompt and can overlay a named autonomy profile, driving
38
- tool scope, phase, and memory weighting.
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 Flow
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 --> CLS[Intent classifier]
53
- CLS --> STR[Dynamic profile + execution strategy]
54
- STR --> AG[Active agent]
55
- AG --> DEC{Delegate?}
56
- DEC -- no --> TOOLS[Policy-gated tools]
57
- DEC -- yes --> SUB[Subagent task packet]
58
- SUB --> TOOLS
59
- TOOLS --> EV[Evidence + state cards]
60
- EV --> VER[Verification gates]
61
- VER --> DONE[Completion adjudication]
62
- DONE --> STORE[Local runtime state]
63
- STORE --> CTX[Next-turn context]
64
- CTX --> APP
65
- ```
66
-
67
- Plain view:
68
-
69
- ```text
70
- user input
71
- -> CLI / interactive prompt loop
72
- -> terminal-session prompt ownership + buffered replay boundary
73
- -> BuilderAPI facade
74
- -> BuilderApp classification and strategy
75
- -> active agent or delegated subagent
76
- -> policy-gated tool execution
77
- -> evidence, workflow state, and verification records
78
- -> completion adjudication
79
- -> local state and next-turn context
80
- ```
81
-
82
- Builder is a **domain-neutral** runtime with a security focus. Development,
83
- pentesting, CTF, audit, and release work layer in via skills — never baked into
84
- the core.
85
-
86
- ## Dynamic Agent Profiles
87
-
88
- There is no fixed persona. The runtime derives a profile per request, optionally
89
- overlays a named autonomy profile, then reuses tool scope, phase, and memory
90
- weighting.
91
-
92
- CTF frontier exploration keeps the global `[exploration]` default off, then
93
- enables the effective CTF profile when `engagement.kind = "ctf"` or a
94
- `flag_format` is configured. That profile selects `ctf-competition` autonomy,
95
- turns on exploration, requires verified `flag_check` evidence before completion,
96
- and auto-continues the TUI loop after `/goal`. See `docs/config/ctf.toml`,
97
- `docs/plans/2026/07/08/PLAN_CtfFrontierExploration_2026-07-08.md`, and the
98
- decision record beside it.
99
-
100
- The shipped design is advisor-guided, not scheduler-owned: `decide_next` is a
101
- pure traversal recommendation over `EvidenceKind::Lead` events, while dispatch
102
- uses the existing delegated-task fan-out. There is no detached task registry or
103
- second runtime scheduler in the default implementation. Phase 10 is pinned by
104
- `orch_spec::exploration_e2e`, which exercises the flag-off path and the
105
- breadth/depth/pivot/reseed/merge flow without launching real subagents.
106
-
107
- Reliability guards sit below the profile layer. Provider protocol capabilities
108
- default native tool support for OpenAI/Anthropic-compatible responses on
109
- registry misses, unparsed tool-shaped markup becomes retryable instead of a
110
- false completion, raw control markup is scrubbed from the stream, and the
111
- markdown renderer bounds very large no-newline buffers.
112
-
113
- ```mermaid
114
- flowchart LR
115
- R[Request] --> GEN["Derive<br/>dynamic profile"]
116
- GEN --> REC["Overlay<br/>named autonomy profile"]
117
- REC --> USE["Reuse<br/>tool scope · phase · memory weight"]
118
- ```
119
-
120
- Request to closure:
121
-
122
- ```mermaid
123
- flowchart TD
124
- U[User request] --> C[Intent classifier]
125
- C --> P[Dynamic profile<br/>task shape + tool scope + rigor]
126
- P --> R[Runtime router]
127
- R --> A[Active agent]
128
- A --> T{Need delegation?}
129
- T -- no --> O[Tool execution]
130
- T -- yes --> D[Agent tool]
131
- D --> CO[coordinator]
132
- D --> I[investigator]
133
- D --> OP[operator]
134
- D --> RV[reviewer]
135
- D --> V[verifier]
136
- D --> W[report-writer]
137
- CO --> O
138
- I --> O
139
- OP --> O
140
- RV --> O
141
- V --> O
142
- W --> O
143
- O --> G[Completion gates]
144
- G --> M[Memory + artifacts]
145
- M --> U
146
- ```
147
-
148
- ## Agent Team
149
-
150
- The core agent team is domain-neutral. Each agent ships as a markdown persona
151
- definition under `crates/builder_repo/src/agents/`.
152
-
153
- | Agent | Default role | Runtime profile |
154
- | --- | --- | --- |
155
- | `builder` | Hands-on implementation, refactoring, local file changes, tests | Implement + broad local write |
156
- | `planner` | Implementation plans and risk breakdowns | Plan + read-only |
157
- | `researcher` | Read-only codebase and reference research | Investigate + read-only |
158
- | `coordinator` | Splits broad work into owned packets and consolidates results | Coordinate + broad local write |
159
- | `investigator` | Evidence gathering across code, logs, commands, APIs, and behavior | Investigate + shell diagnostics |
160
- | `operator` | Builds, tests, packaging, service startup, and runtime workflows | Implement + broad local write |
161
- | `reviewer` | Findings-first technical review | Review + strict read-only |
162
- | `verifier` | Reproduction, build/test proof, and completion claim checks | Verify + strict read-only |
163
- | `report-writer` | Reports, handoffs, release notes, and reproducibility records | Implement + bounded write |
164
-
165
- > Distinct tool-scope is runtime-enforced for `builder`, `planner`, and
166
- > `researcher`; the remaining personas share a task-shaped generic profile
167
- > (read-only when the task shape is review/verify, broad local write otherwise)
168
- > and differ by their prompt instructions.
169
-
170
- ## Named Autonomy Profiles
171
-
172
- Optionally pin the top-level profile (`autonomy_profile = "ctf-competition"`);
173
- leave unset for classifier-driven defaults. CTF engagement config auto-selects
174
- the CTF profile when no explicit profile is set. Delegated subagent contracts
175
- stay intact. Defined in `crates/builder_domain/src/autonomy_profile.rs`.
176
-
177
- | Profile | Purpose |
178
- | --- | --- |
179
- | `general-agent` | Broad autonomous local orchestration for mixed tasks |
180
- | `local-builder` | Hands-on implementation with fresh evidence retrieval |
181
- | `ctf-competition` | Competition/lab workflow backed by `ctf-competition` and `pentesting-methodology` skills |
182
- | `enterprise-review` | Strict, review-heavy profile with read-only dynamic scope |
183
-
184
- ## Engagement Metadata
185
-
186
- Runs can attach typed engagement context — scope, phase, tags, flag format,
187
- flag-evidence requirement, and standard refs (PTES, MITRE ATT&CK, OWASP,
188
- CWE/CAPEC, NIST CSF, CIS Controls) to workflow metadata. `/workflow report`
189
- exports it as a Markdown handoff.
190
-
191
- ## Memory & Knowledge
192
-
193
- Local-first and split across two complementary layers, no vector DB, no cloud:
194
-
195
- - **Conversation memories** facts/preferences/gotchas distilled from sessions,
196
- persisted in local runtime state and recalled into each prompt by hybrid
197
- retrieval. These carry a *strength* that fades like human memory, so the store
198
- stays sharp instead of rotting.
199
- - **Knowledge vault** an optional Obsidian-style set of markdown notes under
200
- `.builder/knowledge` (wiki-links, backlinks, tags). The agent reads it on every
201
- turn and grows it with the `write` tool; it is never auto-deleted.
202
-
203
- Both layers feed the same strength-weighted hybrid retrieval.
204
-
205
- **Storage** Ebbinghaus lifecycle (decay · reinforce · floor, never deleted):
206
-
207
- ```mermaid
208
- flowchart TD
209
- N[New memory] --> S["strength = quality × recall × e^-λ·age"]
210
- S --> U{recalled?}
211
- U -- yes --> RE[reinforce ↑ · reset age]
212
- U -- no --> D[decay over time]
213
- RE --> S
214
- D --> F{below floor?}
215
- F -- no --> S
216
- F -- yes --> AR[de-reference: archive / tombstone]
217
- AR -. recoverable on disk .-> N
218
- ```
219
-
220
- Kinds fade at different speeds (procedural outlives episodic); bi-temporal
221
- `event_time` vs `ingestion_time` lets newer facts supersede stale ones.
222
-
223
- **Retrieval** hybrid fuse, strength-weighted, read-only:
224
-
225
- ```mermaid
226
- flowchart LR
227
- Q[Query] --> L[Lexical]
228
- Q --> SE[Semantic]
229
- Q --> G[Graph]
230
- L --> RRF[RRF fuse]
231
- SE --> RRF
232
- G --> RRF
233
- RRF --> RR[rerank: phase · recency · task]
234
- RR --> W[weight by strength]
235
- W --> P[Prompt context]
236
- ```
237
-
238
- Faded, private, or unsafe memories are held back from the prompt. Lookups never
239
- write reinforce/archive/supersede are explicit, never search side effects.
240
-
241
- ## Storage Strategy
242
-
243
- Builder uses one operational storage strategy: local on-disk runtime state plus
244
- markdown-native knowledge artifacts.
245
-
246
- ```mermaid
247
- flowchart LR
248
- W[Workspace files] --> AD[Source adapters]
249
- S[Skills] --> AD
250
- M[Conversation memories] --> AD
251
- N[Markdown notes] --> AD
252
- AD --> IDX[Local lexical + semantic + graph index]
253
- IDX --> RR[Contextual reranker]
254
- RR --> PC[Prompt context]
255
- PC --> RUN[Agent run]
256
- RUN --> LS[.builder local state]
257
- RUN --> ART[Local artifacts and reports]
258
- ```
259
-
260
- Key invariants:
261
-
262
- - Runtime state is local-first and does not require an external data service.
263
- - The markdown knowledge graph is derived from local facts: notes, skills,
264
- conversation memory, wiki-links, backlinks, and run artifacts.
265
- - Graph data is a derived retrieval view, not a second source of truth.
266
- - Workflow runs, evidence, state cards, memories, and large-output artifacts
267
- persist through local repositories.
268
- - Domain methods such as development, CTF practice, pentesting methodology,
269
- audits, and release work live in skills and task instructions; they do not
270
- change the core runtime identity.
271
-
272
- ## Crate Map
273
-
274
- | Layer | Crates | Responsibility |
275
- | --- | --- | --- |
276
- | Interaction | `builder_main`, `builder_ratatui`, `builder_select`, `builder_markdown_stream` | CLI, TUI, prompt flow, rendering, selector fallback |
277
- | Facade | `builder_api` | Thin application boundary used by entry points |
278
- | Coordination | `builder_app` | classification, routing, execution strategy, orchestration, completion gates |
279
- | Contracts | `builder_domain` | typed IDs, tools, workflow records, engagement metadata, policies |
280
- | Capabilities | `builder_services` | tool services, auth, provider support, file/search/shell/fetch operations |
281
- | Persistence | `builder_repo`, `builder_provider_repo` | local repositories, provider catalog, chat repository |
282
- | Knowledge | `builder_knowledge`, `builder_workspace_index`, `builder_embed` | markdown note adapters, graph parsing, hybrid retrieval, local semantic scoring |
283
- | Infrastructure | `builder_config`, `builder_infra`, `builder_fs`, `builder_walker` | config, environment, filesystem, process/runtime helpers |
284
- | 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 |
285
-
286
- ## Tool Surface
287
-
288
- The runtime tool catalog is file, shell, network-fetch, planning, skill, todo,
289
- and delegation oriented. Core tools:
290
-
291
- - `read`, `write`, `patch`, `multi_patch`, `undo`, `remove`
292
- - `fs_search`, `sem_search`
293
- - `shell`, `fetch`
294
- - `plan`, `skill`, `todo_read`, `todo_write`
295
- - `task` and dynamically registered agent tools
296
-
297
- The full catalog (`builder_domain/src/tools/catalog.rs`) also includes web
298
- search, memory, verification primitives (flag check, best-of-N verify, finding),
299
- session/process control, and compaction tools. Direct raw storage-query tooling
300
- is not part of the active runtime surface.
301
-
302
- ## Verification And Completion
303
-
304
- Completion is runtime-owned:
305
-
306
- ```text
307
- candidate answer
308
- -> evidence check
309
- -> verification record
310
- -> acceptance-gate check
311
- -> adjudication
312
- -> complete / replan / blocked
313
- ```
314
-
315
- The key rule is that a model response is not considered done until the runtime
316
- has enough recorded evidence to close the task.
317
-
318
- ## Distribution single source, two surfaces
319
-
320
- Pentesting and Builder share the **same Rust runtime binary**. The `pentesting`
321
- npm package is a thin distribution facade:
322
-
323
- ```text
324
- npm install -g pentesting
325
-
326
-
327
- pentesting CLI (Node.js shim)
328
- │ resolves or downloads the matching Builder release asset
329
-
330
- Builder binary (Rust) ← single runtime engine
331
- │ PENTESTING_PRODUCT_NAME=pentesting
332
-
333
- Interactive TUI with "pentesting" banner
334
- ```
335
-
336
- - The npm package installs a launcher, **not** a second agent runtime.
337
- - It resolves or downloads the correct release asset from
338
- `agnusdei1207/pentesting-public`.
339
- - It forwards arguments directly into the Rust binary — no command translation
340
- or compatibility shims.
341
- - If a change would add orchestration, memory, or prompt logic into the npm
342
- layer, that change belongs upstream in the Rust runtime.
343
-
344
- ## Supported Runtime Targets
345
-
346
- The npm launcher currently resolves a managed native release asset for Linux
347
- x64. Other operating systems, including Apple Silicon Macs, Linux arm64,
348
- Windows, and Android, can run the multi-architecture Docker image or use
349
- `PENTESTING_BIN` to point at a locally built compatible binary.
350
-
351
- | OS | CPU | Release asset |
352
- | --- | --- | --- |
353
- | Linux | x64 | `pentesting-x86_64-unknown-linux-musl` |
354
-
355
- `/update` (and the npm postinstall) resolves the matching asset for the current
356
- supported OS/CPU target from `agnusdei1207/pentesting-public`.
357
-
358
- ## Configuration
359
-
360
- Pentesting reads a user-global config from `~/.pentesting/.pentesting.toml`,
361
- overridden by project-local `.pentesting.toml` files discovered by walking up
362
- from the working directory. Local storage is the default; normal setup only
363
- needs the public model endpoint environment.
364
-
365
- The same shape is represented in `builder.schema.json`, `.pentesting.toml`, and
366
- the interactive `/config` UI. Set `PENTESTING_CONFIG` to override the global
367
- config directory.
368
-
369
- | Variable | Description |
370
- | --- | --- |
371
- | `OPENAI_API_KEY` | API key or gateway token for OpenAI-compatible providers. |
372
- | `OPENAI_BASE_URL` | OpenAI-compatible base URL, for example `https://api.openai.com/v1` or a self-hosted gateway. |
373
- | `OPENAI_MODEL` | Default model id. |
374
- | `OPENAI_MAX_TOKENS` | Optional output-token override; accepts values like `4096`, `32k`, or `1M`. |
375
- | `PENTESTING_BIN` | Use an already-installed Builder binary instead of the managed download. |
376
- | `PENTESTING_PRODUCT_NAME` | Runtime banner label. The `pentesting` launcher sets this to `pentesting` automatically. |
377
- | `PENTESTING_REPO` | Override the public release repo used for binary downloads. Defaults to `agnusdei1207/pentesting-public`. |
378
- | `PENTESTING_SKIP_DOWNLOAD` | Skip the postinstall binary download. Useful in CI or when `PENTESTING_BIN` will be provided later. |
379
- | `PENTESTING_CONFIG` | Override the global config directory. |
380
-
381
- ### Backward compatibility `builder` `pentesting`
382
-
383
- The runtime engine is still `builder` under the hood, so legacy names keep
384
- working. Use whichever you like; the `PENTESTING_*` form wins when both are set.
385
-
386
- | Surface | Canonical | Legacy (still accepted) |
387
- | :--- | :--- | :--- |
388
- | Env vars | `PENTESTING_*` | `BUILDER_*` |
389
- | Config-dir override | `PENTESTING_CONFIG` | `BUILDER_CONFIG` |
390
- | Global config file | `~/.pentesting/.pentesting.toml` | `~/.builder/.builder.toml`, `~/builder/.builder.toml` |
391
- | Project config file | `.pentesting.toml` | `.builder.toml` |
392
-
393
- ## Interactive Commands
394
-
395
- Inside an interactive session, these commands inspect and drive runtime state
396
- (`/help` lists the full set):
397
-
398
- ```text
399
- /status Show the current run phase, active tasks, gates, hooks, and budget signals
400
- /workflow Show the current focus and recent workflow steps for the active conversation
401
- /workflow report
402
- Export the active run, engagement metadata, evidence, and large outputs to Markdown
403
- /context Show recent context-budget snapshots for the current conversation
404
- /memory Show stored conversation memories for the current conversation
405
- /tools List the currently available tools and schemas
406
- /agent Switch the active agent
407
- /conversation Browse conversations for the active workspace
408
- /goal <task> Set the active goal
409
- /auto Toggle autonomous mode for the current goal
410
- /update Download and apply the latest public release asset for supported native targets
411
- /help Show all commands
412
- /exit Quit
413
- ```
414
-
415
- ## Security Domain Skills
416
-
417
- The `ctf-competition` and `pentesting-methodology` skills map authorized
418
- assessments to standard frameworks:
419
-
420
- - **PTES** (Penetration Testing Execution Standard)
421
- - **MITRE ATT&CK** tactics and techniques
422
- - **OWASP** Top 10 and Testing Guide
423
- - **CWE/CAPEC** weakness and attack pattern catalogs
424
- - **NIST CSF** and **CIS Controls**
425
-
426
- ### Shell listener for authorized labs
427
-
428
- ```bash
429
- pentesting shell-listener --bind 127.0.0.1 --port 4444
430
- ```
431
-
432
- Manages multiple accepted TCP sessions with per-session routing, buffered
433
- output, raw byte logging, full-duplex transcripts, command history, attach /
434
- detach events, replay, and evidence manifests. `pty-upgrade` sends the helper
435
- only; `upgrade` runs the helper plus a probe and records `pty_state` as verified
436
- or failed. The upgrade helper is drawn from a named technique catalog
437
- (`python3`, `python`, `python2`, `script`, `expect`) selectable per request —
438
- there is no default, so the request is rejected unless the caller picks a
439
- technique or supplies a full custom command, forcing the agent to recon the
440
- target and match what it actually has instead of assuming one interpreter; a
441
- missing tool is recorded as `pty_state=failed` with reason `<technique> helper
442
- unavailable`. Raw logs and transcripts are capped per session and closed sessions
443
- are archived automatically so a noisy peer cannot grow memory or disk without
444
- bound. Secret redaction is applied before new raw/transcript/display records are
445
- written; it is not retroactive for output that arrived before the secret value
446
- was registered. Bound to loopback by default; `--allow-remote` is an explicit
447
- opt-in gate.
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.
57
+ - **Prompt Ownership** Prompt mode owns Enter submission. Buffered replay may
58
+ preserve typed-ahead input, but live terminal control responses, redraws, and
59
+ resize noise are not allowed to turn a normal Enter into a pasted newline.
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. Installed users edit the relevant engagement, flag,
137
+ and frontier fields through `/config`.
138
+
139
+ The shipped exploration tool does not replace the core execution strategy.
140
+ It provides a bounded `EvidenceKind::Lead` ledger and explicit dispatch. Stable
141
+ generated identity is separate from semantic deduplication. Dead probes suppress
142
+ an execution branch without rejecting its knowledge hypothesis, and fresh
143
+ evidence reopens scheduling. There is no passive `/frontier` command, detached
144
+ task registry, or second scheduler. `orch_spec::exploration_e2e` pins the off
145
+ path and the explicit breadth/depth/pivot/reseed/merge behavior.
146
+
147
+ Reliability guards sit below the profile layer. Provider protocol capabilities
148
+ default native tool support for OpenAI/Anthropic-compatible responses on
149
+ registry misses, unparsed tool-shaped markup becomes retryable instead of a
150
+ false completion, raw control markup is scrubbed from the stream, and the
151
+ markdown renderer flushes long no-newline prose at soft boundaries while still
152
+ bounding very large buffers.
153
+
154
+ ```mermaid
155
+ flowchart LR
156
+ R[Request] --> GEN["Resolve<br/>task-shaped defaults"]
157
+ GEN --> REC["Optional<br/>named profile / pack"]
158
+ REC --> USE["Bound<br/>tool scope and budget"]
159
+ ```
160
+
161
+ Request to closure:
162
+
163
+ ```mermaid
164
+ flowchart TD
165
+ U[User request] --> A[Agent turn]
166
+ A --> M[Model output]
167
+ M --> T{Registered action?}
168
+ T -- no --> X[Typed turn exit]
169
+ T -- yes --> G[Common tool gateway]
170
+ G --> O[Observation]
171
+ O --> A
172
+ X --> V{Verified artifact?}
173
+ V -- no --> TC[TurnCompleted]
174
+ V -- yes --> MC[TaskComplete + provenance]
175
+ ```
176
+
177
+ ## Agent Team
178
+
179
+ The core agent team is domain-neutral. Each agent ships as a markdown persona
180
+ definition under `crates/builder_repo/src/agents/`.
181
+
182
+ Subagents are explicit and bounded. A `task` call selects one agent; its tasks
183
+ run concurrently up to four per call and delegation stops at depth two.
184
+ Separate top-level tool calls are sequenced. Built-ins include `crypto`, `rev`,
185
+ and `pwn`.
186
+
187
+ `explore dispatch` is a separate path. It runs selected leads as `builder`
188
+ clones with category overlays, defaults to breadth one, is hard-capped at four,
189
+ and waits for the batch. It does not auto-route leads to specialist personas.
190
+ Every child uses the same tool/policy gateway, budget, lineage, and evidence
191
+ merge contracts.
192
+
193
+ | Agent | Default role | Runtime profile |
194
+ | --- | --- | --- |
195
+ | `builder` | Hands-on implementation, refactoring, local file changes, tests | Implement + broad local write |
196
+ | `planner` | Implementation plans and risk breakdowns | Plan + read-only |
197
+ | `researcher` | Read-only codebase and reference research | Investigate + read-only |
198
+ | `coordinator` | Splits broad work into owned packets and consolidates results | Coordinate + broad local write |
199
+ | `investigator` | Evidence gathering across code, logs, commands, APIs, and behavior | Investigate + shell diagnostics |
200
+ | `operator` | Builds, tests, packaging, service startup, and runtime workflows | Implement + broad local write |
201
+ | `reviewer` | Findings-first technical review | Review + strict read-only |
202
+ | `verifier` | Reproduction, build/test proof, and completion claim checks | Verify + strict read-only |
203
+ | `report-writer` | Reports, handoffs, release notes, and reproducibility records | Implement + bounded write |
204
+
205
+ > Distinct tool-scope is runtime-enforced for `builder`, `planner`, and
206
+ > `researcher`; the remaining personas share a task-shaped generic profile
207
+ > (read-only when the task shape is review/verify, broad local write otherwise)
208
+ > and differ by their prompt instructions.
209
+
210
+ ## Named Autonomy Profiles
211
+
212
+ Optionally pin the top-level profile (`autonomy_profile = "ctf-competition"`);
213
+ leave unset for the deterministic general default. CTF engagement config may
214
+ select CTF prompt context when no explicit profile is set, but it never changes
215
+ tool reachability. Delegated subagent contracts stay intact. Defined in
216
+ `crates/builder_domain/src/autonomy_profile.rs`.
217
+
218
+ | Profile | Purpose |
219
+ | --- | --- |
220
+ | `general-agent` | Broad autonomous local orchestration for mixed tasks |
221
+ | `local-builder` | Hands-on implementation with fresh evidence retrieval |
222
+ | `ctf-competition` | Competition/lab workflow backed by `ctf-competition` and `pentesting-methodology` skills |
223
+ | `enterprise-review` | Strict, review-heavy profile with read-only dynamic scope |
224
+
225
+ ## Engagement Metadata
226
+
227
+ Runs can attach typed engagement context — scope, phase, tags, flag format,
228
+ flag-evidence requirement, and standard refs (PTES, MITRE ATT&CK, OWASP,
229
+ CWE/CAPEC, NIST CSF, CIS Controls) — to workflow metadata. `/workflow report`
230
+ exports it as a Markdown handoff.
231
+
232
+ ## Memory & Knowledge
233
+
234
+ Local-first and split across two complementary layers, no vector DB, no cloud:
235
+
236
+ - **Conversation memories** — facts/preferences/gotchas distilled from sessions,
237
+ persisted in local runtime state and recalled into each prompt by hybrid
238
+ retrieval. These carry a *strength* that fades like human memory, so the store
239
+ stays sharp instead of rotting.
240
+ - **Knowledge vault** — an optional Obsidian-style set of markdown notes under
241
+ `.pentesting/knowledge` (wiki-links, backlinks, tags). The agent reads it on every
242
+ turn and grows it with the `write` tool; it is never auto-deleted.
243
+
244
+ Both layers feed the same strength-weighted hybrid retrieval.
245
+
246
+ **Storage** — Ebbinghaus lifecycle (decay · reinforce · floor, never deleted):
247
+
248
+ ```mermaid
249
+ flowchart TD
250
+ N[New memory] --> S["strength = quality × recall × e^-λ·age"]
251
+ S --> U{recalled?}
252
+ U -- yes --> RE[reinforce · reset age]
253
+ U -- no --> D[decay over time]
254
+ RE --> S
255
+ D --> F{below floor?}
256
+ F -- no --> S
257
+ F -- yes --> AR[de-reference: archive / tombstone]
258
+ AR -. recoverable on disk .-> N
259
+ ```
260
+
261
+ Kinds fade at different speeds (procedural outlives episodic); bi-temporal
262
+ `event_time` vs `ingestion_time` lets newer facts supersede stale ones.
263
+
264
+ **Retrieval** — hybrid fuse, strength-weighted, read-only:
265
+
266
+ ```mermaid
267
+ flowchart LR
268
+ Q[Query] --> L[Lexical]
269
+ Q --> SE[Semantic]
270
+ Q --> G[Graph]
271
+ L --> RRF[RRF fuse]
272
+ SE --> RRF
273
+ G --> RRF
274
+ RRF --> RR[rerank: phase · recency · task]
275
+ RR --> W[weight by strength]
276
+ W --> P[Prompt context]
277
+ ```
278
+
279
+ Faded, private, or unsafe memories are held back from the prompt. Lookups never
280
+ write reinforce/archive/supersede are explicit, never search side effects.
281
+
282
+ ## Storage Strategy
283
+
284
+ Builder uses one operational storage strategy: local on-disk runtime state plus
285
+ markdown-native knowledge artifacts.
286
+
287
+ ```mermaid
288
+ flowchart LR
289
+ W[Workspace files] --> AD[Source adapters]
290
+ S[Skills] --> AD
291
+ M[Conversation memories] --> AD
292
+ N[Markdown notes] --> AD
293
+ AD --> IDX[Local lexical + semantic + graph index]
294
+ IDX --> RR[Contextual reranker]
295
+ RR --> PC[Prompt context]
296
+ PC --> RUN[Agent run]
297
+ RUN --> LS[.pentesting local state]
298
+ RUN --> ART[Local artifacts and reports]
299
+ ```
300
+
301
+ Key invariants:
302
+
303
+ - Runtime state is local-first and does not require an external data service.
304
+ - The markdown knowledge graph is derived from local facts: notes, skills,
305
+ conversation memory, wiki-links, backlinks, and run artifacts.
306
+ - Graph data is a derived retrieval view, not a second source of truth.
307
+ - Evidence, workflow runs, state cards, and verified artifacts persist through
308
+ local repositories. Removed semantic-verdict, recovery-route, completion
309
+ bundle, replay-archive, and curation projections cannot redirect the active
310
+ model loop because they no longer exist in the runtime model.
311
+ - Domain methods such as development, CTF practice, pentesting methodology,
312
+ audits, and release work live in skills and task instructions; they do not
313
+ change the core runtime identity.
314
+
315
+ ## Crate Map
316
+
317
+ | Layer | Crates | Responsibility |
318
+ | --- | --- | --- |
319
+ | Interaction | `builder_main`, `builder_ratatui`, `builder_select`, `builder_markdown_stream` | CLI, TUI, prompt flow, rendering, selector fallback |
320
+ | Facade | `builder_api` | Thin application boundary used by entry points |
321
+ | Coordination | `builder_app` | turn loop, provider adaptation, common tool gateway, observations, verified outcome |
322
+ | Contracts | `builder_domain` | typed IDs, tools, workflow records, engagement metadata, policies |
323
+ | Capabilities | `builder_services` | tool services, auth, provider support, file/search/shell/fetch operations |
324
+ | Persistence | `builder_repo`, `builder_provider_repo` | local repositories, provider catalog, chat repository |
325
+ | Knowledge | `builder_knowledge`, `builder_workspace_index`, `builder_embed` | markdown note adapters, graph parsing, hybrid retrieval, local semantic scoring |
326
+ | Infrastructure | `builder_config`, `builder_infra`, `builder_fs`, `builder_walker` | config, environment, filesystem, process/runtime helpers |
327
+ | 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 |
328
+
329
+ ## Tool Surface
330
+
331
+ The runtime tool catalog is file, shell, network-fetch, planning, skill, todo,
332
+ and delegation oriented. Core tools:
333
+
334
+ - `read`, `write`, `patch`, `multi_patch`, `undo`, `remove`
335
+ - `fs_search`, `sem_search`
336
+ - `shell`, `fetch`
337
+ - `plan`, `skill`, `todo_read`, `todo_write`
338
+ - `task` and dynamically registered agent tools
339
+
340
+ The full catalog (`builder_domain/src/tools/catalog.rs`) also includes web
341
+ search, memory, verification primitives, session/process control, and
342
+ compaction tools. Security-session primitives, `flag_check`, and `explore` are
343
+ all present on the same surface. Engagement metadata supplies context;
344
+ permission and resource budgets constrain execution. Direct raw storage-query
345
+ tooling is not part of the active runtime surface.
346
+
347
+ ## Verification And Completion
348
+
349
+ Turn closure and mission closure are separate:
350
+
351
+ ```text
352
+ provider terminal
353
+ -> TurnExit
354
+ -> TurnCompleted
355
+
356
+ candidate outcome + trusted artifact
357
+ -> bind objective + target + verifier + artifact + freshness
358
+ -> MissionState::Verified
359
+ -> TaskComplete
360
+ ```
361
+
362
+ The key rule is that a model response may finish a turn but cannot prove the
363
+ mission. The former completion-adjudicator, semantic self-review, consensus
364
+ panel, recovery synthesis, and hot-path replay export have been removed. A
365
+ trusted verifier with explicit provenance is the only mission-promotion path;
366
+ `flag_check` is the direct CTF fast path.
367
+
368
+ ## Diagnostic UI boundary
369
+
370
+ The default TUI renders the response stream and deterministic input queue. It
371
+ does not maintain a second workflow engine. `/status` consumes one immutable
372
+ `RunStatusProjection`; `/workflow report` is the explicit offline export. The
373
+ former bare `/workflow` alias has been removed. The live status row deliberately
374
+ shows only actionable progress/wait state; frontier JSON is not parsed into
375
+ hidden chrome state, and full run/tool detail remains in explicit output and
376
+ `/status`.
377
+
378
+ ## Distribution single source, two surfaces
379
+
380
+ Pentesting and Builder share the **same Rust runtime binary**. The `pentesting`
381
+ npm package is a thin distribution facade:
382
+
383
+ ```text
384
+ npm install -g pentesting
385
+
386
+
387
+ pentesting CLI (Node.js shim)
388
+ │ resolves or downloads the matching Builder release asset
389
+
390
+ Builder binary (Rust) ← single runtime engine
391
+ │ PENTESTING_PRODUCT_NAME=pentesting
392
+
393
+ Interactive TUI with "pentesting" banner
394
+ ```
395
+
396
+ - The npm package installs a launcher, **not** a second agent runtime.
397
+ - It resolves or downloads the correct release asset from
398
+ `agnusdei1207/pentesting-public`.
399
+ - It forwards arguments directly into the Rust binary no command translation
400
+ or compatibility shims.
401
+ - If a change would add orchestration, memory, or prompt logic into the npm
402
+ layer, that change belongs upstream in the Rust runtime.
403
+
404
+ ## Supported Runtime Targets
405
+
406
+ The npm launcher currently resolves a managed native release asset for Linux
407
+ x64. Docker is the recommended runtime on Windows and macOS. Published Docker
408
+ images support `linux/amd64` only; Apple Silicon Macs use Docker Desktop's amd64
409
+ emulation. Native ARM64 images and binaries are not supported. Advanced users
410
+ may set `PENTESTING_BIN` to a locally supplied compatible binary.
411
+
412
+ | OS | CPU | Release asset |
413
+ | --- | --- | --- |
414
+ | Linux | x64 | `pentesting-x86_64-unknown-linux-musl` |
415
+
416
+ `/update` (and the npm postinstall) resolves the matching asset for the current
417
+ supported OS/CPU target from `agnusdei1207/pentesting-public`.
418
+
419
+ ## Build containment boundary
420
+
421
+ Compilation is outside the application runtime boundary and is always executed
422
+ through resource-capped Docker wrappers. Host Cargo is not an emergency
423
+ fallback. `dbuild.sh` owns individual Cargo commands, `dverify.sh` owns
424
+ sequential gate profiles, and `dbuild-image.sh` owns BuildKit. Each path shares
425
+ storage admission, effective-limit inspection, a machine-wide lock, watchdogs,
426
+ and structured failure reports. Automated CI/CD is disabled; maintainers invoke
427
+ these wrappers explicitly. The
428
+ normative contract is [Docker-only build safety](https://github.com/agnusdei1207/pentesting/blob/main/docs/BUILD_SAFETY.md).
429
+
430
+ The measured next-stage simplification and deletion plan is indexed at
431
+ [Minimal Core plan](https://github.com/agnusdei1207/pentesting/blob/main/docs/plans/2026/07/10/minimal-core/README.md).
432
+ The concrete PTY actor, unified security-tool surface, turn-trajectory, and dead-path reduction is
433
+ recorded in [the 2026-07-10 implementation report](docs/plans/2026/07/10/IMPLEMENTATION_LightweightCoreRefactor_2026-07-10.md).
434
+
435
+ ## Configuration
436
+
437
+ Pentesting reads a user-global config from `~/.pentesting/.pentesting.toml`,
438
+ overridden by project-local `.pentesting.toml` files discovered by walking up
439
+ from the working directory. Local storage is the default; normal setup only
440
+ needs the public model endpoint environment.
441
+
442
+ The full file shape is represented in `builder.schema.json`; common runtime and
443
+ CTF fields are editable through `/config`. Set `PENTESTING_CONFIG` to override
444
+ the global config directory.
445
+
446
+ | Variable | Description |
447
+ | --- | --- |
448
+ | `OPENAI_API_KEY` | API key or gateway token for OpenAI-compatible providers. |
449
+ | `OPENAI_BASE_URL` | OpenAI-compatible base URL, for example `https://api.openai.com/v1` or a self-hosted gateway. |
450
+ | `OPENAI_MODEL` | Default model id. |
451
+ | `OPENAI_MAX_TOKENS` | Optional output-token override; accepts values like `4096`, `32k`, or `1M`. |
452
+ | `PENTESTING_BIN` | Use an already-installed Builder binary instead of the managed download. |
453
+ | `PENTESTING_PRODUCT_NAME` | Runtime banner label. The `pentesting` launcher sets this to `pentesting` automatically. |
454
+ | `PENTESTING_REPO` | Override the public release repo used for binary downloads. Defaults to `agnusdei1207/pentesting-public`. |
455
+ | `PENTESTING_SKIP_DOWNLOAD` | Skip the postinstall binary download. Useful in CI or when `PENTESTING_BIN` will be provided later. |
456
+ | `PENTESTING_CONFIG` | Override the global config directory. |
457
+
458
+ ### Canonical configuration contract
459
+
460
+ The next-generation runtime accepts one product namespace. Configuration uses
461
+ `PENTESTING_*`, `~/.pentesting/.pentesting.toml`, and project-local
462
+ `.pentesting.toml`. `BUILDER_*`, `.builder.toml`, `.builder/`, JSON config
463
+ fallbacks, and runtime alias translation have been removed. Existing users must
464
+ move data explicitly before upgrading; the runtime does not carry a permanent
465
+ old/new branch.
466
+
467
+ ## Interactive Commands
468
+
469
+ Inside an interactive session, these commands inspect and drive runtime state
470
+ (`/help` lists the full set):
471
+
472
+ ```text
473
+ /status Show the current run phase, active tasks, hooks, and budget signals
474
+ /workflow report
475
+ Export the active run, engagement metadata, evidence, and large outputs to Markdown
476
+ /context Show recent context-budget snapshots for the current conversation
477
+ /memory Show stored conversation memories for the current conversation
478
+ /tools List the currently available tools and schemas
479
+ /agent Switch the active agent
480
+ /conversation Browse conversations for the active workspace
481
+ /goal <task> Set the active goal without enabling autonomous mode
482
+ /auto Toggle autonomous mode for the current goal (default: off; Esc stops it)
483
+ /update Download and apply the latest public release asset for supported native targets
484
+ /help Show all commands
485
+ /exit Quit
486
+ ```
487
+
488
+ ## Security Domain Skills
489
+
490
+ The `ctf-competition` and `pentesting-methodology` skills map authorized
491
+ assessments to standard frameworks:
492
+
493
+ - **PTES** (Penetration Testing Execution Standard)
494
+ - **MITRE ATT&CK** tactics and techniques
495
+ - **OWASP** Top 10 and Testing Guide
496
+ - **CWE/CAPEC** weakness and attack pattern catalogs
497
+ - **NIST CSF** and **CIS Controls**
498
+
499
+ ### Shell listener for authorized labs
500
+
501
+ ```bash
502
+ pentesting shell-listener --bind 127.0.0.1 --port 4444
503
+ ```
504
+
505
+ Manages multiple accepted TCP sessions with per-session routing, buffered
506
+ output, raw byte logging, full-duplex transcripts, command history, attach /
507
+ detach events, replay, and evidence manifests. `pty-upgrade` sends one concrete
508
+ helper only; `upgrade` runs a helper plus a probe and records `pty_state` as
509
+ verified or failed. Explicit `technique=auto` adds a bounded listener-side state
510
+ machine: framed capability recon, allowlisted `bash`/`sh` selection, ordered
511
+ helper attempts (`python3`, `python`, `python2`, `script`, `expect`), generic
512
+ prompt observation, and phase-local probe verification. Only unavailable,
513
+ early-returned, or completed-but-unverified attempts advance to the next
514
+ candidate; timeout, disconnect, or writer failure stops without blind input.
515
+ The entire operation keeps one command id, deadline, session lease, ledger, and
516
+ final response. There is still no silent default: omission is rejected, manual
517
+ techniques keep their single-attempt behavior, and custom text remains the
518
+ escape hatch for unusual targets. Raw logs and transcripts are capped per session and closed sessions
519
+ are archived automatically so a noisy peer cannot grow memory or disk without
520
+ bound. Secret redaction is applied before new raw/transcript/display records are
521
+ written; it is not retroactive for output that arrived before the secret value
522
+ was registered. Bound to loopback by default; `--allow-remote` is an explicit
523
+ opt-in gate.