pwn 0.5.677 → 0.5.679

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/documentation/AI-Integration.md +4 -3
  4. data/documentation/Agent-Tool-Registry.md +27 -5
  5. data/documentation/CLI-Drivers.md +1 -1
  6. data/documentation/Configuration.md +65 -25
  7. data/documentation/Cron.md +12 -2
  8. data/documentation/Home.md +1 -1
  9. data/documentation/How-PWN-Works.md +1 -1
  10. data/documentation/Installation.md +12 -7
  11. data/documentation/Reinforcement-Learning.md +10 -6
  12. data/documentation/Skills-Memory-Learning.md +1 -1
  13. data/documentation/What-is-PWN.md +1 -1
  14. data/documentation/diagrams/agent-tool-registry.svg +156 -147
  15. data/documentation/diagrams/cron-scheduling.svg +149 -126
  16. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -1
  17. data/documentation/diagrams/dot/cron-scheduling.dot +6 -3
  18. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +1 -1
  19. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +14 -13
  20. data/documentation/pwn-REPL.md +1 -1
  21. data/documentation/pwn-ai-Agent.md +16 -9
  22. data/lib/pwn/ai/agent/policy.rb +9 -3
  23. data/lib/pwn/ai/agent/registry.rb +95 -6
  24. data/lib/pwn/ai/anthropic.rb +2 -6
  25. data/lib/pwn/ai/gemini.rb +2 -6
  26. data/lib/pwn/ai/grok.rb +7 -8
  27. data/lib/pwn/ai/ollama.rb +2 -6
  28. data/lib/pwn/ai/open_ai.rb +2 -6
  29. data/lib/pwn/ai/open_web_ui.rb +2 -6
  30. data/lib/pwn/blockchain/btc.rb +2 -6
  31. data/lib/pwn/blockchain/eth.rb +2 -6
  32. data/lib/pwn/config.rb +4 -3
  33. data/lib/pwn/plugins/black_duck_binary_analysis.rb +2 -4
  34. data/lib/pwn/plugins/jira_data_center.rb +2 -4
  35. data/lib/pwn/plugins/repl.rb +12 -6
  36. data/lib/pwn/plugins/tty_spinner.rb +75 -0
  37. data/lib/pwn/plugins.rb +1 -0
  38. data/lib/pwn/version.rb +1 -1
  39. data/spec/lib/pwn/ai/agent/registry_spec.rb +6 -0
  40. data/spec/lib/pwn/ai/grok_spec.rb +7 -0
  41. data/spec/lib/pwn/plugins/tty_spinner_spec.rb +61 -0
  42. data/third_party/pwn_rdoc.jsonl +8 -2
  43. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf1cf850ee77f4cc07bf307e7d26d68c882dd88e070874c066351c942d1fb727
4
- data.tar.gz: 33d594394b80414c16e6a1bc5c058848067e3c5ceb6e34766635e1b9ef3e5ed7
3
+ metadata.gz: 81490e3fc28a7f1e743e069075ce57da65f4a54548b47f72d7467d22fab64432
4
+ data.tar.gz: f77147d5e3bb6b53d994ff7f7af3c21e260a7659a60cda70b599fec1c565176d
5
5
  SHA512:
6
- metadata.gz: e9872bba2acd8bbf95d876b530eab372b115d2a15195a671e557aa1a9cd666d8ae44a95ec706709824ab211f47a8dfac6573d9f909b3ec08dc803517287db6e8
7
- data.tar.gz: cdf382e873b520457023d00b0c0b33fad8810549b5598714ce8dcadff653aa28b0b250af72a36628e5b46dce7827b4f84f1b34959e7037539cb80b96e2a011ee
6
+ metadata.gz: d034c13085bdeffac43c2ded717317a7dc70dce6cb72d828f7879ba4847abf26fcc4258820551e4410b2d571ad925ccd49843aa2cd94ee3add1c0071412b6e6c
7
+ data.tar.gz: 4901e7063ec2fc27ffd60349a5f6681a46d7bea30baf3c70f1d03c3cb53903e0face0946c558ad2dbd82358864f6f29d2d06cb04f0ae7c40cd3360cf5ffe6986
data/README.md CHANGED
@@ -97,7 +97,7 @@ small and easy to swap:
97
97
 
98
98
  On every turn the AI layer runs a **feedback loop**. It checks inward
99
99
  (Metrics, Learning, **Mistakes**, and **Policy**: what failed last time, and
100
- which tool the live Q / REINFORCE table currently prefers) and outward
100
+ which tool the live Q / REINFORCE table plus `tool_preference` currently prefers) and outward
101
101
  (Snapshot, Drift, Intel, RF, and **Web**: did the host or network change?).
102
102
  Live checks use browser-backed **`extro_verify`** / **`extro_watch`** and RF
103
103
  **`extro_rf_tune`**. `extro_correlate` joins those views so the agent can tell
@@ -162,7 +162,7 @@ PWN is a **single gem** with a built-in post-install doctor/provisioner -
162
162
  `PWN::` capability needs. Tested on Kali/Debian/Ubuntu, Fedora, Arch, macOS.
163
163
 
