pwn 0.5.668 → 0.5.670

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +15 -0
  3. data/Gemfile +1 -1
  4. data/README.md +8 -6
  5. data/documentation/AI-Integration.md +5 -3
  6. data/documentation/Agent-Tool-Registry.md +18 -14
  7. data/documentation/Configuration.md +6 -0
  8. data/documentation/Contributing.md +13 -0
  9. data/documentation/Diagrams.md +1 -1
  10. data/documentation/Home.md +4 -4
  11. data/documentation/How-PWN-Works.md +6 -6
  12. data/documentation/Persistence.md +17 -0
  13. data/documentation/Reinforcement-Learning.md +39 -39
  14. data/documentation/SDR.md +1 -1
  15. data/documentation/Sessions.md +1 -0
  16. data/documentation/Skills-Memory-Learning.md +2 -0
  17. data/documentation/What-is-PWN.md +3 -3
  18. data/documentation/diagrams/agent-tool-registry.svg +43 -43
  19. data/documentation/diagrams/ai-integration-tool-calling.svg +112 -85
  20. data/documentation/diagrams/dot/agent-tool-registry.dot +4 -4
  21. data/documentation/diagrams/dot/ai-integration-tool-calling.dot +7 -3
  22. data/documentation/diagrams/dot/memory-skills-detailed.dot +2 -2
  23. data/documentation/diagrams/dot/overall-pwn-architecture.dot +6 -4
  24. data/documentation/diagrams/dot/persistence-filesystem.dot +1 -1
  25. data/documentation/diagrams/dot/sdr-radio-flow.dot +1 -1
  26. data/documentation/diagrams/dot/task-summarizer.dot +24 -12
  27. data/documentation/diagrams/memory-skills-detailed.svg +182 -182
  28. data/documentation/diagrams/overall-pwn-architecture.svg +154 -146
  29. data/documentation/diagrams/persistence-filesystem.svg +6 -6
  30. data/documentation/diagrams/sdr-radio-flow.svg +1 -1
  31. data/documentation/diagrams/task-summarizer.svg +178 -126
  32. data/documentation/pwn-ai-Agent.md +53 -15
  33. data/lib/pwn/ai/agent/loop.rb +773 -6
  34. data/lib/pwn/ai/agent/prompt_builder.rb +81 -7
  35. data/lib/pwn/ai/agent/task_summarizer.rb +426 -28
  36. data/lib/pwn/ai/agent/tools/shell.rb +32 -0
  37. data/lib/pwn/config.rb +7 -2
  38. data/lib/pwn/memory.rb +188 -0
  39. data/lib/pwn/memory_index.rb +17 -2
  40. data/lib/pwn/plugins/repl.rb +36 -7
  41. data/lib/pwn/sessions.rb +9 -4
  42. data/lib/pwn/version.rb +1 -1
  43. data/spec/lib/pwn/ai/agent/loop_spec.rb +246 -2
  44. data/spec/lib/pwn/ai/agent/prompt_builder_spec.rb +51 -0
  45. data/spec/lib/pwn/ai/agent/task_summarizer_spec.rb +115 -0
  46. data/spec/lib/pwn/ai/agent/tools/shell_spec.rb +21 -0
  47. data/spec/lib/pwn/memory_spec.rb +62 -0
  48. data/spec/lib/pwn/plugins/repl_pwn_vault_spec.rb +134 -0
  49. data/third_party/pwn_rdoc.jsonl +30 -2
  50. metadata +4 -3
@@ -90,7 +90,7 @@ $ pwn --ai "run bin/pwn_sast against ./src and push findings to DefectDojo"
90
90
 
91
91
  ## What the agent can call
92
92
 
93
- 12 toolsets · **78 tools** - full table at
93
+ 12 toolsets · **82 tools** - full table at
94
94
  [Agent Tool Registry](Agent-Tool-Registry.md).
95
95
 
96
96
  The two that matter most:
@@ -113,12 +113,21 @@ full `Loop.run` under a persona overlay) that share a JSONL bus. See
113
113
 
114
114
  ## Task summaries (long autonomous turns)
115
115
 
