pentesting 0.101.8 → 0.101.9

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 CHANGED
@@ -54,7 +54,7 @@ Provider variables are optional — the TUI launches without them and lets you l
54
54
  | Verified agent loop | Streams actions and observations; a model Stop ends only the turn, evidence-backed verification closes the mission, and the full trajectory is persisted |
55
55
  | Unified tool boundary | Built-in, delegated, and MCP calls share schema validation, provenance, permissions, policy, and resource limits |
56
56
  | Context economy | Automatic micro-pruning and model-triggered summaries preserve useful context for low-cost models |
57
- | Deterministic steering | Esc stops the current turn and auto loop, while submitted input resumes in FIFO order at safe turn boundaries |
57
+ | Deterministic steering | Active-turn submissions are retained for the next safe transcript boundary; Esc stops the current turn and auto loop while the visible inputs resume in FIFO order |
58
58
  | Reverse-shell & PTY lifecycle | One control plane manages authorized callbacks and local PTY/pipe sessions, from tagging, probing, and verified upgrades to transcripts, evidence, FD accounting, and deterministic reclamation |
59
59
  | Bounded battlefield | A persistent Lead ledger produces a compact on-demand attention brief and read-only `/status` view; dispatch stays explicit and is capped at four branches |
60
60
  | Adversarial pathfinding | A localized AlphaGo-inspired minimax technique models an opponent's best defensive move and improves the ability to find viable bypass paths |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.101.8",
4
- "builderReleaseTag": "v0.101.8",
3
+ "version": "0.101.9",
4
+ "builderReleaseTag": "v0.101.9",
5
5
  "description": "Penetration testing AI agent powered by Rust, with audited reverse-shell capture, verified PTY upgrades, and evidence-first orchestration.",
6
6
  "license": "MIT",
7
7
  "author": "agnusdei1207",
@@ -14,7 +14,6 @@
14
14
  "lib",
15
15
  "scripts/postinstall.mjs",
16
16
  "README.md",
17
- "ARCHITECTURE.md",
18
17
  "pentesting-logo.svg"
19
18
  ],