164
164
  ```
165
- $ gem install pwn
165
+ $ gem install --verbose pwn
166
166
  $ pwn setup # read-only doctor: which capabilities are usable?
167
167
  $ pwn setup --profile full --yes # provision everything (or: web | net | sdr | vision | ...)
168
168
  $ pwn
@@ -14,7 +14,7 @@ agent code never cares which model is behind it.
14
14
  | `anthropic` | `PWN::AI::Anthropic` | `key:` | tool-use native |
15
15
  | `grok` | `PWN::AI::Grok` | `key:` **or** `oauth: true` | OAuth = RFC-8628 device-code flow using xAI's public Grok-CLI client id (no secret) - see skill `xai_grok_oauth_device_flow` |
16
16
  | `gemini` | `PWN::AI::Gemini` | `key:` | function-calling native |
17
- | `ollama` | `PWN::AI::Ollama` | none | local - native `/api/chat` (`num_ctx`, `keep_alive`, low-temp + `format:'json'` on tool turns) and `/api/embed` for `PWN::MemoryIndex` |
17
+ | `ollama` | `PWN::AI::Ollama` | none (stock) | Direct Ollama server (default `http://127.0.0.1:11434`). Native `/api/chat` (`num_ctx`, `num_predict`, `keep_alive`, low `tool_temp`) and `/api/embed` for `PWN::MemoryIndex`. No prefix-cache field. |
18
18
  | `openwebui` | `PWN::AI::OpenWebUI` | `key:` (JWT / API token) + `base_uri:` | Open WebUI gateway - OpenAI-compatible `/api/v1/chat/completions` plus proxied Ollama `/ollama/api/*` (including embed) |
19
19
 
20
20
  > PWN is **model-agnostic**. `ai.<engine>.model` is passed straight through to
@@ -46,13 +46,14 @@ The harness adapts to the *class* of engine, not the model name:
46
46
  |---|---|---|
47
47
  | **PromptBuilder.budget** | full MEMORY / METRICS / MISTAKES / LEARNING / EXTRO blocks | tightened via `ai.ollama.prompt_budget` (extro off by default) |
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
- | **Tool schemas shipped** | all toolsets | `CORE_TOOLS` + top-K keyword matches when `ai.agent.tool_router` is on |
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
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 |
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
- | **Post-answer** | `auto_introspect` | `auto_introspect` **+** `fact_check_local_final` (auto `extro_verify` on CVE/version-shaped claims) |
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. |
55
55
  | **Metrics bucket** | `metrics.json[:tools][name][:engines][:<engine>]` | same - the `TOOL EFFECTIVENESS` block is per-engine so local telemetry never blends with frontier |
56
+ | **Prefix cache** | Anthropic `cache_control` · OpenAI `prompt_cache_key` · Grok `x-grok-conv-id` · Gemini `systemInstruction` split (`ai.agent.prompt_cache`, default on) | none - Ollama / Open WebUI have no prefix-cache request field |
56
57
 
57
58
  ## Teacher-student reflection
58
59
 
@@ -59,18 +59,40 @@ pool to:
59
59
  CORE_TOOLS = shell · pwn_eval · memory_remember · memory_recall
60
60
  mistakes_record · mistakes_resolve · learning_note_outcome
61
61
  + top-K keyword-ranked matches for THIS request
62
- (ties break on Metrics per-engine success_rate → the router
63
- itself is a learned component)
62
+ (ties break on Metrics per-engine success_rate, then
63
+ ai.agent.tool_preference)
64
64
  ```
65
65
 
66
66
  ```ruby
67
67
  PWN::AI::Agent::Registry.definitions(relevance: 'nmap sweep 10.0.0.0/8', top_k: 10)
68
68
  PWN::AI::Agent::Registry.rank(query: 'run a shell command') # inspect ranking