116
- `PWN::AI::Agent::TaskSummarizer` keeps the TUI readable during multi-step work:
116
+ `PWN::AI::Agent::TaskSummarizer` keeps the TUI readable during multi-step work.
117
+ First it classifies the request with `request_kind` (LLM when enabled, else
118
+ heuristics / `request_intent`):
119
+
120
+ | Kind | Example | Task breakdown |
121
+ |---|---|---|
122
+ | `statement` | "FYI the build is green." | None - brief ack only |
123
+ | `question` | "what is the default GQRX port?" / "how to ...?" | None - concise answer only |
124
+ | `autonomous_goal` | "refactor Loop.run and run rubocop" / "what is my hostname?" | **Required** ordered work units (each may use one or more tools) |
117
125
 
118
126
  | Surface | When | Content |
119
127
  |---|---|---|
120
- | `emit_plan!` | User submit | **Full** goal + ordered plain-English tangible tasks (each may need many tools) |
121
- | `about_to` | Before each tool batch | **Primary:** `task k/n: <english>` - **secondary:** `via shell×2 (search)` (not raw argv) |
128
+ | `request_kind` | User submit | `statement` \| `question` \| `autonomous_goal` |
129
+ | `emit_plan!` | Autonomous goals only | **Full** goal + ordered plain-English tangible tasks (each may need many tools) |
130
+ | `about_to` | Before each tool batch | **Primary:** `task k/n: <english>` - **secondary:** `via shell×2 (search)` (not raw argv) |
122
131
  | `plan_context` / `active_task_prompt` | Into Loop messages | Same English tasks steer tool choice (not TUI-only) |
123
132
  | `record!` | After each tool | Advances `plan_idx`; emits English advancement brief when the index moves; verbose progress only if `task_summary_verbose` |
124
133
  | `flush!` | End of turn | Optional closing brief with active `task k/n` |
@@ -131,7 +140,7 @@ full `Loop.run` under a persona overlay) that share a JSONL bus. See
131
140
  - Advancement needs a PRM +1 streak or a clear phase shift after tools on the active task (not a blind every-3-tools hop).
132
141
  - REPL contract: `on_tool.call('task', full_summary_text, '')` - result empty, no truncation.
133
142
 
134
- **Budget pressure:** when unresolved `agent_loop` / `assistant_answer` budget-exhaustion fingerprints dominate, `Loop.budget_exhaustion_hot?` tightens the live turn (stricter `max_iters` on local engines than remote), forces a text-only tail, skips counterfactual forks, and still flushes task state + Learning on the exhaust path.
143
+ **Long-run pressure:** when recent turns keep hitting the iteration ceiling, the agent tightens the rest of the turn: lower `max_iters` (stricter on local engines than remote), a text-only finish, and no extra counterfactual forks. Task state and Learning still flush on the way out so the run ends with a real answer instead of thrashing.
135
144
 
136
145
  ![TaskSummarizer](diagrams/task-summarizer.svg)
137
146
 
@@ -142,6 +151,8 @@ task_summary: true # master switch (default on)
142
151
  task_summary_every: 5 # verbose progress every N tools
143
152
  task_summary_interval_s: 8.0 # or every N seconds (verbose)
144
153
  task_summary_verbose: false # mid-flight Progress: lines
154
+ task_summary_llm: true # LLM task decompose for autonomous goals (default on)
155
+ request_kind_llm: null # null = follow task_summary_llm; false = heuristic-only
145
156
  max_iters: 25 # budget pressure may lower the effective cap (stricter on local engines)
