pwn 0.5.680 → 0.5.683

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/documentation/AI-Integration.md +1 -1
  4. data/documentation/Agent-Tool-Registry.md +11 -7
  5. data/documentation/Configuration.md +6 -7
  6. data/documentation/How-PWN-Works.md +2 -2
  7. data/documentation/Reinforcement-Learning.md +1 -1
  8. data/documentation/diagrams/agent-tool-registry.svg +1 -1
  9. data/documentation/diagrams/dot/agent-tool-registry.dot +1 -1
  10. data/documentation/diagrams/dot/task-summarizer.dot +3 -3
  11. data/documentation/pwn-ai-Agent.md +16 -35
  12. data/lib/pwn/ai/agent/loop.rb +265 -192
  13. data/lib/pwn/ai/agent/mistakes.rb +17 -0
  14. data/lib/pwn/ai/agent/policy.rb +53 -4
  15. data/lib/pwn/ai/agent/prompt_builder.rb +46 -19
  16. data/lib/pwn/ai/agent/registry.rb +18 -13
  17. data/lib/pwn/ai/agent/task_summarizer.rb +374 -503
  18. data/lib/pwn/ai/agent/tools/sessions.rb +32 -0
  19. data/lib/pwn/ai/agent/tools/skills.rb +56 -0
  20. data/lib/pwn/ai/anthropic.rb +0 -1
  21. data/lib/pwn/ai/gemini.rb +0 -1
  22. data/lib/pwn/ai/grok.rb +0 -1
  23. data/lib/pwn/ai/ollama.rb +0 -1
  24. data/lib/pwn/ai/open_ai.rb +0 -1
  25. data/lib/pwn/ai/open_web_ui.rb +0 -1
  26. data/lib/pwn/config.rb +1 -1
  27. data/lib/pwn/plugins/repl.rb +37 -0
  28. data/lib/pwn/plugins/tty_spinner.rb +55 -6
  29. data/lib/pwn/sessions.rb +82 -0
  30. data/lib/pwn/version.rb +1 -1
  31. data/spec/integration/prompt_builder_spec.rb +6 -4
  32. data/spec/lib/pwn/ai/agent/loop_spec.rb +314 -34
  33. data/spec/lib/pwn/ai/agent/mistakes_spec.rb +14 -0
  34. data/spec/lib/pwn/ai/agent/policy_spec.rb +52 -1
  35. data/spec/lib/pwn/ai/agent/prompt_builder_spec.rb +8 -9
  36. data/spec/lib/pwn/ai/agent/registry_spec.rb +30 -3
  37. data/spec/lib/pwn/ai/agent/signal_hygiene_spec.rb +4 -5
  38. data/spec/lib/pwn/ai/agent/task_summarizer_spec.rb +321 -90
  39. data/spec/lib/pwn/ai/agent/tools/sessions_spec.rb +5 -0
  40. data/spec/lib/pwn/ai/agent/tools/skills_spec.rb +16 -0
  41. data/spec/lib/pwn/ai/red_team/test_case_engine_spec.rb +20 -0
  42. data/spec/lib/pwn/plugins/repl_spec.rb +9 -0
  43. data/spec/lib/pwn/plugins/tty_spinner_spec.rb +30 -0
  44. data/spec/lib/pwn/sessions_spec.rb +29 -0
  45. data/spec/spec_helper.rb +6 -0
  46. data/third_party/pwn_rdoc.jsonl +30 -9
  47. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca4257e59d3ee50dde626ddb4aabf356b578ebd2bb82a23f3b724cae214d6d09
4
- data.tar.gz: 62c7c4a1b139769fe86e20ea0243f0cc2d7155eb15421dcd2e29c640b6bd838d
3
+ metadata.gz: 138deb9b9916fd71329a5898d6cb49ab53751e597f408177aee7682704f33500
4
+ data.tar.gz: 77f88100898efbff17bea33bbd2efa186afecf2776c02d3e577a71b26d1b2d3b
5
5
  SHA512:
6
- metadata.gz: adca8d361a9535a64bac1804a5cf5ae04b1736bfa4ecde55be7b956dfa33d02e7f8e75827bd76164af9c103b6e1d188fa53ed6627fe38677ff1263512c202795
7
- data.tar.gz: 0de0c0e020d650c893322714b7ea90a1a91c9d0a4e38c475fad8e37584711c0f8d985571e8514fcaf05fd0d8c2a02010974b44fd3fe923ca1ee89014002a8be0
6
+ metadata.gz: 265a38e4abaead447360e549c98f88dc0a3d3220358d0e30c9e9419d6c1b53dd558dac87b2ce093e968b53bbab9051db7032b405d5835194c33934acd64ecb4d
7
+ data.tar.gz: 7c0e34b2be0c96ddef980ee81493f5b2d394680ca956f0b6208cc32758fda13f212670febca563092cd5b0331ac46464bdecd0f6c88d2f7a15744f4b1cd79d48
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  ._*
2
2
  .each*
3
+ .env
3
4
  *.swp
4
5
  *.gem
5
6
  *.rbc
@@ -48,7 +48,7 @@ The harness adapts to the *class* of engine, not the model name:
48
48
  | **MEMORY ranking** | relevance-ranked when a local Ollama `embed_model` is reachable, else newest-first | relevance-ranked via `PWN::MemoryIndex` (`~/.pwn/memory.idx`) |
49
49
  | **Tool schemas shipped** | all toolsets | `CORE_TOOLS` + top-K keyword matches when `ai.agent.tool_router` is on (default on). Ties also honor `tool_preference`. |
50
50
  | **Pre-pass** | none | `plan_first` numbered tool plan before first dispatch |
51
- | **Intent route** | always | `request_intent` + LLM/heuristic `request_kind` (statement \| question \| autonomous_goal). Short-circuits how-to/questions (text only), greetings/statements (fixed ack), pure recall, and unauthorized recon on all engines; host-evidence Qs (hostname/cwd/whoami) and only true autonomous goals get multi-step TaskSummarizer plans. Critical for ollama/openwebui |
51
+ | **Intent route** | always | `request_intent` only (greeting / howto / recall cheap paths). There is no request type. Every other turn gets a TaskSummarizer compass and CORE_TOOLS. |
52
52
  | **Few-shot** | none | `Learning.exemplars_for(request)` splices a prior successful trace |
53
53
  | **Dispatch parsing** | strict | tolerant - Levenshtein tool-name repair + JSON5-ish arg cleanup, each repair fingerprinted into `Mistakes` |
54
54
  | **Post-answer** | `auto_introspect` (deferred by default) | `auto_introspect` **+** `fact_check_local_final` (auto `extro_verify` on CVE/version-shaped claims). Deferred after the reply; specs/cron stay inline. |
@@ -13,8 +13,8 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
13
13
  | `terminal` | `shell` | `Open3.capture3` on the host, after `PWN::AI::Agent::ToolGuard` |
14
14
  | `pwn` | `pwn_eval` | `TOPLEVEL_BINDING.eval` in the live REPL process, after `ToolGuard` |
15
15
  | `memory` | `memory_remember` · `memory_recall` · `memory_forget` · `memory_clear` · **`memory_lean`** | `PWN::Memory` → `~/.pwn/memory.json` |