69
- PWN::AI::Agent::Registry.toolsets # the 13 names above
70
- PWN::AI::Agent::Registry.all.count # 85
69
+ PWN::AI::Agent::Registry.preference_order # Env / DEFAULT_PREFERENCE
70
+ PWN::AI::Agent::Registry.toolsets # -> the 13 names above
71
+ PWN::AI::Agent::Registry.all.count # -> 85
71
72
  ```
72
73
 
73
- Frontier engines leave `tool_router` off and receive the full set.
74
+ Frontier engines leave `tool_router` off (unless you set it) and receive the
75
+ full set. Local engines (`ollama` / `openwebui`) default `tool_router` to on.
76
+
77
+ ## Tool preference (`ai.agent.tool_preference`)
78
+
79
+ When keyword fit and other rank scores tie, the registry prefers this
80
+ default order:
81
+
82
+ ```text
83
+ memory_recall · sessions_view · pwn_eval · shell
84
+ mistakes_record · mistakes_resolve · learning_note_outcome · memory_remember
85
+ ```
86
+
87
+ Set `ai.agent.tool_preference` in `~/.pwn/pwn.yaml`, or pass `order:` /
88
+ `preference:` into `Registry.definitions`, `.rank`, or `.apply_preference`.
89
+ An explicit empty list turns preference off (no Env / default fallback).
90
+
91
+ 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.
94
+
95
+ `Policy` uses the same list when it suggests a next action in the prompt.
74
96
 
75
97
  ## Adding a tool
76
98
 
@@ -43,7 +43,7 @@ Run any with `--help` for its flags.
43
43
 
44
44
  ## `pwn_setup` - post-install doctor / provisioner / state migrator
45
45
 
46
- The one driver that isn't a plugin wrapper. It grows a bare `gem install pwn`
46
+ The one driver that isn't a plugin wrapper. It grows a bare `gem install --verbose pwn`
47
47
  into a fully-armed host by installing OS headers / external tools for whatever
48
48
  capability profile you ask for, **and** verifies/repairs every persisted
49
49
  `~/.pwn` state file after an upgrade. Also reachable as `pwn setup` and
@@ -8,8 +8,10 @@ frozen constant **`PWN::Env`** (a redacted copy is available as
8
8
  The file is **AES-encrypted at rest** by `PWN::Plugins::Vault`. Its key/IV
9
9
  live in a sibling **`~/.pwn/pwn.yaml.decryptor`** file (or in
10
10
  `PWN_DECRYPTOR_KEY` / `PWN_DECRYPTOR_IV` env vars). Never edit `pwn.yaml`
11
- by hand - use the **`pwn-vault`** REPL command, which decrypts opens
12
- `$EDITOR` re-encrypts reloads `PWN::Env`.
11
+ by hand - use the **`pwn-vault`** REPL command, which decrypts, opens
12
+ `$EDITOR`, re-encrypts, and reloads `PWN::Env`. If `PWN::Config` rejects the
13
+ edited file, the editor reopens until the vault loads cleanly, so you do not
14
+ leave the REPL stuck on a decrypt / re-edit / encrypt loop.
13
15
 
14
16
  If `~/.pwn/pwn.yaml` does not exist on first run, `PWN::Config.default_env`
15
17
  writes a fully-commented template with every key below (values set to
@@ -32,7 +34,7 @@ generates the decryptor.
32
34
  # ~/.pwn/pwn.yaml (shown DECRYPTED - file is AES-encrypted on disk)
33
35
 
34
36
  ai:
35
- active: grok # Which engine backs `pwn-ai`. One of: openai | anthropic | grok | gemini | ollama.
37
+ active: grok # Which engine backs `pwn-ai`. One of: openai | anthropic | grok | gemini | ollama | openwebui.
36
38
  module_reflection: false # Master gate for LLM self-analysis (SAST triage, Burp enrichment, Learning.llm_reflect).
37
39
 
38
40
  grok:
@@ -78,14 +80,17 @@ ai:
78
80
  max_prompt_length: 1000000 # Soft input-context ceiling (chars) - Gemini supports very large contexts.
79
81
 
80
82
  ollama:
81
- base_uri: https://ollama.local # REQUIRED for ollama - Open WebUI / ollama-serve base URL (no vendor default).
82
- key: eyJ... # Open WebUI JWT (Settings Account API Key). Prompted if blank.
83
+ base_uri: http://127.0.0.1:11434 # Direct Ollama server. Optional; this is the stock default. No vendor key.
84
+ key: ~ # Only if a reverse-proxy sits in front of Ollama. Stock ollama needs none.
83
85
  model: <local-model-tag> # Local model tag exactly as `ollama list` shows it.
84
- embed_model: <embed-model-tag> # Embedding model for PWN::MemoryIndex (relevance-ranked MEMORY). Must be pulled locally.
86
+ embed_model: nomic-embed-text # Embedding model for PWN::MemoryIndex (relevance-ranked MEMORY). Must be pulled locally.
85
87
  system_role_content: 'You are an ethically hacking Ollama agent.' # Base system prompt for this engine.
86
88
  temp: 1.0 # Sampling temperature (used on the FINAL text-only turn - tool-bearing turns are pinned low for deterministic routing).
89
+ tool_temp: 0.1 # Lower temperature on tool-bearing turns for stable routing.
87
90
  num_ctx: 32768 # Context window passed to /api/chat options.num_ctx. Ollama's default (2048) is too small for the pwn-ai system prompt.
91
+ num_predict: 4096 # Decode-length cap so a thinking model cannot stream forever.
88
92
  keep_alive: 30m # How long ollama keeps the model resident between iterations (avoids reload latency mid-turn).
93
+ result_max: 4000 # Tool-result cap for local models (frontier keeps Result::DEFAULT_MAX).
89
94
  prompt_budget: # Per-block caps applied by PromptBuilder.budget so a small model spends attention on the request, not the harness.
90
95
  memory: 6 # Max MEMORY entries injected (relevance-ranked via PWN::MemoryIndex when available).
91
96
  metrics: 3 # Max TOOL EFFECTIVENESS rows.
@@ -94,11 +99,26 @@ ai:
94
99
  extro: false # Gate the (heaviest) EXTROSPECTION block entirely for local models.
95
100
  max_prompt_length: 32000 # Soft input-context ceiling (chars) - tune per local model's real context window.
96
101
 
102
+ openwebui:
103
+ base_uri: https://openwebui.local # REQUIRED - Open WebUI gateway (separate provider from ollama).
104
+ key: eyJ... # REQUIRED - Open WebUI JWT (Settings -> Account -> API Key).
105
+ model: <model-id-or-tag> # Model id / tag Open WebUI exposes.
106
+ embed_model: nomic-embed-text # Used when a direct ollama embed_model is unset.
107
+ system_role_content: 'You are an ethically hacking Open WebUI agent.'
108
+ temp: 1.0
109
+ tool_temp: 0.1
110
+ num_ctx: 32768
111
+ num_predict: 4096
112
+ keep_alive: 30m
113
+ result_max: 4000
114
+ prompt_budget: { memory: 6, metrics: 3, mistakes: 3, learning: 2, extro: false }
115
+ max_prompt_length: 32000
116
+
97
117
  reflect_engine: ~ # Teacher-student reflection: EXECUTE on ai.active, but write durable lessons via THIS engine (nil = same as active). Lets a local model act while a frontier model authors the Memory :lesson entries it reads back.
98
118
 
99
119
  agent:
100
120
  native_tools: true # Use provider-native tool_calls / function-calling. false → legacy text-parsed tool protocol.
101
- max_iters: 25 # Hard cap on tool-call rounds per user turn before a forced final answer.
121
+ max_iters: 75 # Hard cap on tool-call rounds per user turn. Local engines tighten under budget pressure.
102
122
  task_summary: true # Executive task briefs via TaskSummarizer (plan + about_to). false disables.
103
123
  task_summary_every: 5 # When task_summary_verbose: emit Progress every N completed tools.
104
124
  task_summary_interval_s: 8.0 # When verbose: also emit when this many seconds elapsed.
@@ -107,12 +127,24 @@ ai:
107
127
  request_kind_llm: ~ # LLM request_kind classifier (statement|question|autonomous_goal). nil = follow task_summary_llm.
108
128
  max_depth: 3 # Recursion guard: how many levels deep agent_ask/agent_debate sub-agents may spawn sub-agents.
109
129
  auto_introspect: true # Run Learning.auto_introspect (outcome logging + lesson mining) after every final answer.
110
- auto_extrospect: false # Optional ambient baseline (host/repo/env ONLY - never launches burpsuite/zaproxy/msf/gqrx). Sense tools (intel/verify/watch/rf_tune/observe) stay on-demand.
130
+ auto_extrospect: true # Ambient baseline after every final answer (host/repo/env ONLY - never launches burpsuite/zaproxy/msf/gqrx). Sense tools stay on-demand.
131
+ defer_introspect: true # Run auto_introspect on a background thread AFTER the user-visible reply (default on). Specs/cron stay inline.
132
+ prompt_cache: true # Engine-native prefix cache. Anthropic cache_control, OpenAI prompt_cache_key, Grok x-grok-conv-id, Gemini systemInstruction split. Ollama / Open WebUI have none.
111
133
  recon_authorized: false # Allow live subnet sweeps / raw-socket discovery tools this session
112
- shell_bash: false # true run shell via bash -lc (PIPESTATUS, [[ ]], process substitution). Default is /bin/sh.
113
- plan_first: ~ # Plan-then-act pre-pass: force the model to externalize a numbered tool plan BEFORE its first dispatch. nil = auto (true when ai.active == ollama).
114
- tool_router: false # Dynamic tool-set slimming: ship only Registry::CORE_TOOLS + top-K keyword-relevant schemas per turn (helps small models route correctly).
115
- escalation_persona: ~ # Swarm persona name to ask for a 3-line corrective hint once a local model burns ≥ Loop::ESCALATE_AFTER_FAILS in-turn failures. nil = disabled.
134
+ shell_bash: false # true -> run shell via bash -lc. Default is /bin/sh.
135
+ plan_first: ~ # Plan-then-act pre-pass. nil = auto (true when ai.active is ollama or openwebui).
136
+ 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.
138
+ - memory_recall
139
+ - sessions_view
140
+ - pwn_eval
141
+ - shell
142
+ - mistakes_record
143
+ - mistakes_resolve
144
+ - learning_note_outcome
145
+ - memory_remember
146
+ escalation_persona: escalator # Swarm persona for a 3-line corrective hint after enough in-turn failures. nil = disabled.
147
+ local_introspect: failure_only # End-of-turn auto_introspect policy for local engines: always | failure_only | every_n.
116
148
  policy: true # Live tabular Q / REINFORCE. Advisory only; never replaces TaskSummarizer / plan_first. false disables.
117
149
  toolsets: ~ # Allow-list of toolsets exposed to the agent. nil = all. Valid: cron, curriculum, extrospection, learning, memory, metrics, policy, pwn, reward, sessions, skills, swarm, terminal.
118
150
  extrospection:
@@ -221,7 +253,7 @@ targets: # Optional - engagement-scope URLs/hosts. Mer
221
253
 
222
254
  ```ruby