146
157
  ```
147
158
 
@@ -157,18 +168,17 @@ max_iters: 25 # budget pressure may lower the effective cap (s
157
168
  - Run `mistakes_list` before retrying something that failed last session -
158
169
  the fix may already be recorded.
159
170
  - `ai.agent.tool_router: true` + `ai.agent.plan_first: true` when running on
160
- a local model - dramatically cuts mis-routing.
171
+ a local model - that cuts mis-routing a lot.
161
172
  - Set `ai.reflect_engine:` to a frontier provider so lessons written to
162
- `~/.pwn/memory.json` are high-signal even when the *executing* engine is
173
+ `~/.pwn/memory.json` stay high-signal even when the executing engine is
163
174
  local.
164
- - `PWN::AI::Agent::Learning.export_finetune` + `Reward.export_dpo` turn every
165
- successful session and every preference pair into supervised / DPO
166
- datasets under `~/.pwn/finetune/` - `Curriculum.train_and_gate` then
167
- LoRA-tunes the local model and promotes only under **gate v2** (resolved
168
- margin + mean judge + frozen smoke set). Preference pairs prefer trajectory
169
- geometry: revised answers and winning traces, not fix-commentary prose.
170
- `scrub_preferences` and the export filter enforce that; practice lands
171
- winning traces.
175
+ - `PWN::AI::Agent::Learning.export_finetune` and `Reward.export_dpo` turn
176
+ successful sessions and preference pairs into supervised / preference
177
+ datasets under `~/.pwn/finetune/`. `Curriculum.train_and_gate` can then
178
+ fine-tune a local model and promote only when resolved-mistake margin,
179
+ mean judge score, and a frozen smoke set all look healthy. Preference
180
+ pairs should be real answer revisions and winning traces, not fix-commentary
181
+ prose. `scrub_preferences` and the export filter enforce that.
172
182
  See [Reinforcement Learning](Reinforcement-Learning.md).
173
183
 
174
184
  ## RL feature flags (`PWN::Env[:ai][:agent]`)
@@ -189,3 +199,31 @@ Full detail: [Reinforcement Learning](Reinforcement-Learning.md).
189
199
  [Extrospection](Extrospection.md) · [Swarm](Swarm.md) · [Cron](Cron.md)
190
200
 
191
201
  [← Home](Home.md)
202
+
203
+ ## Intent routing (kind + fine-grained intent)
204
+
205
+ Every user turn is classified on two layers:
206
+
207
+ 1. **`request_kind`** - `statement` | `question` | `autonomous_goal` (TaskSummarizer is the
208
+ single source of truth; `Loop.request_kind` delegates). Classification order:
209
+ injected label (tests) → cheap `request_intent` short-circuits (greeting/howto/recall/recon) →
210
+ strong agent-do / host-evidence heuristics → **LLM classify** via `chat_for_kind`
211
+ (when `ai.agent.request_kind_llm` is on / follows `task_summary_llm`) → offline
212
+ `heuristic_request_kind`. Only autonomous goals receive a multi-step tangible-task plan.
213
+ 2. **`request_intent`** - fine-grained route for cheap short-circuits and recon guard.
214
+
215
+ | Intent | Kind | Example | Behavior |
216
+ |--------|------|---------|----------|
217
+ | How-to | question | "how to do a ping sweep of a subnet using hping3?" | Short explanation with example commands only. No tools and no multi-step plan. |
218
+ | Question | question | "what is the default GQRX remote-control port?" | Concise answer. No multi-step task breakdown. |
219
+ | Host evidence | autonomous_goal | "what is my hostname?" / "excellent - what is my hostname?" | Needs a live local lookup (hostname, cwd, whoami, IP, ...). Treated as a goal so tools run; not text-only Q&A. |
220
+ | Greeting | statement | "Howdy, it's cloudy." / "hi" | Fixed short ack that the system is ready. No tools, no LLM, and no weather echo such as "noted, cloudy out there." |
221
+ | Statement | statement | "FYI the build is green." | Brief note. No multi-step task plan. |
222
+ | Recall | question | "what did I just say?" / "how did you respond?" | Cheap prior-turn answer from the session transcript. No plan_first and no multi-tool archaeology. |
223
+ | Live recon | autonomous_goal | "using hping3 what live hosts can you find in this subnet?" | Needs clear in-scope / authorized engagement wording, or set `ai.agent.recon_authorized=true`. Otherwise the agent refuses and points you at the how-to form. |
224
+ | Act | autonomous_goal | "refactor Loop.run and run rubocop" | Normal multi-step agent work: decompose into ordered work units, each may use one or more tools. |
225
+
226
+ The `shell` tool also blocks hping3 / nmap-style sweep commands when recon is
227
+ not authorized. On how-to asks, memory SOPs about repo rubocop/rake hygiene are
228
+ kept out of the prompt so the model does not pivot into unrelated verification.
229
+