20
19
  "engines": {
package/ARCHITECTURE.md DELETED
@@ -1,646 +0,0 @@
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. For a diagram-level tour of the
6
- main runtime flows, see [Main Flows](docs/architecture/MAIN_FLOWS.md). Both are
7
- internal-only and are never mirrored to the public repo.
8
-
9
- > **Engine vs product.** The orchestration engine is **`builder`** — a
10
- > general-purpose, local-first Rust agent runtime. **`pentesting`** is the
11
- > published, security-focused distribution of that same engine: the npm package
12
- > and the command you run. They share one binary. The model owns task reasoning;
13
- > the Rust runtime owns protocol normalization, authorization, bounded execution,
14
- > observations, and verified outcome provenance.
15
-
16
- ## 1. Architecture at a glance
17
-
18
- ```text
19
- user input
20
- → deterministic turn queue
21
- → model/provider adapter
22
- → one tool gateway
23
- → authorized, bounded execution
24
- → append observation to the turn
25
- → repeat until TurnExit
26
- → emit TurnCompleted
27
- → emit TaskComplete only for a verified MissionState
28
- ```
29
-
30
- The core is deliberately narrower than the complete product. Its append-only
31
- `TurnEvent` trajectory contains model terminals, actions, observations, and
32
- verification provenance. The complete trajectory is stored in the terminal
33
- `RunOutcome`; the request-time `TurnSnapshot` is its bounded O(1) projection.
34
- Memory, MCP,
35
- delegation, CTF exploration, and security sessions use the same tool boundary.
36
- Engagement context changes instructions, not tool reachability; resource caps
37
- bound expensive operations.
38
-
39
- ## 2. Design pillars
40
-
41
- - **Model-Driven Work** — The model chooses plans, probes, commands, and ordinary
42
- recovery. The runtime does not duplicate that reasoning with hot-path LLM judges.
43
- - **Hard Boundaries, Not Hard Opinions** — Schema, scope, permission, secrets,
44
- cancellation, time, output, memory, and process limits are deterministic.
45
- - **Typed Turn Lifecycle** — Provider terminal state, `TurnExit`, and
46
- `MissionState` are separate. Stop is never proof of success.
47
- - **One Tool Entry Boundary** — Built-in, delegated, and MCP tools share
48
- allowlist, provenance, registered-contract, and schema validation. Hooks are
49
- orchestrator-owned; permission checks apply only when a tool produces a
50
- policy operation. Ordinary/MCP tools use configured timeouts, while
51
- delegation uses its own runtime budget.
52
- - **Append-Oriented Observation** — Trajectory and evidence are local-first;
53
- prior-run information is linked by reference rather than copied.
54
- - **Deterministic Queuing** — FIFO revisions support amend-next and explicit
55
- replace without auxiliary LLM prioritization.
56
- - **One Security Surface** — Session, process, finding, flag verification, and
57
- frontier operations are ordinary tools. Engagement context, permission,
58
- resource budget, and proof remain separate responsibilities.
59
- - **Prompt Ownership** — Prompt mode owns Enter submission. Buffered replay may
60
- preserve typed-ahead input, but live terminal control responses, redraws, and
61
- resize noise are not allowed to turn a normal Enter into a pasted newline.
62
- Modal return restores the transcript scroll region and its pre-modal saved
63
- cursor before the fixed bottom UI is redrawn.
64
- - **Lab Session Multiplexing** — `shell-listener` runs multiple authorized TCP,
65
- local PTY, and local pipe sessions. A single actor exclusively owns each
66
- session's descriptors, command queue, transcript, raw log, and child
67
- lifecycle; the registry keeps only a bounded sender and projection.
68
- - **Ebbinghaus-Inspired Memory** — Memories carry a *strength* that fades like
69
- human memory and reinforces on recall. Faded notes are de-referenced, never
70
- destroyed.
71
- - **Git-Backed Rewind** — Working-tree checkpoint/restore keeps autonomous edits
72
- reversible.
73
-
74
- ## 3. Runtime flow, one level deeper
75
-
76
- ```mermaid
77
- flowchart TD
78
- U[User request] --> CLI[builder_main CLI / TUI]
79
- CLI --> API[builder_api facade]
80
- API --> APP[builder_app coordination]
81
- APP --> TURN[Turn kernel]
82
- TURN --> MODEL[Provider adapter]
83
- MODEL --> GW[Tool entry boundary]
84
- GW --> POLICY[Schema + applicable policy/resource boundary]
85
- POLICY --> EXEC[Tool / environment execution]
86
- EXEC --> OBS[Observation + artifact refs]
87
- OBS --> TURN
88
- TURN --> EXIT[Typed TurnExit]
89
- EXIT --> VERIFY[Outcome verifier]
90
- VERIFY --> OUT[TurnCompleted / verified TaskComplete]
91
- ```
92
-
93
- Plain view:
94
-
95
- ```text
96
- user input
97
- -> CLI / interactive prompt loop
98
- -> terminal-session prompt ownership + buffered replay boundary
99
- -> BuilderAPI facade
100
- -> BuilderApp turn kernel and provider adapter
101
- -> registered tool contract and common entry boundary
102
- -> policy-gated, resource-bounded execution
103
- -> observation and artifact references
104
- -> typed turn exit and optional verified mission outcome
105
- ```
106
-
107
- Builder is a domain-neutral runtime with a security-focused distribution.
108
- Development, pentesting, CTF, audit, and release behavior layers in through
109
- context, tools, and skills rather than new core strategy kinds.
110
-
111
- ### Runtime persistence ports
112
-
113
- Hot-path consumers depend on ten cohesive persistence ports:
114
-
115
- ```text
116
- run/objective/evidence/task/execution/outcome
117
- audit/observation/lineage/conversation-memory
118
- |
119
- local persistence composition root
120
- ```
121
-
122
- Each producer/consumer depends on the smallest relevant port. The methodless
123
- `ControlPlaneRepository` marker composes those ports only at construction and
124
- dynamic storage boundaries. Implementations and test fakes implement the
125
- physical ports directly; there are no blanket forwarding adapters, fallback
126
- methods, alternate schemas, or second runtime state.
127
-
128
- ## 4. Engagement context and bounded CTF exploration
129
-
130
- There is no model-backed intent classifier or weak/standard model mode in the
131
- request hot path. Explicit event metadata is routed deterministically; absent
132
- metadata receives one general strategy. Named profiles may add context, but
133
- coarse labels do not authorize or reject tool calls.
134
-
135
- CTF engagement metadata may select `ctf-competition` prompt context, and
136
- `flag_check` remains a verification tool and evidence source rather than a
137
- default completion gate. `explore` is always available; `[exploration]` only
138
- sets node and fan-out caps. Installed users edit the relevant engagement, flag,
139
- and frontier fields through `/config`.
140
-
141
- The shipped exploration tool does not replace the core execution strategy.
142
- It provides a bounded `EvidenceKind::Lead` ledger and explicit dispatch. Stable
143
- generated identity is separate from semantic deduplication. Dead probes suppress
144
- an execution branch without rejecting its knowledge hypothesis, and fresh
145
- evidence reopens scheduling. An explicit `explore op=frontier` call reads one
146
- canonical snapshot and returns a bounded attention brief: one visible focus, at
147
- most two alternatives, at most two alerts, state counts, and an omitted count.
148
- Focus is visibility, not a recommendation, authorization, or execution lock;
149
- priority scores stay internal and the model must name leads in a separate
150
- `dispatch` call. The model-facing payload stays within 4 KiB after JSON and HTML
151
- escaping. On an explicit `/status`, the same pure projection is loaded once and
152
- rendered as Battlefield Lite: at most eight logical rows and 1.5 KiB, containing
153
- only typed counts/enums/numeric metadata and revalidated Lead IDs. It omits Lead
154
- title, detail, parent/sample IDs, evidence references, tool output, and score;
155
- that is a narrow Lead-prose disclosure boundary, not a general secret scanner
156
- for the rest of the diagnostic output. There is no passive mission-control
157
- injection, model-request hot-path repository read, `/frontier` command, detached
158
- task registry, advisor, or second scheduler.
159
- `orch_spec::exploration_e2e` pins the explicit frontier/pivot/dispatch/merge
160
- behavior. A deterministic 256-Lead Phase 4 fixture measured the legacy rendered
161
- frontier at 121,420 bytes and the bounded brief at 1,858 bytes (98.46% smaller),
162
- while the existing completion-provenance corpus remained 9/9. This supports the
163
- bounded visibility decision; it is not a claim of improved live-model solve rate.
164
-
165
- Reliability guards sit below the profile layer. Provider protocol capabilities
166
- default native tool support for OpenAI/Anthropic-compatible responses on
167
- registry misses, unparsed tool-shaped markup becomes retryable instead of a
168
- false completion, raw control markup is scrubbed from the stream, and the
169
- markdown renderer flushes long no-newline prose at soft boundaries while still
170
- bounding very large buffers.
171
-
172
- ```mermaid
173
- flowchart LR
174
- R[Request] --> GEN["Resolve<br/>task-shaped defaults"]
175
- GEN --> REC["Optional<br/>named profile / pack"]
176
- REC --> USE["Bound<br/>tool scope and budget"]
177
- ```
178
-
179
- Request to closure:
180
-
181
- ```mermaid
182
- flowchart TD
183
- U[User request] --> A[Agent turn]
184
- A --> M[Model output]
185
- M --> T{Registered action?}
186
- T -- no --> X[Typed turn exit]
187
- T -- yes --> G[Common tool gateway]
188
- G --> O[Observation]
189
- O --> A
190
- X --> V{Verified artifact?}
191
- V -- no --> TC[TurnCompleted]
192
- V -- yes --> MC[TaskComplete + provenance]
193
- ```
194
-
195
- ## Agent Team
196
-
197
- The core agent team is domain-neutral. Each agent ships as a markdown persona
198
- definition under `crates/builder_repo/src/agents/`.
199
-
200
- Subagents are explicit and bounded. A `task` call selects one agent; its tasks
201
- run concurrently up to four per call and delegation stops at depth two.
202
- Separate top-level tool calls are sequenced. Built-ins include `crypto`, `rev`,
203
- and `pwn`.
204
-
205
- `explore dispatch` is a separate path. It runs selected leads as `builder`
206
- clones with category overlays, defaults to breadth one, is hard-capped at four,
207
- and waits for the batch. It does not auto-route leads to specialist personas.
208
- Every child uses the same tool/policy gateway, budget, lineage, and evidence
209
- merge contracts.
210
-
211
- | Agent | Default role | Runtime profile |
212
- | --- | --- | --- |
213
- | `builder` | Hands-on implementation, refactoring, local file changes, tests | Implement + broad local write |
214
- | `planner` | Implementation plans and risk breakdowns | Plan + read-only |
215
- | `researcher` | Read-only codebase and reference research | Investigate + read-only |
216
- | `coordinator` | Splits broad work into owned packets and consolidates results | Coordinate + broad local write |
217
- | `investigator` | Evidence gathering across code, logs, commands, APIs, and behavior | Investigate + shell diagnostics |
218
- | `operator` | Builds, tests, packaging, service startup, and runtime workflows | Implement + broad local write |
219
- | `reviewer` | Findings-first technical review | Review + strict read-only |
220
- | `verifier` | Reproduction, build/test proof, and completion claim checks | Verify + strict read-only |
221
- | `report-writer` | Reports, handoffs, release notes, and reproducibility records | Implement + bounded write |
222
-
223
- > Distinct tool-scope is runtime-enforced for `builder`, `planner`, and
224
- > `researcher`; the remaining personas share a task-shaped generic profile
225
- > (read-only when the task shape is review/verify, broad local write otherwise)
226
- > and differ by their prompt instructions.
227
-
228
- ## Named Autonomy Profiles
229
-
230
- Optionally pin the top-level profile (`autonomy_profile = "ctf-competition"`);
231
- leave unset for the deterministic general default. CTF engagement config may
232
- select CTF prompt context when no explicit profile is set, but it never changes
233
- tool reachability. Delegated subagent contracts stay intact. Defined in
234
- `crates/builder_domain/src/autonomy_profile.rs`.
235
-
236
- | Profile | Purpose |
237
- | --- | --- |
238
- | `general-agent` | Broad autonomous local orchestration for mixed tasks |
239
- | `local-builder` | Hands-on implementation with fresh evidence retrieval |
240
- | `ctf-competition` | Competition/lab workflow; the profile references `ctf-competition` and `pentesting-methodology`, while built-in `write-report` remains explicitly selectable |
241
- | `enterprise-review` | Strict, review-heavy profile with read-only dynamic scope |
242
-
243
- ## Engagement Metadata
244
-
245
- Runs can attach typed engagement context — scope, phase, tags, flag format,
246
- flag-evidence requirement, and standard refs (PTES, MITRE ATT&CK, OWASP,
247
- CWE/CAPEC, NIST CSF, CIS Controls) — to workflow metadata. `/workflow report`
248
- exports it as a Markdown handoff.
249
-
250
- ## Memory & Knowledge
251
-
252
- Local-first and split across two complementary layers, no vector DB, no cloud:
253
-
254
- - **Conversation memories** — facts/preferences/gotchas distilled from sessions,
255
- persisted in local runtime state and recalled into each prompt by hybrid
256
- retrieval. These carry a *strength* that fades like human memory, so the store
257
- stays sharp instead of rotting.
258
- - **Knowledge vault** — an optional Obsidian-style set of markdown notes under
259
- `.pentesting/knowledge` (wiki-links, backlinks, tags). The agent reads it on every
260
- turn and grows it with the `write` tool; it is never auto-deleted.
261
-
262
- Both layers feed the same strength-weighted hybrid retrieval.
263
-
264
- **Storage** — Ebbinghaus lifecycle (decay · reinforce · floor, never deleted):
265
-
266
- ```mermaid
267
- flowchart TD
268
- N[New memory] --> S["strength = quality × recall × e^-λ·age"]
269
- S --> U{recalled?}
270
- U -- yes --> RE[reinforce ↑ · reset age]
271
- U -- no --> D[decay over time]
272
- RE --> S
273
- D --> F{below floor?}
274
- F -- no --> S
275
- F -- yes --> AR[de-reference: archive / tombstone]
276
- AR -. recoverable on disk .-> N
277
- ```
278
-
279
- Kinds fade at different speeds (procedural outlives episodic); bi-temporal
280
- `event_time` vs `ingestion_time` lets newer facts supersede stale ones.
281
-
282
- **Retrieval** — hybrid fuse, strength-weighted, read-only:
283
-
284
- ```mermaid
285
- flowchart LR
286
- Q[Query] --> L[Lexical]
287
- Q --> SE[Semantic]
288
- Q --> G[Graph]
289
- L --> RRF[RRF fuse]
290
- SE --> RRF
291
- G --> RRF
292
- RRF --> RR[rerank: phase · recency · task]
293
- RR --> W[weight by strength]
294
- W --> P[Prompt context]
295
- ```
296
-
297
- Faded, private, or unsafe memories are held back from the prompt. Lookups never
298
- write — reinforce/archive/supersede are explicit, never search side effects.
299
-
300
- ## Storage Strategy
301
-
302
- Builder uses one operational storage strategy: local on-disk runtime state plus
303
- markdown-native knowledge artifacts.
304
-
305
- ```mermaid
306
- flowchart LR
307
- W[Workspace files] --> AD[Source adapters]
308
- S[Skills] --> AD
309
- M[Conversation memories] --> AD
310
- N[Markdown notes] --> AD
311
- AD --> IDX[Local lexical + semantic + graph index]
312
- IDX --> RR[Contextual reranker]
313
- RR --> PC[Prompt context]
314
- PC --> RUN[Agent run]
315
- RUN --> LS[.pentesting local state]
316
- RUN --> ART[Local artifacts and reports]
317
- ```
318
-
319
- Key invariants:
320
-
321
- - Runtime state is local-first and does not require an external data service.
322
- - The markdown knowledge graph is derived from local facts: notes, skills,
323
- conversation memory, wiki-links, backlinks, and run artifacts.
324
- - Graph data is a derived retrieval view, not a second source of truth.
325
- - Evidence, workflow runs, state cards, and verified artifacts persist through
326
- local repositories. Removed semantic-verdict, recovery-route, completion
327
- bundle, replay-archive, and curation projections cannot redirect the active
328
- model loop because they no longer exist in the runtime model.
329
- - Domain methods such as development, CTF practice, pentesting methodology,
330
- audits, and release work live in skills and task instructions; they do not
331
- change the core runtime identity.
332
-
333
- ## Crate Map
334
-
335
- | Layer | Crates | Responsibility |
336
- | --- | --- | --- |
337
- | Interaction | `builder_main`, `builder_ratatui`, `builder_select`, `builder_markdown_stream` | CLI, TUI, prompt flow, rendering, selector fallback |
338
- | Facade | `builder_api` | Thin application boundary used by entry points |
339
- | Coordination | `builder_app` | turn loop, provider adaptation, common tool gateway, observations, verified outcome |
340
- | Contracts | `builder_domain` | typed IDs, tools, workflow records, engagement metadata, policies |
341
- | Capabilities | `builder_services` | tool services, auth, provider support, file/search/shell/fetch operations |
342
- | Persistence | `builder_repo`, `builder_provider_repo` | local repositories, provider catalog, chat repository |
343
- | Knowledge | `builder_knowledge`, `builder_workspace_index`, `builder_embed` | markdown note adapters, graph parsing, hybrid retrieval, local semantic scoring |
344
- | Infrastructure | `builder_config`, `builder_infra`, `builder_fs`, `builder_walker` | config, environment, filesystem, process/runtime helpers |
345
- | 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 |
346
-
347
- ## Tool Surface
348
-
349
- The runtime tool catalog is file, shell, network-fetch, planning, skill, todo,
350
- and delegation oriented. Core tools:
351
-
352
- - `read`, `write`, `patch`, `multi_patch`, `undo`, `remove`
353
- - `fs_search`, `sem_search`
354
- - `shell`, `fetch`
355
- - `plan`, `skill`, `todo_read`, `todo_write`
356
- - `task` and dynamically registered agent tools
357
-
358
- The full catalog (`builder_domain/src/tools/catalog.rs`) also includes web
359
- search, memory, verification primitives, session/process control, and
360
- compaction tools. Security-session primitives, `flag_check`, and `explore` are
361
- all present on the same surface. Engagement metadata supplies context;
362
- permission and resource budgets constrain execution. Direct raw storage-query
363
- tooling is not part of the active runtime surface.
364
-
365
- ## Verification And Completion
366
-
367
- Turn closure and mission closure are separate:
368
-
369
- ```text
370
- provider terminal
371
- -> TurnExit
372
- -> TurnCompleted
373
-
374
- candidate outcome + trusted artifact
375
- -> bind objective + target + verifier + artifact + freshness
376
- -> MissionState::Verified
377
- -> TaskComplete
378
- ```
379
-
380
- The key rule is that a model response may finish a turn but cannot prove the
381
- mission. The former completion-adjudicator, semantic self-review, consensus
382
- panel, recovery synthesis, and hot-path replay export have been removed. A
383
- trusted verifier with explicit provenance is the only mission-promotion path;
384
- `flag_check` is the direct CTF fast path.
385
-
386
- ## Diagnostic UI boundary
387
-
388
- The default TUI renders the response stream and deterministic input queue. It
389
- does not maintain a second workflow engine. `/status` consumes one immutable
390
- `RunStatusProjection`; `/workflow report` is the explicit offline export. The
391
- former bare `/workflow` alias has been removed. For an active run the projection
392
- adds exactly one optional canonical Lead-ledger read and immediately reduces it
393
- to `Option<AttentionBrief>`; raw nodes never cross the API boundary, an optional
394
- read failure only renders `BATTLEFIELD [UNAVAILABLE]`, and no Lead produces no
395
- battlefield rows. Core status read failures retain their existing error path.
396
- With no recorded run, `/status` still shows goal, manual/auto mode, queue, and
397
- usage without an evidence read. Recorded `TurnExit` and typed `MissionState` are
398
- shown separately so model Stop or run completion cannot appear as verified
399
- mission completion. The live status row deliberately remains limited to
400
- actionable progress/wait state: there is no frontier parsing, background refresh,
401
- write, dispatch shortcut, or hidden chrome state.
402
-
403
- Interactive `/auto` progress is producer-owned rather than inferred from the
404
- latest conversation after the fact. Dispatch marks a self-prompt turn in flight;
405
- successful cleanup captures that turn's final assistant markdown in memory,
406
- records a deterministic completed-turn line in the transcript, and synchronizes
407
- optional `current/target` progress to the footer before queued user input is
408
- replayed. A regular `AUTO_GOAL_PROGRESS` line is observability-only.
409
- `AUTO_GOAL_COMPLETE` retains completion authority and
410
- `AUTO_GOAL_BLOCKED` remains non-terminal. Cancellation, goal/auto reset, and a
411
- manual user turn invalidate pending completion provenance so a later reply
412
- cannot be misattributed to the autonomous turn. Unexpected stream termination
413
- also revokes ownership before queue replay, and explicit stop interrupts disable
414
- auto mode before preserved input is replayed. Interrupt-listener shutdown
415
- linearizes the terminal boundary as stop, reader join, then pending-source
416
- recovery, so an Esc accepted concurrently with `TurnCompleted` wins before
417
- progress or completion can be committed. Tool/delegated-agent markdown and
418
- terminal events have no root completion authority while a nested producer owns
419
- the stream. The auto footer is process-level chrome: turn-local backend resets
420
- preserve it until an explicit UI state transition clears it. The footer receives
421
- a bounded single-line goal projection, while the deterministic progress title
422
- does not repeat the goal every turn, so multiline/control-bearing goals cannot
423
- corrupt fixed chrome or inflate transcript history.
424
-
425
- Completed type-ahead inputs carry an explicit active-turn behavior. Safe
426
- inspection commands (`/info`, `/usage`, `/context`, `/memory`, `/status`,
427
- `/help`, `/skill`, and `/tools`) are atomically extracted and
428
- rendered without cancelling the response stream. State-changing and modal
429
- commands, including `/log` and `/model`, remain in FIFO order until the next safe turn
430
- boundary. `/new`, `/retry`, `/exit`, and explicit `/replace` retain interrupt
431
- semantics and take priority over active-turn query extraction. The input buffer
432
- rebuilds replay events after extraction so queued messages and the current draft
433
- preserve their original order and cursor. Esc cancellation preserves submitted
434
- queued input and starts its FIFO replay after stream cleanup; Ctrl+C remains the
435
- explicit clear-buffer interrupt. A conversation reset consumes `/new` but retains
436
- its FIFO tail for the new conversation. Modal prompts isolate that pre-existing
437
- tail from widget input and expose it again only after modal ownership ends.
438
- Commands that eventually open a modal keep the outer interrupt listener during
439
- their asynchronous prefetch and persistence phases. Before the widget starts,
440
- the terminal session requests a reader pause and waits for its acknowledgement;
441
- the reader resumes after modal ownership ends. Type-ahead is therefore buffered
442
- FIFO instead of racing or leaking into a later model, agent, or configuration
443
- field. Service-layer approval, secret, selection, and follow-up prompts acquire
444
- the same lifetime-bound modal handoff through the prompt-entry hook, and
445
- concurrent service prompts are serialized so two widgets never read stdin at
446
- once.
447
-
448
- `/resume` is the canonical saved-session selector; `/conversation` and
449
- `/conversations` remain compatibility aliases. The selector includes every
450
- conversation with persisted context, even when it has no title. Resuming a
451
- different conversation clears the process-local goal and forces auto mode off,
452
- so state from the previous session cannot drive the resumed one accidentally.
453
- `/new` applies the same process-local goal/auto reset at the fresh-session
454
- boundary while preserving the queued FIFO tail. Persisted titles are reduced to
455
- one bounded control-free selector row before that row is bound to its typed
456
- conversation ID. Local upserts stamp the activity time used by `/resume`,
457
- `--continue`, and `conversation resume <id>` ordering. The command remains
458
- FIFO-queued while a turn is active because its selector is a modal terminal
459
- owner.
460
-
461
- Normal `/exit` and empty-prompt Ctrl+D termination are serialized through the
462
- output actor. It rejects new writes, completes its current render batch, resets
463
- styles and terminal modes, restores the full scroll region, clears the tracked
464
- multiline footer, shows the cursor, disables raw mode, and drops the terminal
465
- surface before printing one plain saved-session message. The shutdown
466
- acknowledgement and actor join occur after that message, so no detached redraw
467
- can overwrite terminal cleanup. The generic `restore_terminal` function is a
468
- best-effort fallback for failures outside this coordinated path. An empty
469
- session reports that no resumable messages were created instead of promising a
470
- session that the repository intentionally excludes from the resume list.
471
-
472
- Typing `/` opens the complete registered command catalog. Search includes
473
- canonical names and aliases; Up/Down changes the selection, and Enter inserts
474
- the selected template into the editor for partial matches and commands that
475
- require arguments. A later Enter submits that populated input; a fully typed
476
- exact command that needs no expansion submits normally. Palette descriptions
477
- expose `[now]`, `[queued]`, and `[interrupt]` so the queue behavior is visible
478
- before submission. The selected entry is rendered as the first hint row so it
479
- remains visible when the terminal can show only a constrained input viewport.
480
-
481
- ## Distribution — single source, two surfaces
482
-
483
- Pentesting and Builder share the **same Rust runtime binary**. The `pentesting`
484
- npm package is a thin distribution facade:
485
-
486
- ```text
487
- npm install -g pentesting
488
-
489
-
490
- pentesting CLI (Node.js shim)
491
- │ resolves or downloads the matching Builder release asset
492
-
493
- Builder binary (Rust) ← single runtime engine
494
- │ PENTESTING_PRODUCT_NAME=pentesting
495
-
496
- Interactive TUI with "pentesting" banner
497
- ```
498
-
499
- - The npm package installs a launcher, **not** a second agent runtime.
500
- - It resolves or downloads the correct release asset from
501
- `agnusdei1207/pentesting-public`.
502
- - It forwards arguments directly into the Rust binary — no command translation
503
- or compatibility shims.
504
- - If a change would add orchestration, memory, or prompt logic into the npm
505
- layer, that change belongs upstream in the Rust runtime.
506
-
507
- ## Supported Runtime Targets
508
-
509
- The npm launcher currently resolves a managed native release asset for Linux
510
- x64. Docker is the recommended runtime on Windows and macOS. Published Docker
511
- images support `linux/amd64` only; Apple Silicon Macs use Docker Desktop's amd64
512
- emulation. Native ARM64 images and binaries are not supported. Advanced users
513
- may set `PENTESTING_BIN` to a locally supplied compatible binary.
514
-
515
- | OS | CPU | Release asset |
516
- | --- | --- | --- |
517
- | Linux | x64 | `pentesting-x86_64-unknown-linux-musl` |
518
-
519
- `/update` (and the npm postinstall) resolves the matching asset for the current
520
- supported OS/CPU target from `agnusdei1207/pentesting-public`.
521
-
522
- ## Build containment boundary
523
-
524
- Compilation is outside the application runtime boundary and is always executed
525
- through resource-capped Docker wrappers. Host Cargo is not an emergency
526
- fallback. `dbuild.sh` owns individual Cargo commands, `dverify.sh` owns
527
- sequential gate profiles, and `dbuild-image.sh` owns BuildKit. Each path shares
528
- storage admission, effective-limit inspection, a machine-wide lock, watchdogs,
529
- and structured failure reports. Automated CI/CD is disabled; maintainers invoke
530
- these wrappers explicitly. The
531
- normative contract is [Docker-only build safety](https://github.com/agnusdei1207/pentesting/blob/main/docs/BUILD_SAFETY.md).
532
-
533
- Patch publication performs one Cross build. The version-checked, checksummed
534
- AMD64 musl artifact is uploaded to GitHub and packaged into Docker from a
535
- minimal context; its dependency cache stays in a versioned Docker volume.
536
-
537
- The measured next-stage simplification and deletion plan is indexed at
538
- [Minimal Core plan](https://github.com/agnusdei1207/pentesting/blob/main/docs/plans/2026/07/10/minimal-core/README.md).
539
- The concrete PTY actor, unified security-tool surface, turn-trajectory, and dead-path reduction is
540
- recorded in [the 2026-07-10 implementation report](docs/plans/2026/07/10/IMPLEMENTATION_LightweightCoreRefactor_2026-07-10.md).
541
-
542
- ## Configuration
543
-
544
- Pentesting reads a user-global config from `~/.pentesting/.pentesting.toml`,
545
- overridden by project-local `.pentesting.toml` files discovered by walking up
546
- from the working directory. Local storage is the default; normal setup only
547
- needs the public model endpoint environment.
548
-
549
- The full file shape is represented in `builder.schema.json`; common runtime and
550
- CTF fields are editable through `/config`. Set `PENTESTING_CONFIG` to override
551
- the global config directory.
552
-
553
- | Variable | Description |
554
- | --- | --- |
555
- | `OPENAI_API_KEY` | API key or gateway token for OpenAI-compatible providers. |
556
- | `OPENAI_BASE_URL` | OpenAI-compatible base URL, for example `https://api.openai.com/v1` or a self-hosted gateway. |
557
- | `OPENAI_MODEL` | Default model id. |
558
- | `OPENAI_MAX_TOKENS` | Optional output-token override; accepts values like `4096`, `32k`, or `1M`. |
559
- | `PENTESTING_BIN` | Use an already-installed Builder binary instead of the managed download. |
560
- | `PENTESTING_PRODUCT_NAME` | Runtime banner label. The `pentesting` launcher sets this to `pentesting` automatically. |
561
- | `PENTESTING_REPO` | Override the public release repo used for binary downloads. Defaults to `agnusdei1207/pentesting-public`. |
562
- | `PENTESTING_SKIP_DOWNLOAD` | Skip the postinstall binary download. Useful in CI or when `PENTESTING_BIN` will be provided later. |
563
- | `PENTESTING_CONFIG` | Override the global config directory. |
564
-
565
- ### Canonical configuration contract
566
-
567
- The next-generation runtime accepts one product namespace. Configuration uses
568
- `PENTESTING_*`, `~/.pentesting/.pentesting.toml`, and project-local
569
- `.pentesting.toml`. `BUILDER_*`, `.builder.toml`, `.builder/`, JSON config
570
- fallbacks, and runtime alias translation have been removed. Existing users must
571
- move data explicitly before upgrading; the runtime does not carry a permanent
572
- old/new branch.
573
-
574
- ## Interactive Commands
575
-
576
- Inside an interactive session, these commands inspect and drive runtime state
577
- (`/help` lists the full set):
578
-
579
- ```text
580
- /status Show goal/mode/queue, turn vs mission, run gates, budgets, and a bounded read-only battlefield
581
- /workflow report
582
- Export the active run, engagement metadata, evidence, and large outputs to Markdown
583
- /context Show recent context-budget snapshots for the current conversation
584
- /memory Show stored conversation memories for the current conversation
585
- /tools List the currently available tools and schemas
586
- /agent Switch the active agent
587
- /resume Resume a saved session for the active workspace
588
- /goal <task> Set the active goal without enabling autonomous mode
589
- /auto Toggle autonomous mode for the current goal (default: off; Esc stops it)
590
- /update Download and apply the latest public release asset for supported native targets
591
- /help Show all commands
592
- /exit Save the session, restore the terminal, and quit
593
- ```
594
-
595
- ## Security Domain Skills
596
-
597
- Six built-in skills ship with the runtime: `create-skill`, `execute-plan`,
598
- `github-pr-description`, `ctf-competition`, `pentesting-methodology`, and
599
- `write-report`. For authorized security work, `ctf-competition` covers callback
600
- delivery agility, reliable payload/tool delivery, and interpreter-aware
601
- execution; `pentesting-methodology` maps assessments to standard frameworks;
602
- and `write-report` turns preserved evidence into reproducible CTF and
603
- penetration-test writeups.
604
-
605
- - **PTES** (Penetration Testing Execution Standard)
606
- - **MITRE ATT&CK** tactics and techniques
607
- - **OWASP** Top 10 and Testing Guide
608
- - **CWE/CAPEC** weakness and attack pattern catalogs
609
- - **NIST CSF** and **CIS Controls**
610
-
611
- ### Shell listener for authorized labs
612
-
613
- ```bash
614
- pentesting shell-listener --bind 127.0.0.1 --port 4444 --extra-ports 8443,9001
615
- ```
616
-
617
- Up to 32 unique primary/additional ports bind concurrently and share one monotonic
618
- session-id sequence; an unavailable port is skipped as long as at least one
619
- requested port binds. `shell-session --json health` reports the active bound
620
- endpoints so callback selection can be evidence-based. The remote-bind safety
621
- gate remains unchanged.
622
-
623
- Manages multiple accepted TCP sessions with per-session routing, buffered
624
- output, raw byte logging, full-duplex transcripts, command history, attach /
625
- detach events, replay, and evidence manifests. `probe` records the remote's
626
- current shell interpreter in `shell`, detected only from `/proc/$$/exe` and
627
- `$0`, so a BusyBox `sh` target is not confused with an installed Bash. This
628
- interpreter axis is separate from TTY/`pty_state`; it is stored in session state,
629
- the `shell-session --json` projection, session snapshots, and evidence manifests,
630
- and is restored after a listener restart. `pty-upgrade` sends one concrete
631
- helper only; `upgrade` runs a helper plus a probe and records `pty_state` as
632
- verified or failed. Explicit `technique=auto` adds a bounded listener-side state
633
- machine: framed capability recon, allowlisted `bash`/`sh` selection, ordered
634
- helper attempts (`python3`, `python`, `python2`, `script`, `expect`), generic
635
- prompt observation, and phase-local probe verification. Only unavailable,
636
- early-returned, or completed-but-unverified attempts advance to the next
637
- candidate; timeout, disconnect, or writer failure stops without blind input.
638
- The entire operation keeps one command id, deadline, session lease, ledger, and
639
- final response. There is still no silent default: omission is rejected, manual
640
- techniques keep their single-attempt behavior, and custom text remains the
641
- escape hatch for unusual targets. Raw logs and transcripts are capped per session and closed sessions
642
- are archived automatically so a noisy peer cannot grow memory or disk without
643
- bound. Secret redaction is applied before new raw/transcript/display records are
644
- written; it is not retroactive for output that arrived before the secret value
645
- was registered. Bound to loopback by default; `--allow-remote` is an explicit
646
- opt-in gate.