223
255
  PWN::Env[:ai][:active] # => :grok
224
- PWN::Env.dig(:ai, :agent, :max_iters) # => 25
256
+ PWN::Env.dig(:ai, :agent, :max_iters) # => 75
225
257
  PWN::EnvRedacted[:ai][:grok][:key] # => ">>> REDACTED >>> ..."
226
258
 
227
259
  # Edit + re-encrypt + reload without leaving the REPL:
@@ -239,10 +271,10 @@ PWN::Config.refresh_env
239
271
 
240
272
  | Key path | Type | Default | Consumed by | Purpose |
241
273
  |---|---|---|---|---|
242
- | `ai.active` | String | `grok` | `PWN::Config.refresh_env`, `PWN::AI::Agent::Loop`, `PWN::Plugins::REPL`, `PWN::Cron` | Which AI engine backs `pwn-ai`. One of `openai` · `anthropic` · `grok` · `gemini` · `ollama`. |
274
+ | `ai.active` | String | `grok` | `PWN::Config.refresh_env`, `PWN::AI::Agent::Loop`, `PWN::Plugins::REPL`, `PWN::Cron` | Which AI engine backs `pwn-ai`. One of `openai` · `anthropic` · `grok` · `gemini` · `ollama` · `openwebui`. |
243
275
  | `ai.module_reflection` | Boolean | `false` | `PWN::AI::Agent::Reflect`, `PWN::SAST::*`, `PWN::Plugins::BurpSuite` | Master gate for LLM-driven self-analysis (SAST triage, Burp finding enrichment, `Learning.llm_reflect`). |
244
- | `ai.<engine>.base_uri` | String | provider default | `PWN::AI::<Engine>.rest_call` | Override the API base URL (self-hosted proxy, private endpoint, Azure/VPC gateway). **Required** for `ollama`. |
245
- | `ai.<engine>.key` | String | - | `PWN::AI::<Engine>` | API key / bearer token. If blank AND no OAuth is configured, PWN prompts interactively at load. |
276
+ | `ai.<engine>.base_uri` | String | provider default | `PWN::AI::<Engine>.rest_call` | Override the API base URL (self-hosted proxy, private endpoint, Azure/VPC gateway). Optional for stock `ollama` (`http://127.0.0.1:11434`). **Required** for `openwebui`. |
277
+ | `ai.<engine>.key` | String | - | `PWN::AI::<Engine>` | API key / bearer token. Stock `ollama` needs none. `openwebui` requires a JWT. If blank AND no OAuth is configured on a key-backed engine, PWN prompts interactively at load. |
246
278
  | `ai.<engine>.model` | String | provider default | `PWN::AI::<Engine>.chat` / `.chat_tool_loop` | Model id sent on every request. Use whatever id the provider / `ollama list` currently exposes - PWN never hard-codes a specific model. |