16
- | `skills` | `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` · `skill_migrate_legacy` | `~/.pwn/skills/<name>/SKILL.md` (**[agentskills.io](https://agentskills.io) spec**; legacy flat `*.md` auto-migrated) |
17
- | `sessions` | `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` · **`sessions_lean`** | `PWN::Sessions` → `~/.pwn/sessions/` |
16
+ | `skills` | **`skills_recall`** · `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` · `skill_migrate_legacy` | `~/.pwn/skills/<name>/SKILL.md` (**[agentskills.io](https://agentskills.io) spec**; legacy flat `*.md` auto-migrated) |
17
+ | `sessions` | **`session_recall`** · `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` · **`sessions_lean`** | `PWN::Sessions` → `~/.pwn/sessions/` |
18
18
  | `learning` | `learning_note_outcome` · `learning_reflect` · `learning_distill_skill` · `learning_stats` · `learning_outcomes` · `learning_consolidate` · `learning_reset` · `learning_auto_introspect_toggle` · **`learning_gc_stores`** · **`learning_purge_noise`** · **`mistakes_list`** · **`mistakes_record`** · **`mistakes_resolve`** · **`mistakes_reset`** · **`mistakes_lean`** · **`reward_judge`** · **`reward_prm`** · **`reward_sentinel`** · **`reward_preferences`** · **`reward_export_dpo`** · **`reward_warm_sentinel`** · **`reward_scrub_preferences`** · **`reward_preference_balance`** · **`curriculum_practice`** · **`curriculum_train`** · **`curriculum_hindsight`** · **`curriculum_offline_judge`** · **`curriculum_preference_balance`** | `PWN::AI::Agent::Learning` + `Mistakes` + `Reward` + `Curriculum` → `~/.pwn/learning.jsonl` + `~/.pwn/mistakes.json` + `~/.pwn/preferences.jsonl` + `~/.pwn/curriculum/` + `~/.pwn/finetune/` |
19
19
  | `reward` | **`reward_generator_mix`** | `PWN::AI::Agent::Reward.generator_mix` → online preference source-mix controller (`preferences.jsonl`) |
20
20
  | `curriculum` | **`curriculum_practice_kpi`** | `PWN::AI::Agent::Curriculum.practice_kpi` → `~/.pwn/curriculum_kpi.jsonl` |
@@ -56,8 +56,9 @@ user request through as `relevance:`, `Registry.definitions` shrinks the
56
56
  pool to:
57
57
 
58
58
  ```text
59
- CORE_TOOLS = shell · pwn_eval · memory_remember · memory_recall
60
- mistakes_record · mistakes_resolve · learning_note_outcome
59
+ CORE_TOOLS / DEFAULT_PREFERENCE (same list):
60
+ memory_recall · session_recall · skills_recall · pwn_eval · shell
61
+ mistakes_record · mistakes_resolve · learning_note_outcome · memory_remember
61
62
  + top-K keyword-ranked matches for THIS request
62
63
  (ties break on Metrics per-engine success_rate, then
63
64
  ai.agent.tool_preference)
@@ -80,7 +81,7 @@ When keyword fit and other rank scores tie, the registry prefers this
80
81
  default order:
81
82
 
82
83
  ```text
83
- memory_recall · sessions_view · pwn_eval · shell
84
+ memory_recall · session_recall · skills_recall · pwn_eval · shell
84
85
  mistakes_record · mistakes_resolve · learning_note_outcome · memory_remember
85
86
  ```
86
87
 
@@ -88,9 +89,12 @@ Set `ai.agent.tool_preference` in `~/.pwn/pwn.yaml`, or pass `order:` /
88
89
  `preference:` into `Registry.definitions`, `.rank`, or `.apply_preference`.
89
90
  An explicit empty list turns preference off (no Env / default fallback).
90
91
 
92
+ Learned facts and this session are injected (MEMORY / RECENT TURNS), not
93
+ first tools. Preference then lists `pwn_eval` before `shell`. `sessions_view`
94
+ is not a CORE tool. There is no separate ACT_PREFERENCE.
95
+
91
96
  Keyword fit stays the primary signal. Preference is a smaller bonus plus a
92
- stable sort after the router slims the pool, so `memory_recall` wins a
93
- tie against `shell` without hiding a better keyword match.
97
+ stable sort after the router slims the pool.
94
98
 
95
99
  `Policy` uses the same list when it suggests a next action in the prompt.
96
100
 
@@ -123,8 +123,7 @@ ai:
123
123
  task_summary_every: 5 # When task_summary_verbose: emit Progress every N completed tools.
124
124
  task_summary_interval_s: 8.0 # When verbose: also emit when this many seconds elapsed.
125
125
  task_summary_verbose: false # Mid-flight Progress/Finished lines (default: only plan + about_to).
126
- task_summary_llm: true # LLM tangible-task decompose for autonomous goals (default on). false = offline fallback.
127
- request_kind_llm: ~ # LLM request_kind classifier (statement|question|autonomous_goal). nil = follow task_summary_llm.
126
+ task_summary_llm: true # LLM tangible-task decompose (default on). false = offline fallback.
128
127
  max_depth: 3 # Recursion guard: how many levels deep agent_ask/agent_debate sub-agents may spawn sub-agents.
129
128
  auto_introspect: true # Run Learning.auto_introspect (outcome logging + lesson mining) after every final answer.
130
129
  auto_extrospect: true # Ambient baseline after every final answer (host/repo/env ONLY - never launches burpsuite/zaproxy/msf/gqrx). Sense tools stay on-demand.
@@ -134,9 +133,10 @@ ai:
134
133
  shell_bash: false # true -> run shell via bash -lc. Default is /bin/sh.
135
134
  plan_first: ~ # Plan-then-act pre-pass. nil = auto (true when ai.active is ollama or openwebui).
136
135
  tool_router: ~ # Dynamic tool-set slimming. nil = auto (true for ollama / openwebui).
137
- tool_preference: # Operator-tunable tool order. Rank bonus + Policy suggested-action list.
136
+ tool_preference: # Same order as CORE_TOOLS. Current session is injected; then memory_recall, session_recall, skills_recall, pwn_eval, shell.
138
137
  - memory_recall
139
- - sessions_view
138
+ - session_recall
139
+ - skills_recall
140
140
  - pwn_eval
141
141
  - shell
142
142
  - mistakes_record
@@ -308,8 +308,7 @@ PWN::Config.refresh_env
308
308
  | `ai.agent.task_summary_every` | Integer | `5` | `TaskSummarizer.every_n` | Verbose progress cadence (tools). |
309
309
  | `ai.agent.task_summary_interval_s` | Float | `8.0` | `TaskSummarizer.interval_s` | Verbose progress cadence (seconds). |
310
310
  | `ai.agent.task_summary_verbose` | Boolean | `false` | `TaskSummarizer.verbose?` | Emit mid-flight `Progress:` / `Finished:` lines; default keeps only plan + about_to. |
311
- | `ai.agent.task_summary_llm` | Boolean \| `nil` | `nil` (on) | `TaskSummarizer.llm_plan_enabled?` | LLM tangible-task decomposition for autonomous goals. `false` forces offline generic fallback (tests / air-gap). |
312
- | `ai.agent.request_kind_llm` | Boolean \| `nil` | `nil` (follow `task_summary_llm`) | `TaskSummarizer.llm_kind_enabled?` / `request_kind` | LLM classifier for `statement` \| `question` \| `autonomous_goal`. Cheap intents and host-evidence heuristics still win first; `false` is heuristic-only. |
311
+ | `ai.agent.task_summary_llm` | Boolean \| `nil` | `nil` (on) | `TaskSummarizer.llm_plan_enabled?` | LLM tangible-task decomposition. `false` forces offline generic fallback (tests / air-gap). |
313
312
  | `ai.agent.max_depth` | Integer | `3` | `PWN::AI::Agent::Swarm` | Recursion guard for `agent_ask` / `agent_debate` sub-agents spawning sub-agents. |
314
313
  | `ai.agent.auto_introspect` | Boolean | `true` | `PWN::AI::Agent::Learning.auto_introspect` | Run outcome logging + lesson mining after every final answer. Toggle live via `learning_auto_introspect_toggle`. |
315
314
  | `ai.agent.auto_extrospect` | Boolean | `true` | `PWN::AI::Agent::Extrospection.auto_extrospect` | Ambient baseline after every final answer (`AUTO_SECTIONS` = host/repo/env only; never spawns GUI/JVM tools). Sense tools (`intel`/`verify`/`watch`/`rf_tune`/`observe`) stay on-demand. Toggle live via `extro_auto_toggle`. |
@@ -318,7 +317,7 @@ PWN::Config.refresh_env
318
317
  | `ai.agent.shell_bash` | Boolean | `false` | `PWN::AI::Agent::ToolGuard.shell_bash?` | When true, `shell` runs via `bash -lc` so bash-only syntax is allowed. Default is POSIX `/bin/sh` and bashisms are rejected with a rewrite hint. |
319
318
  | `ai.agent.plan_first` | Boolean \| `nil` | `nil` (auto: `true` when `ai.active` is `ollama` or `openwebui`) | `PWN::AI::Agent::Loop.plan_first` | Plan-then-act pre-pass: the model must emit a numbered tool plan (as an assistant message) *before* it may dispatch anything. Cheap chain-of-thought scaffolding for local models. |
320
319
  | `ai.agent.tool_router` | Boolean \| `nil` | `nil` (auto: `true` for `ollama` / `openwebui`) | `PWN::AI::Agent::Registry.definitions` | Dynamic tool-set slimming: expose only `Registry::CORE_TOOLS` + the top-K keyword-relevant schemas for *this* request. Ties break on historical `Metrics` success rate, then `ai.agent.tool_preference`. |
321
- | `ai.agent.tool_preference` | Array\<String\> | `memory_recall`, `sessions_view`, `pwn_eval`, `shell`, `mistakes_record`, `mistakes_resolve`, `learning_note_outcome`, `memory_remember` | `PWN::AI::Agent::Registry.preference_order` / `.rank` / `.apply_preference`, `Policy` | Operator-tunable tool order. Keyword fit stays primary; this list is a rank bonus and the default action list Policy quotes in the prompt. Explicit empty list disables preference. |
320
+ | `ai.agent.tool_preference` | Array\<String\> | `memory_recall`, `session_recall`, `skills_recall`, `pwn_eval`, `shell`, `mistakes_record`, `mistakes_resolve`, `learning_note_outcome`, `memory_remember` | `PWN::AI::Agent::Registry.preference_order` / `.rank` / `.apply_preference`, `Policy` | Same order as `CORE_TOOLS`. Current session is injected; then `memory_recall`, `session_recall`, `skills_recall`, `pwn_eval`, `shell`. Explicit empty list disables preference. |
322
321
  | `ai.agent.defer_introspect` | Boolean | `true` | `PWN::AI::Agent::TurnFinalizer` | Run `Learning.auto_introspect` on a background thread after the user-visible reply. Specs and cron stay inline. |
323
322
  | `ai.agent.prompt_cache` | Boolean | `true` | `PWN::AI::Agent::PromptCache` | Engine-native prefix cache. Anthropic uses `cache_control`; OpenAI uses `prompt_cache_key`; Grok uses `x-grok-conv-id`; Gemini splits `systemInstruction`. Ollama and Open WebUI have no native prefix-cache field. |
324
323
  | `ai.agent.local_introspect` | Symbol | `failure_only` | `PWN::AI::Agent::Learning.auto_introspect` | End-of-turn introspect policy for local engines: `always` · `failure_only` · `every_n` (with `introspect_every_n`). |
@@ -28,8 +28,8 @@ hardware).
28
28
  | Module | Role |
29
29
  |---|---|
30
30
  | `Loop` | plan → **TaskSummarizer** briefs → dispatch tool_calls → observe → repeat until final answer; tightens runway when recent turns exhausted the budget |
31
- | **`TaskSummarizer`** | Executive UX: LLM/heuristic `request_kind` gates plans (only autonomous goals, including host-evidence Qs) - English tasks primary - `emit_plan!` · `about_to` as `task k/n` + via tools · Loop `plan_context` injection · clearer `plan_idx` advance |
32
- | `Registry` | JSON-Schema function definitions grouped into 13 **toolsets** · **85 tools** · `tool_preference` order (default memory_recall-first) |
31
+ | **`TaskSummarizer`** | Executive UX: every request gets an English task compass (`emit_plan!` · `about_to` as `task k/n`) no statement/question/goal type |
32
+ | `Registry` | JSON-Schema function definitions grouped into 13 **toolsets** · **87 tools** · `CORE_TOOLS` = `DEFAULT_PREFERENCE` (`memory_recall` · `session_recall` · `skills_recall` · `pwn_eval` · `shell`) |
33
33
  | `Dispatch` / `Result` | execute a tool, capture stdout/value/error/duration |
34
34
  | `PromptBuilder` | inject MEMORY / SKILLS / LEARNING / **KNOWN MISTAKES + FIXES** / METRICS / **POLICY** / EXTROSPECTION / RECENT TURNS |
35
35
  | `Metrics` · `Learning` · `Reflect` · **`Policy`** | **introspection** - how well am I doing? (Policy is live Q / REINFORCE, advisory rank only) |
@@ -169,7 +169,7 @@ This table is the live control list. Track the outcomes, not source comments.
169
169
  :max_iters: 75 # hard cap; budget pressure may lower effective value
170
170
  :defer_introspect: true # post-answer Learning after the user-visible reply
171
171
  :prompt_cache: true # engine-native prefix cache (not ollama / openwebui)
172
- :tool_preference: [memory_recall, sessions_view, pwn_eval, shell, mistakes_record, mistakes_resolve, learning_note_outcome, memory_remember]
172
+ :tool_preference: [memory_recall, session_recall, skills_recall, pwn_eval, shell, mistakes_record, mistakes_resolve, learning_note_outcome, memory_remember]
173
173
  ```
174
174
 
175
175
  ## Cron self-improvement
@@ -29,7 +29,7 @@
29
29
  <text xml:space="preserve" text-anchor="middle" x="105.12" y="-521.82" font-family="sans-Serif" font-size="12.00" fill="#0f172a">JSON&#45;Schema function defs</text>
30
30
  <text xml:space="preserve" text-anchor="middle" x="105.12" y="-507.57" font-family="sans-Serif" font-size="12.00" fill="#0f172a">rank(query) · CORE_TOOLS</text>
31
31
  <text xml:space="preserve" text-anchor="middle" x="105.12" y="-493.32" font-family="sans-Serif" font-size="12.00" fill="#0f172a">tool_router → CORE + top&#45;K</text>
32
- <text xml:space="preserve" text-anchor="middle" x="105.12" y="-479.07" font-family="sans-Serif" font-size="12.00" fill="#0f172a">tool_preference (memory_recall first)</text>
32
+ <text xml:space="preserve" text-anchor="middle" x="105.12" y="-479.07" font-family="sans-Serif" font-size="12.00" fill="#0f172a">tool_preference (pwn_eval then shell)</text>
33
33
  </g>
34
34
  <!-- terminal -->
35
35
  <g id="node2" class="node">
@@ -9,7 +9,7 @@ digraph "PWN_Agent_Tool_Registry" {
9
9
  shape=box, penwidth=1.3, color="#334155", fontcolor="#0f172a"];
10
10
  edge [color="#94a3b8", penwidth=1.1, arrowsize=0.7];
11
11
 
12
- Registry [label="Registry\nJSON-Schema function defs\nrank(query) · CORE_TOOLS\ntool_router → CORE + top-K\ntool_preference (memory_recall first)", fillcolor="#c4b5fd", fontsize=12, penwidth=2];
12
+ Registry [label="Registry\nJSON-Schema function defs\nrank(query) · CORE_TOOLS\ntool_router → CORE + top-K\ntool_preference (pwn_eval then shell)", fillcolor="#c4b5fd", fontsize=12, penwidth=2];
13
13
 
14
14
  subgraph cluster_ts {
15
15
  label="Toolsets"; fontcolor="#a7f3d0"; style=rounded;
@@ -1,6 +1,6 @@
1
1
  digraph "PWN_TaskSummarizer" {
2
2
  graph [
3
- label=<<B>PWN::AI::Agent::TaskSummarizer - Request kind + executive briefs</B><BR/><FONT POINT-SIZE="11" COLOR="#94a3b8">request_kind(statement|question: no plan) · (autonomous_goal: emit_plan! → about_to → tools)</FONT>>,
3
+ label=<<B>PWN::AI::Agent::TaskSummarizer - executive briefs</B><BR/><FONT POINT-SIZE="11" COLOR="#94a3b8">every request → emit_plan! → about_to → tools (no request type)</FONT>>,
4
4
  labelloc=t, fontsize=20, fontname="Helvetica",
5
5
  rankdir=TB, splines=spline, nodesep=0.55, ranksep=0.9,
6
6
  bgcolor="#0f172a", fontcolor="#e2e8f0", pad=0.6, newrank=true, compound=true
@@ -11,8 +11,8 @@ digraph "PWN_TaskSummarizer" {
11
11
  fontcolor="#cbd5e1", penwidth=1.3, arrowsize=0.8];
12
12
 
13
13
  User [label="User request", fillcolor="#7dd3fc"];
14
- Loop [label="Loop.run\nts_state = TaskSummarizer.fresh\nrequest_kind + request_intent", fillcolor="#c4b5fd"];
15
- Kind [label="request_kind (LLM + heuristic)\nstatement | question | autonomous_goal\nhost-evidence Qs → goal", fillcolor="#fcd34d", penwidth=2];
14
+ Loop [label="Loop.run\nts_state = TaskSummarizer.fresh\nrequest_intent only", fillcolor="#c4b5fd"];
15
+ Kind [label="no request type\nevery turn is a goal", fillcolor="#fcd34d", penwidth=2];
16
16
  {rank=same; User; Loop; Kind}
17
17
 
18
18
  subgraph cluster_nogoal {
@@ -126,19 +126,11 @@ full `Loop.run` under a persona overlay) that share a JSONL bus. See
126
126
  ## Task summaries (long autonomous turns)
127
127
 
128
128
  `PWN::AI::Agent::TaskSummarizer` keeps the TUI readable during multi-step work.
129
- First it classifies the request with `request_kind` (LLM when enabled, else
130
- heuristics / `request_intent`):
131
-
132
- | Kind | Example | Task breakdown |
133
- |---|---|---|
134
- | `statement` | "FYI the build is green." | None - brief ack only |
135
- | `question` | "what is the default GQRX port?" / "how to ...?" | None - concise answer only |
136
- | `autonomous_goal` | "refactor Loop.run and run rubocop" / "what is my hostname?" | **Required** ordered work units (each may use one or more tools) |
129
+ There is no request type. Every request gets an English task compass.
137
130
 
138
131
  | Surface | When | Content |
139
132
  |---|---|---|
140
- | `request_kind` | User submit | `statement` \| `question` \| `autonomous_goal` |
141
- | `emit_plan!` | Autonomous goals only | **Full** goal + ordered plain-English tangible tasks (each may need many tools) |
133
+ | `emit_plan!` | User submit | **Full** goal + ordered plain-English tangible tasks (each may need many tools) |
142
134
  | `about_to` | Before each tool batch | **Primary:** `task k/n: <english>` - **secondary:** `via shell×2 (search)` (not raw argv) |
143
135
  | `plan_context` / `active_task_prompt` | Into Loop messages | Same English tasks steer tool choice (not TUI-only) |
144
136
  | `record!` | After each tool | Advances `plan_idx`; emits English advancement brief when the index moves; verbose progress only if `task_summary_verbose` |
@@ -163,8 +155,7 @@ task_summary: true # master switch (default on)
163
155
  task_summary_every: 5 # verbose progress every N tools
164
156
  task_summary_interval_s: 8.0 # or every N seconds (verbose)
165
157
  task_summary_verbose: false # mid-flight Progress: lines
166
- task_summary_llm: true # LLM task decompose for autonomous goals (default on)
167
- request_kind_llm: null # null = follow task_summary_llm; false = heuristic-only
158
+ task_summary_llm: true # LLM task decompose (default on)
168
159
  max_iters: 75 # budget pressure may lower the effective cap (stricter on local engines)
169
160
  ```
170
161
 
@@ -206,7 +197,7 @@ max_iters: 75 # budget pressure may lower the effective cap (s
206
197
  | `reward_llm_timeout` | `12` | seconds for the cheap ORM chat (clamped 2..30) |
207
198
  | `verify_as_reward` | `nil` (auto) | browser-grounded claim sample policy |
208
199
  | `local_introspect` | `:failure_only` | ollama / openwebui end-of-turn introspect policy |
209
- | `tool_preference` | memory_recall-first list | Rank bonus + Policy suggested-action order |
200
+ | `tool_preference` | same list as CORE_TOOLS (`memory_recall`, `session_recall`, `skills_recall`, `pwn_eval`, `shell`) | Rank bonus + Policy suggested-action order |
210
201
  | `defer_introspect` | `true` | Post-answer Learning on a background thread |
211
202
  | `prompt_cache` | `true` | Engine-native prefix cache (not Ollama / Open WebUI) |
212
203
 
@@ -219,28 +210,18 @@ Full detail: [Reinforcement Learning](Reinforcement-Learning.md).
219
210
 
220
211
  [← Home](Home.md)
221
212
 
222
- ## Intent routing (kind + fine-grained intent)
223
-
224
- Every user turn is classified on two layers:
225
-
226
- 1. **`request_kind`** - `statement` | `question` | `autonomous_goal` (TaskSummarizer is the
227
- single source of truth; `Loop.request_kind` delegates). Classification order:
228
- injected label (tests) → cheap `request_intent` short-circuits (greeting/howto/recall/recon) →
229
- strong agent-do / host-evidence heuristics **LLM classify** via `chat_for_kind`
230
- (when `ai.agent.request_kind_llm` is on / follows `task_summary_llm`) offline
231
- `heuristic_request_kind`. Only autonomous goals receive a multi-step tangible-task plan.
232
- 2. **`request_intent`** - fine-grained route for cheap short-circuits and recon guard.
233
-
234
- | Intent | Kind | Example | Behavior |
235
- |--------|------|---------|----------|
236
- | 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. |
237
- | Question | question | "what is the default GQRX remote-control port?" | Concise answer. No multi-step task breakdown. |
238
- | 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. |
239
- | 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." |
240
- | Statement | statement | "FYI the build is green." | Brief note. No multi-step task plan. |
241
- | 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. |
242
- | 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. |
243
- | 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. |
213
+ ## Intent routing
214
+
215
+ There is no request type. Greeting / howto / recall still use `request_intent`
216
+ for cheap short-circuits. Everything else is a goal: TaskSummarizer compass + CORE_TOOLS.
217
+
218
+ | Intent | Example | Behavior |
219
+ |--------|---------|----------|
220
+ | How-to | "how to do a ping sweep of a subnet using hping3?" | Short explanation with example commands only. No tools. |
221
+ | Greeting | "Howdy, it's cloudy." / "hi" | Fixed short ack. No tools, no LLM, no weather echo. |
222
+ | Recall | "what did I just say?" / "how did you respond?" | Cheap prior-turn answer from the session transcript. |
223
+ | Live recon | "using hping3 what live hosts can you find in this subnet?" | Needs in-scope / authorized wording, or `ai.agent.recon_authorized=true`. |
224
+ | Goal | "refactor Loop.run and run rubocop" / "what color is a cherry" | Task compass + CORE_TOOLS. There is no statement/question type. |
244
225
 
245
226
  The `shell` tool also blocks hping3 / nmap-style sweep commands when recon is
246
227
  not authorized. On how-to asks, memory SOPs about repo rubocop/rake hygiene are