247
279
  | `ai.<engine>.system_role_content` | String | ethical-hacker persona | `PWN::AI::Agent::PromptBuilder`, `PWN::Plugins::REPL` | Base system prompt prepended to MEMORY / SKILLS / LEARNING / EXTROSPECTION blocks. |
248
280
  | `ai.<engine>.temp` | Float | `1.0` | `PWN::AI::<Engine>.chat` | Sampling temperature. |
@@ -252,6 +284,10 @@ PWN::Config.refresh_env
252
284
  | `ai.ollama.embed_model` | String | provider default | `PWN::MemoryIndex` | Local embedding model tag used to build `~/.pwn/memory.idx` for **relevance-ranked** MEMORY injection. Falls back to substring recall when unset / unreachable. |
253
285
  | `ai.ollama.num_ctx` | Integer | `32768` | `PWN::AI::Ollama.chat_with_tools` | Context window sent as `options.num_ctx` on the native `/api/chat` call. Ollama's own default (2048) truncates the pwn-ai system prompt. |
254
286
  | `ai.ollama.keep_alive` | String | `30m` | `PWN::AI::Ollama.chat_with_tools` | How long the model stays resident in ollama between iterations of a single turn. |
287
+ | `ai.ollama.num_predict` | Integer | `4096` | `PWN::AI::Ollama.chat_with_tools` | Decode-length cap so a thinking model cannot stream forever. |
288
+ | `ai.ollama.tool_temp` | Float | `0.1` | `PWN::AI::Ollama.chat_with_tools` | Sampling temperature on tool-bearing turns (final text-only turn uses `temp`). |
289
+ | `ai.ollama.result_max` | Integer | `4000` | `PWN::AI::Agent::Result` | Tool-result cap for local models. |
290
+ | `ai.openwebui.*` | (same shape as `ollama`) | JWT + `base_uri` required | `PWN::AI::OpenWebUI` | Separate provider from `ollama`. OpenAI-compatible `/api/v1/chat/completions` plus proxied `/ollama/api/*` (including embed). |
255
291
  | `ai.ollama.prompt_budget` | Hash | `{memory:6, metrics:3, mistakes:3, learning:2, extro:false}` | `PWN::AI::Agent::PromptBuilder.budget` | Per-block caps on injected context so a small local model spends its attention on the request, not the harness. Any engine may set this. |
256
292
  | `ai.reflect_engine` | Symbol \| `nil` | `nil` (= `ai.active`) | `PWN::AI::Agent::Reflect.on`, `Learning.reflect` | **Teacher-student** override: run the task on `ai.active`, but generate durable lessons via *this* engine. Lets a local model execute while a frontier model writes the Memory it reads back. |
257
293
  | `ai.grok.oauth.refresh_token` | String | - | `PWN::AI::Grok.resolve_auth` | Durable OAuth refresh token (from `PWN::AI::Grok.obtain_oauth_bearer_token` device flow). Enables silent re-auth without an API key. |
@@ -267,7 +303,7 @@ PWN::Config.refresh_env
267
303
  | Key path | Type | Default | Consumed by | Purpose |
268
304
  |---|---|---|---|---|
269
305
  | `ai.agent.native_tools` | Boolean | `true` | `PWN::Plugins::REPL` (`pwn-ai` cmd) | Use provider-native `tool_calls` / function-calling. `false` falls back to the legacy text-parsed tool protocol. |
270
- | `ai.agent.max_iters` | Integer | `25` | `PWN::AI::Agent::Loop.run`, `PWN::AI::Agent::Swarm` | Hard cap on tool-call rounds per user turn before a forced final answer. When budget-exhaustion pressure is high, the effective cap is tightened (stricter on local/ollama than remote) so long multi-step goals keep a usable runway without thrashing. |
306
+ | `ai.agent.max_iters` | Integer | `75` | `PWN::AI::Agent::Loop.run`, `PWN::AI::Agent::Swarm` | Hard cap on tool-call rounds per user turn before a forced final answer. When recent turns keep hitting the ceiling, the effective cap is tightened (stricter on local engines than remote) so long multi-step goals keep a usable runway without thrashing. |
271
307
  | `ai.agent.task_summary` | Boolean | `true` | `PWN::AI::Agent::TaskSummarizer`, `Loop` | Master switch for executive task briefs (`emit_plan!` / `about_to`). |
272
308
  | `ai.agent.task_summary_every` | Integer | `5` | `TaskSummarizer.every_n` | Verbose progress cadence (tools). |
273
309
  | `ai.agent.task_summary_interval_s` | Float | `8.0` | `TaskSummarizer.interval_s` | Verbose progress cadence (seconds). |
@@ -276,22 +312,26 @@ PWN::Config.refresh_env
276
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. |
277
313
  | `ai.agent.max_depth` | Integer | `3` | `PWN::AI::Agent::Swarm` | Recursion guard for `agent_ask` / `agent_debate` sub-agents spawning sub-agents. |
278
314
  | `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`. |
279
- | `ai.agent.auto_extrospect` | Boolean | `false` | `PWN::AI::Agent::Extrospection.auto_extrospect` | Optional ambient baseline after every final answer (`AUTO_SECTIONS` = host/repo/env only; never spawns GUI/JVM tools). Prefer on-demand sense tools (`intel`/`verify`/`watch`/`rf_tune`/`observe`). Toggle live via `extro_auto_toggle`. |
315
+ | `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`. |
280
316
  | `ai.agent.toolsets` | Array\<String\> \| `nil` | `nil` (all) | `bin/pwn`, `PWN::Plugins::REPL`, `PWN::AI::Agent::Registry` | Allow-list of toolsets exposed to the agent. Valid: `cron`, `curriculum`, `extrospection`, `learning`, `memory`, `metrics`, `policy`, `pwn`, `reward`, `sessions`, `skills`, `swarm`, `terminal`. |
281
317
  | `ai.agent.recon_authorized` | Boolean | `false` | `PWN::AI::Agent::ToolGuard.recon_authorized?` / `Loop.recon_authorized?` | When true (or the user request contains in-scope / engagement language), live host-discovery tools may run. Default refuses unauthorized sweeps. |
282
318
  | `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. |
283
- | `ai.agent.plan_first` | Boolean \| `nil` | `nil` (auto: `true` when `ai.active == ollama`) | `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. |
284
- | `ai.agent.tool_router` | Boolean | `false` | `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 so the router itself is a learned component. |
285
- | `ai.agent.escalation_persona` | String \| `nil` | `nil` | `PWN::AI::Agent::Loop.escalate` `Swarm.ask` | Circuit-breaker: once a local model accumulates `Loop::ESCALATE_AFTER_FAILS` in-turn failures, ask this Swarm persona for a 3-line corrective hint (injected as a synthetic tool result). The local model still authors the final answer so Learning/Metrics stay attributed. |
286
- | `ai.agent.critic` | Boolean | `false` | `PWN::AI::Agent::Curriculum.critic` | Tool-armed constitutional self-critic reviews (and may `shell`/`extro_verify`) every final answer before it is returned. |
287
- | `ai.agent.red_team_plan` | Boolean | `false` | `PWN::AI::Agent::Curriculum.red_team_plan` | Adversarial review of the `plan_first` numbered plan, grounded in Metrics/Mistakes/`extro_drift` telemetry, before the first dispatch. |
288
- | `ai.agent.counterfactual` | Boolean | `false` | `PWN::AI::Agent::Curriculum.counterfactual` | On `[REPEATING]`, fork an alt-persona branch, judge both, and record the `(loser, winner)` DPO preference pair. |
319
+ | `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
+ | `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. |
322
+ | `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
+ | `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
+ | `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`). |
325
+ | `ai.agent.escalation_persona` | String \| `nil` | `escalator` | `PWN::AI::Agent::Loop.escalate` -> `Swarm.ask` | Circuit-breaker: once a local model accumulates enough in-turn failures, ask this Swarm persona for a 3-line corrective hint (injected as a synthetic tool result). The local model still authors the final answer so Learning/Metrics stay attributed. |
326
+ | `ai.agent.critic` | Boolean \| `nil` | `nil` (auto: on for remote, off for ollama) | `PWN::AI::Agent::Curriculum.critic` | Tool-armed constitutional self-critic reviews (and may `shell`/`extro_verify`) every final answer before it is returned. |
327
+ | `ai.agent.red_team_plan` | Boolean \| `nil` | `nil` (auto: on for remote, off for ollama) | `PWN::AI::Agent::Curriculum.red_team_plan` | Adversarial review of the `plan_first` numbered plan, grounded in Metrics/Mistakes/`extro_drift` telemetry, before the first dispatch. |
328
+ | `ai.agent.counterfactual` | Boolean \| `nil` | `nil` (auto: on for remote, off for ollama) | `PWN::AI::Agent::Curriculum.counterfactual` | On `[REPEATING]`, fork an alt-persona branch, judge both, and record the `(loser, winner)` DPO preference pair. |
289
329
  | `ai.agent.hindsight` | Boolean | `true` | `PWN::AI::Agent::Curriculum.hindsight` | Hindsight Experience Replay - relabel a failed trajectory as `success:true` for whatever it *did* accomplish. Free positive samples from failures. |
290
330
  | `ai.agent.policy` | Boolean | `true` | `PWN::AI::Agent::Policy` | Live tabular Q-learning + REINFORCE. Records `(s,a,r,s')` per tool step, trains on `Reward.judge` at episode end, and adds a small Q-advantage term to `Registry.rank`. Advisory only: never replaces TaskSummarizer or plan_first. |
291
331
  | `ai.agent.reward_llm` | Boolean \| `nil` | `nil` (auto: on for remote, off for ollama) | `PWN::AI::Agent::Reward.judge` / `.prm` | Use a cheap LLM teacher for outcome/process judges even when `module_reflection` is false. Local ollama stays heuristic unless this is `true`. |
292
332
  | `ai.agent.reward_model` | String \| `nil` | `nil` | `Reward.judge` / `.prm` | Optional cheaper model id for the ORM/PRM chat. Falls back to `ai.reflect_model`, then the active engine default. |
293
333
  | `ai.agent.reward_llm_timeout` | Integer | `12` | `Reward.judge` / `.prm` | Seconds for the cheap ORM chat (clamped 2..30). Fail fast to the overlap heuristic rather than a 900s hang. |
294
- | `ai.agent.verify_as_reward` | Boolean | `false` | `PWN::AI::Agent::Reward.verify_as_reward` | Ground the LLM judge score by browser-verifying any checkable claim in the final via `extro_verify`; verdict caps/floors `Reward.judge`. |
334
+ | `ai.agent.verify_as_reward` | Boolean \| `nil` | `nil` (auto: ~10% local / always frontier when a claim matches) | `PWN::AI::Agent::Reward.verify_as_reward` | Ground the LLM judge score by browser-verifying any checkable claim in the final via `extro_verify`; verdict caps/floors `Reward.judge`. |
295
335
  | `ai.agent.extrospection.web.anchors` | Array\<String\> | `DEFAULT_WEB_ANCHORS` | `PWN::AI::Agent::Extrospection.probe_web` | URLs the headless browser fingerprints on `extro_snapshot(sections:[:web])`. Alias: `web_anchors`. |
296
336
  | `ai.agent.extrospection.web.proxy` | String | - | `Extrospection.probe_web` / `.verify` / `.watch` | Upstream proxy for `PWN::Plugins::TransparentBrowser` (e.g. `tor`, `http://127.0.0.1:8080`). |
297
337
  | `ai.agent.extrospection.web.max_anchors` | Integer | `8` | `Extrospection.probe_web` | Cap on anchors rendered per snapshot. |
@@ -1,8 +1,18 @@
1
1
  # Cron - Scheduled Autonomous Jobs
2
2
 
3
3
  `PWN::Cron` (`lib/pwn/cron.rb`) stores job definitions in
4
- `~/.pwn/cron/jobs.yml` and can install a matching system-`crontab` line that
5
- invokes `PWN::Cron.run(<id>)` on schedule.
4
+ `~/.pwn/cron/jobs.yml`. `pwn setup` starts (or reuses) a background cron
5
+ worker and installs an OS-native keep-alive so YAML jobs fire on schedule
6
+ without a per-job crontab line:
7
+
8
+ - Linux: `systemd --user` (Restart=always), else `crontab @reboot`
9
+ - macOS: `launchd`
10
+ - Windows: `schtasks`
11
+ - otherwise: `crontab @reboot` when `crontab(1)` exists
12
+
13
+ You can still pass `install_crontab: true` on `cron_create` to add a
14
+ per-job system line. `PWN::Cron.install_worker_crontab` is idempotent and
15
+ does not remove existing per-job lines.
6
16
 
7
17
  ![Cron scheduling](diagrams/cron-scheduling.svg)
8
18
 
@@ -17,7 +17,7 @@
17
17
  | [What is PWN](What-is-PWN.md) | One-paragraph elevator pitch |
18
18
  | [Why PWN](Why-PWN.md) | Design philosophy - why another framework |
19
19
  | [How PWN Works](How-PWN-Works.md) | The five layers, with the architecture diagram |
20
- | [Installation](Installation.md) | `gem install pwn` → `pwn setup` doctor/provisioner · capability profiles · `--migrate` state doctor |
20
+ | [Installation](Installation.md) | `gem install --verbose pwn` → `pwn setup` doctor/provisioner · capability profiles · `--migrate` state doctor |
21
21
  | [General Usage](General-PWN-Usage.md) | Day-one cheat sheet |
22
22
  | [Configuration](Configuration.md) | `~/.pwn/pwn.yaml` (encrypted) - engines, keys, agent options · `pwn-vault` |
23
23
  | **[All Data-Flow Diagrams](Diagrams.md)** | **29 SVGs** in one scrollable page |
@@ -29,7 +29,7 @@ hardware).
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
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** |
32
+ | `Registry` | JSON-Schema function definitions grouped into 13 **toolsets** · **85 tools** · `tool_preference` order (default memory_recall-first) |
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) |
@@ -5,7 +5,7 @@ a plugin whose native extension or OS binary is missing costs nothing until
5
5
  you actually touch that constant. That means the install is **two steps**:
6
6
 
7
7
  ```bash
8
- gem install pwn # 1. get the gem (pure-Ruby core always works)
8
+ gem install --verbose pwn # 1. get the gem (pure-Ruby core always works)
9
9
  pwn setup # 2. doctor + provision this host's capabilities
10
10
  ```
11
11
 
@@ -24,7 +24,7 @@ Tested on **Kali / Debian / Ubuntu**, **Fedora**, **Arch**, and **macOS**
24
24
  ## Quick install (recommended)
25
25
 
26
26
  ```bash
27
- gem install pwn
27
+ gem install --verbose pwn
28
28
  pwn setup # read-only doctor: what's usable, what's missing
29
29
  pwn setup --profile full --yes # install everything for every PWN:: namespace
30
30
  pwn # launch the REPL
@@ -82,6 +82,8 @@ External toolchain used by
82
82
  skills/ drift 1 legacy flat file(s) PWN::Config → run --migrate --fix
83
83
  ...
84
84
 
85
+ cron worker ok systemd --user pid=...
86
+
85
87
  31 / 36 capabilities usable · 5 degraded
86
88
 
87
89
  Run `pwn setup --deps` to install missing OS headers/tools, or
@@ -103,7 +105,7 @@ pwn setup --list-profiles
103
105
  1. Resolve the profile → set of native gems + external binaries.
104
106
  2. Map those to OS packages for **your** package manager (data lives in
105
107
  `PWN::Setup::NATIVE_GEMS` / `::TOOLCHAIN` - versioned with the gem, so
106
- `gem install pwn`, git checkout, Docker, Packer and Vagrant all read the
108
+ `gem install --verbose pwn`, git checkout, Docker, Packer and Vagrant all read the
107
109
  same table).
108
110
  3. Show the exact commands, prompt (unless `--yes`), run them, then
109
111
  `gem pristine` / `gem install` any native extension that still fails to
@@ -187,9 +189,12 @@ predates the running gem (`PWN::Migrate.needed?`).
187
189
 
188
190
  Schema `v1` also seeds `PWN::Cron.install_defaults` - the nightly
189
191
  `curriculum_practice` and weekly `curriculum_train` self-improvement jobs
190
- (see [Reinforcement Learning](Reinforcement-Learning.md)). Live Policy
191
- files (`policy.json`, `policy_traj.jsonl`) are created on first agent turn
192
- when `ai.agent.policy` is on.
192
+ (see [Reinforcement Learning](Reinforcement-Learning.md)). `pwn setup`
193
+ also starts the background cron worker and persists it via the OS scheduler
194
+ (systemd --user / launchd / schtasks / crontab) so those YAML jobs run
195
+ without a per-job crontab line. Live Policy files (`policy.json`,
196
+ `policy_traj.jsonl`) are created on first agent turn when `ai.agent.policy`
197
+ is on.
193
198
 
194
199
  From a checkout:
195
200
 
@@ -221,7 +226,7 @@ lists have been consolidated into `PWN::Setup::NATIVE_GEMS` / `::TOOLCHAIN`.
221
226
 
222
227
  ```dockerfile
223
228
  FROM kalilinux/kali-rolling
224
- RUN gem install pwn && pwn setup --profile full --yes
229
+ RUN gem install --verbose pwn && pwn setup --profile full --yes
225
230
  ```
226
231
 
227
232
  ```yaml
@@ -30,7 +30,7 @@ improvement does not wait on weights.
30
30
  |
31
31
  Learning.consolidate (M1 merge, M3 importance-evict)
32
32
  MemoryIndex.recall_semantic (M2 similarity x recency x importance)
33
- Registry.rank (C1 keyword + UCB + Q-advantage)
33
+ Registry.rank (C1 keyword + UCB + Q-advantage + tool_preference)
34
34
  Policy (R5 live Q / REINFORCE on a judge-scored MDP)
35
35
  Learning.exemplars_for (C2 prioritized replay, C4 minimal trace)
36
36
  |
@@ -53,7 +53,7 @@ This is the live numeric controller. It does not replace planning.
53
53
  | Terminal reward | `Reward.judge` score (skipped when the cheap proxy is untrusted and there is no judge) |
54
54
  | Updates | Q-learning (`alpha=0.15`, `gamma=0.85`) and REINFORCE (`alpha=0.05`). Stored trajectories replay twice on warmup so a short table is not empty advice. |
55
55
  | Budget | Eight finished episodes (live or warmup-credited) unlock greedy suggestions. Until then the prompt omits them. |
56
- | Steer | Q-advantage in `Registry.rank` once the episode budget is met; keyword fit and CORE_TOOLS still come first |
56
+ | Steer | Q-advantage in `Registry.rank` once the episode budget is met; keyword fit and CORE_TOOLS still come first. Suggested actions follow `Registry.preference_order` (`ai.agent.tool_preference`). |
57
57
  | Files | `~/.pwn/policy.json`, `~/.pwn/policy_traj.jsonl` |
58
58
  | Tools | `policy_stats` · `policy_evaluate` · `policy_recommend` (inspect only) |
59
59
  | Off switch | `ai.agent.policy: false` |
@@ -122,10 +122,9 @@ dominate, the loop marks the budget path hot and tightens the live turn:
122
122
  Practice prioritizes those scars with short-horizon "finish the task" prompts.
123
123
  Raising `ai.agent.max_iters` or resolving the scar returns normal runway.
124
124
 
125
- ## Design-priority STATUS (post P14-P25)
125
+ ## Design-priority STATUS
126
126
 
127
- This table is the flag authority. Stop minting new P-numbers for chores already
128
- covered. Track these outcomes instead of hunting comments in the source.
127
+ This table is the live control list. Track the outcomes, not source comments.
129
128
 
130
129
  | Pri | ID | Control | Module(s) | Success criterion |
131
130
  |-----|----|---------|-----------|-------------------|
@@ -167,7 +166,10 @@ covered. Track these outcomes instead of hunting comments in the source.
167
166
  :reward_llm_timeout: 12 # cheap ORM chat timeout seconds (clamped 2..30)
168
167
  :local_introspect: :failure_only # ollama cost rule; remote always introspects
169
168
  :introspect_every_n: 3
170
- :max_iters: 25 # hard cap; budget pressure may lower effective value
169
+ :max_iters: 75 # hard cap; budget pressure may lower effective value
170
+ :defer_introspect: true # post-answer Learning after the user-visible reply
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]
171
173
  ```
172
174
 
173
175
  ## Cron self-improvement
@@ -183,6 +185,8 @@ PWN::Cron.install_defaults
183
185
 
184
186
  `install_defaults` treats the legacy name `offline_judge_nightly` as an alias of
185
187
  `curriculum_offline_judge` and will not double-seed the same slot.
188
+ `pwn setup` also starts the background cron worker so these YAML jobs fire
189
+ without a per-job crontab line.
186
190
 
187
191
  ## Tools exposed to the model
188
192
 
@@ -41,7 +41,7 @@ wiping durable facts, preferences, and lessons. Clearing is still available via
41
41
  5. Agent senses the world (opt) → extro_verify / watch / rf_tune / osint / serial / telecomm / packet / vision / voice / intel / observe
42
42
  ↳ extro_verify → :refuted → Mistakes.record(tool:'assumption', ...) # proactive
43
43
  ↳ extro_verify → :confirmed → observe(:intel, ttl:30d)
44
- 6. Final answer produced Learning.auto_introspect(session_id)
44
+ 6. Final answer produced -> Learning.auto_introspect(session_id) (deferred after reply by default)
45
45
  ↳ Reward.judge (cheap LLM ORM) → Policy.finish (terminal reward; Q + REINFORCE update)
46
46
  ↳ (local) fact_check_local_final → auto extro_verify every CVE/version claim in the answer
47
47
  ↳ if auto_extrospect enabled → Extrospection.auto_extrospect # AUTO_SECTIONS only
@@ -47,7 +47,7 @@ with a **tool-calling AI agent** on top that can run the same methods.
47
47
  tool-calling agent, optionally on a *different* LLM engine) that debate,
48
48
  broadcast, and share an append-only bus - no IRC daemon, no external service.
49
49
  - **Self-healing state.** `PWN::Setup` (doctor/provisioner) + `PWN::Migrate`
50
- (schema-stamped `~/.pwn` verifier/auto-migrator) make `gem install pwn` →
50
+ (schema-stamped `~/.pwn` verifier/auto-migrator) make `gem install --verbose pwn` →
51
51
  `pwn setup` the full install and upgrade path on every supported OS.
52
52
 
53
53
  ![Overall Architecture](diagrams/overall-pwn-architecture.svg)