pwn 0.5.622 → 0.5.626

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/README.md +7 -1
  4. data/bin/pwn_gqrx_scanner +78 -9
  5. data/documentation/Agent-Tool-Registry.md +2 -2
  6. data/documentation/Configuration.md +11 -2
  7. data/documentation/Cron.md +5 -3
  8. data/documentation/Diagrams.md +1 -1
  9. data/documentation/Extrospection.md +472 -26
  10. data/documentation/FFI.md +72 -8
  11. data/documentation/Home.md +4 -4
  12. data/documentation/How-PWN-Works.md +7 -3
  13. data/documentation/Mistakes.md +9 -0
  14. data/documentation/SDR.md +83 -10
  15. data/documentation/Skills-Memory-Learning.md +100 -10
  16. data/documentation/diagrams/agent-tool-registry.svg +56 -55
  17. data/documentation/diagrams/ai-integration-tool-calling.svg +24 -24
  18. data/documentation/diagrams/aws-cloud-security.svg +25 -25
  19. data/documentation/diagrams/burp-vs-zap-preference.svg +12 -12
  20. data/documentation/diagrams/code-scanning-sast.svg +25 -25
  21. data/documentation/diagrams/cron-scheduling.svg +23 -23
  22. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -2
  23. data/documentation/diagrams/dot/extrospection-world-awareness.dot +33 -6
  24. data/documentation/diagrams/dot/hardware-hacking.dot +3 -1
  25. data/documentation/diagrams/dot/memory-skills-detailed.dot +4 -2
  26. data/documentation/diagrams/dot/mistakes-negative-feedback.dot +4 -2
  27. data/documentation/diagrams/dot/overall-pwn-architecture.dot +3 -3
  28. data/documentation/diagrams/dot/persistence-filesystem.dot +3 -3
  29. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +9 -3
  30. data/documentation/diagrams/dot/sdr-radio-flow.dot +39 -16
  31. data/documentation/diagrams/driver-framework.svg +13 -13
  32. data/documentation/diagrams/extrospection-world-awareness.svg +383 -177
  33. data/documentation/diagrams/fuzzing-workflow.svg +24 -24
  34. data/documentation/diagrams/hardware-hacking.svg +84 -69
  35. data/documentation/diagrams/history-to-drivers.svg +18 -18
  36. data/documentation/diagrams/memory-skills-detailed.svg +137 -120
  37. data/documentation/diagrams/mistakes-negative-feedback.svg +152 -137
  38. data/documentation/diagrams/network-infra-testing.svg +27 -27
  39. data/documentation/diagrams/overall-pwn-architecture.svg +97 -97
  40. data/documentation/diagrams/penetration-testing-workflow.svg +30 -30
  41. data/documentation/diagrams/persistence-filesystem.svg +100 -94
  42. data/documentation/diagrams/plugin-ecosystem.svg +35 -35
  43. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +254 -207
  44. data/documentation/diagrams/pwn-repl-prototyping.svg +20 -20
  45. data/documentation/diagrams/reporting-pipeline.svg +18 -18
  46. data/documentation/diagrams/reverse-engineering-flow.svg +21 -21
  47. data/documentation/diagrams/sdr-radio-flow.svg +223 -91
  48. data/documentation/diagrams/sessions-cron-automation.svg +18 -18
  49. data/documentation/diagrams/swarm-multi-agent.svg +39 -39
  50. data/documentation/diagrams/web-application-testing.svg +26 -26
  51. data/documentation/diagrams/zero-day-research-flow.svg +25 -25
  52. data/documentation/pwn-ai-Agent.md +14 -8
  53. data/documentation/pwn_silent_help_learn_demo.gif +0 -0
  54. data/lib/pwn/ai/agent/extrospection.rb +2561 -56
  55. data/lib/pwn/ai/agent/tools/extrospection.rb +311 -8
  56. data/lib/pwn/ffi/adalm_pluto.rb +498 -0
  57. data/lib/pwn/ffi/fftw.rb +192 -0
  58. data/lib/pwn/ffi/hack_rf.rb +193 -0
  59. data/lib/pwn/ffi/liquid.rb +244 -0
  60. data/lib/pwn/ffi/rtl_sdr.rb +210 -0
  61. data/lib/pwn/ffi/soapy_sdr.rb +177 -0
  62. data/lib/pwn/ffi/stdio.rb +9 -1
  63. data/lib/pwn/ffi/volk.rb +241 -0
  64. data/lib/pwn/ffi.rb +45 -2
  65. data/lib/pwn/sdr/decoder/adsb.rb +201 -12
  66. data/lib/pwn/sdr/decoder/apt.rb +19 -5
  67. data/lib/pwn/sdr/decoder/base.rb +314 -1
  68. data/lib/pwn/sdr/decoder/bluetooth.rb +91 -18
  69. data/lib/pwn/sdr/decoder/dect.rb +81 -23
  70. data/lib/pwn/sdr/decoder/dsp.rb +229 -15
  71. data/lib/pwn/sdr/decoder/flex.rb +23 -6
  72. data/lib/pwn/sdr/decoder/gps.rb +80 -18
  73. data/lib/pwn/sdr/decoder/gsm.rb +83 -28
  74. data/lib/pwn/sdr/decoder/iridium.rb +80 -18
  75. data/lib/pwn/sdr/decoder/lora.rb +84 -28
  76. data/lib/pwn/sdr/decoder/lte.rb +80 -18
  77. data/lib/pwn/sdr/decoder/morse.rb +23 -6
  78. data/lib/pwn/sdr/decoder/p25.rb +90 -31
  79. data/lib/pwn/sdr/decoder/pager.rb +23 -6
  80. data/lib/pwn/sdr/decoder/pocsag.rb +23 -6
  81. data/lib/pwn/sdr/decoder/rds.rb +219 -52
  82. data/lib/pwn/sdr/decoder/rfid.rb +81 -27
  83. data/lib/pwn/sdr/decoder/rtl433.rb +85 -27
  84. data/lib/pwn/sdr/decoder/rtty.rb +23 -6
  85. data/lib/pwn/sdr/decoder/wifi.rb +86 -32
  86. data/lib/pwn/sdr/decoder/zigbee.rb +88 -35
  87. data/lib/pwn/sdr/decoder.rb +6 -5
  88. data/lib/pwn/sdr/frequency_allocation.rb +124 -81
  89. data/lib/pwn/sdr/gqrx.rb +1512 -164
  90. data/lib/pwn/version.rb +1 -1
  91. data/spec/lib/pwn/ai/agent/extrospection_spec.rb +96 -0
  92. data/spec/lib/pwn/ai/agent/tools/extrospection_spec.rb +8 -24
  93. data/spec/lib/pwn/ffi/adalm_pluto_spec.rb +37 -0
  94. data/spec/lib/pwn/ffi/fftw_spec.rb +26 -0
  95. data/spec/lib/pwn/ffi/hack_rf_spec.rb +25 -0
  96. data/spec/lib/pwn/ffi/liquid_spec.rb +42 -0
  97. data/spec/lib/pwn/ffi/rtl_sdr_spec.rb +24 -0
  98. data/spec/lib/pwn/ffi/soapy_sdr_spec.rb +25 -0
  99. data/spec/lib/pwn/ffi/volk_spec.rb +36 -0
  100. data/spec/lib/pwn/sdr/decoder/base_iq_spec.rb +65 -0
  101. data/spec/lib/pwn/sdr/decoder/dsp_spec.rb +50 -4
  102. data/spec/lib/pwn/sdr/decoder/rds_spec.rb +45 -4
  103. data/third_party/pwn_rdoc.jsonl +232 -18
  104. metadata +17 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4aeb484ae013e0feb9648009d60cfc493bbd4ec98ba42193745af669ed70bcc
4
- data.tar.gz: 2dcffdf992ee24a9c8a10ae7b83c743ad5b6b1aed83e70063da56e8cf6e9ea85
3
+ metadata.gz: 67a226a1a110698db44ee0378d3f9a5fd290d96d633487a3dd4a7e72c1ac09d9
4
+ data.tar.gz: 8acea5ce6ab68d30486aef426c176611f379a31acf3092cdea7ced91e8dbf8e9
5
5
  SHA512:
6
- metadata.gz: 2468ec9291d44be94de1f3877441380e60cde34e24953f6ac677bd39f0679c82ab6f82f6554b7fcacf1348b0c751c63bf8d8a23a369ac665023b5a9e74cc3a01
7
- data.tar.gz: 722765fd660ca9da266a170da45f65eb061886b7629557143436a0765412dc89d3de3e56ac8f5bd8e9b32e5f25831d3644ac3568d851f6ac5f7629531b9e7768
6
+ metadata.gz: 48c6bca36c123d6419ee8fd12ff6813e2ab405b4fbd92fb31d1c64aea4ca3a2f75ee25e06e5db61d6db9d58775f8228b51783396c1c8e688dcf6afd224720025
7
+ data.tar.gz: 022c9adac00e0ccab76bbd4f6c86d603a32a55ce41e4e0b7d6093a59e52834b4692dbb700bb0e1c8ee2ba50bc0be1a5dd6db0fc80b76308d34188be1f623ce25
data/.rubocop.yml CHANGED
@@ -16,9 +16,9 @@ Metrics/ClassLength:
16
16
  Metrics/CyclomaticComplexity:
17
17
  Max: 158
18
18
  Metrics/MethodLength:
19
- Max: 733
19
+ Max: 800
20
20
  Metrics/ModuleLength:
21
- Max: 1592
21
+ Max: 2900
22
22
  Metrics/PerceivedComplexity:
23
23
  Max: 157
24
24
  Style/HashEachMethods:
data/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ![PWN](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/PWN.png)
2
2
 
3
+ <p align="center">
4
+ <img src="documentation/pwn_silent_help_learn_demo.gif" alt="PWN Silent Demo — Help Surfaces + Learning Feedback Loop" width="640">
5
+ <br>
6
+ <em>Silent walkthrough: <code>pwn</code> help surfaces → <code>pwn-ai</code> → recon → mistakes / learning / extrospection feedback loop</em>
7
+ </p>
8
+
3
9
  ### **Table of Contents** ###
4
10
 
5
11
  - [Intro](#intro)
@@ -52,7 +58,7 @@ Five layers, edges only ever go down:
52
58
 
53
59
  The AI layer closes a **self-improvement loop** on every turn — Metrics +
54
60
  Learning + **Mistakes** (introspection / negative feedback) joined with
55
- Snapshot + Drift + Intel + RF + **Web** (extrospection) — plus browser-backed **`extro_verify`** self fact-checking — via `extro_correlate`, so the
61
+ Snapshot + Drift + Intel + RF + **Web** (extrospection) — plus browser-backed **`extro_verify`** / **`extro_watch`** and RF **`extro_rf_tune`** sensing — via `extro_correlate`, so the
56
62
  agent knows whether a failure was *its* fault or *the world* changed —
57
63
  **and does not repeat the same mistake twice**:
58
64
 
data/bin/pwn_gqrx_scanner CHANGED
@@ -76,8 +76,8 @@ PWN::Driver::Parser.new do |options|
76
76
  opts[:fft_scan] = f
77
77
  end
78
78
 
79
- options.on('--sample-rate=RATE', '<Optional --fft-scan - Visible span/sample_rate in Hz (default 1_000_000). NOTE: no short flag; -S is --strength-lock>') do |s|
80
- opts[:sample_rate] = s
79
+ options.on('--input-rate=RATE', '<Optional --fft-scan - GQRX Input rate / visible span in Hz (default 1_000_000). NOTE: no short flag; -S is --strength-lock>') do |s|
80
+ opts[:input_rate] = s
81
81
  end
82
82
 
83
83
  options.on('-NINT', '--nfft=INT', '<Optional --fft-scan - FFT bin size (default 2048)>') do |n|
@@ -100,13 +100,21 @@ PWN::Driver::Parser.new do |options|
100
100
  opts[:strength_offset_db] = o
101
101
  end
102
102
 
103
- options.on('--min-snr-db=FLOAT', '<Optional --fft-scan - Minimum SNR (dB above per-chunk noise floor) to report a signal (default 12.0)>') do |m|
103
+ options.on('--min-snr-db=FLOAT', '<Optional --fft-scan - Minimum SNR (dB above per-chunk noise floor) to report a signal (default 18.0)>') do |m|
104
104
  opts[:min_snr_db] = m
105
105
  end
106
106
 
107
- options.on('--min-bw-ratio=FLOAT', '<Optional --fft-scan - Reject FFT peaks narrower than RATIO * band-plan bandwidth as spurs (default 0.30)>') do |r|
107
+ options.on('--min-bw-ratio=FLOAT', '<Optional --fft-scan - Reject FFT peaks narrower than RATIO * band-plan bandwidth as spurs (default 0.0 = off)>') do |r|
108
108
  opts[:min_bw_ratio] = r
109
109
  end
110
+
111
+ options.on('--no-refine', '<Optional --fft-scan - Skip the post-FFT iterative edge/peak refine pass that locks the exact channel frequency (default: refine ON)>') do
112
+ opts[:refine] = false
113
+ end
114
+
115
+ options.on('--refine-mode=MODE', '<Optional --fft-scan - Refine strategy: lock (default, fast S-meter raster hunt), fft (legacy local high-res FFT zoom), hybrid (both)>') do |m|
116
+ opts[:refine_mode] = m
117
+ end
110
118
  end.parse!
111
119
 
112
120
  begin
@@ -122,13 +130,55 @@ begin
122
130
  end
123
131
 
124
132
  profile = opts[:profile]
133
+
134
+ # Common user-facing aliases → canonical band_plans keys.
135
+ # (historical/typo names should not crash with Hash#merge! TypeError)
136
+ profile_aliases = {
137
+ 'flex_pager' => 'pager_flex',
138
+ 'flex' => 'pager_flex',
139
+ 'pocsag_pager' => 'pager_pocsag',
140
+ 'pocsag' => 'pager_pocsag',
141
+ 'pager' => 'pager_all',
142
+ 'pagers' => 'pager_all',
143
+ 'adsb' => 'ads_b1090',
144
+ 'adsb1090' => 'ads_b1090',
145
+ 'adsb978' => 'ads_b978',
146
+ 'fm' => 'fm_radio',
147
+ 'noaa' => 'noaa_weather',
148
+ 'wx' => 'noaa_weather',
149
+ 'weather' => 'noaa_weather'
150
+ }.freeze
151
+
152
+ resolve_band_plan = lambda do |name|
153
+ return nil if name.nil?
154
+
155
+ key = name.to_s.strip.downcase.tr('-', '_').to_sym
156
+ key = profile_aliases[key.to_s].to_sym if profile_aliases.key?(key.to_s)
157
+ return key if band_plans.key?(key)
158
+
159
+ # fuzzy suggestions for helpful errors
160
+ cand = band_plans.keys.map(&:to_s)
161
+ suggestions = cand.select do |k|
162
+ k.include?(key.to_s) || key.to_s.include?(k) ||
163
+ k.split('_').intersect?(key.to_s.split('_'))
164
+ end
165
+ suggestions = cand.grep(/#{Regexp.escape(key.to_s.split('_').first)}/i) if suggestions.empty? && !key.to_s.empty?
166
+ msg = "ERROR: Unknown band plan profile: #{name.inspect}."
167
+ msg += " Did you mean: #{suggestions.sort.first(8).join(', ')}?" unless suggestions.empty?
168
+ msg += ' Use --list-band-plans to display supported profiles.'
169
+ raise msg
170
+ end
171
+
172
+ profile_key = resolve_band_plan.call(profile)
173
+ warn "[*] alias #{profile.inspect} → band plan #{profile_key}" if profile_key && profile.to_s.strip.downcase.tr('-', '_') != profile_key.to_s
174
+
125
175
  # Merge opts with profile values if profile provided
126
- opts.merge!(band_plans[profile.to_sym]) unless profile.nil?
176
+ opts.merge!(band_plans[profile_key]) unless profile_key.nil?
127
177
 
128
178
  scan_ranges = opts[:scan_ranges]
129
- raise 'ERROR: --assume-band-plan || --scan-ranges is required.' if scan_ranges.nil? && profile.nil?
179
+ raise 'ERROR: --assume-band-plan || --scan-ranges is required.' if scan_ranges.nil? && profile_key.nil?
130
180
 
131
- ranges = band_plans[profile.to_sym][:ranges] unless profile.nil?
181
+ ranges = band_plans[profile_key][:ranges] unless profile_key.nil?
132
182
  if ranges.nil?
133
183
  # Convert comma-delimited string to array of hashes
134
184
  ranges = scan_ranges.split(',').map do |r|
@@ -179,11 +229,19 @@ begin
179
229
  location = opts[:location]
180
230
 
181
231
  # Merge opts one last time to ensure parameters passed to the driver are included
182
- opts.merge!(band_plans[profile.to_sym]) unless profile.nil?
232
+ opts.merge!(band_plans[profile_key]) unless profile_key.nil?
183
233
 
184
234
  fft_scan = opts[:fft_scan]
185
- sample_rate = opts[:sample_rate] || 1_000_000
235
+ # Prefer (1) explicit --input-rate, (2) band-plan :input_rate from
236
+ # FrequencyAllocation (merged above), (3) historic 1 Msps default.
237
+ # GQRX device Input rate is separate from this *assumption* — use
238
+ # PWN::SDR::GQRX.apply_band_plan_input_rate to push the plan rate into
239
+ # ~/.config/gqrx/*.conf for the connected SDR.
240
+ # Local var + fast_scan_range kwarg remain sample_rate for library parity.
241
+ sample_rate = opts[:input_rate] || 1_000_000
186
242
  sample_rate = sample_rate.to_i
243
+ puts "[*] input_rate (FFT/scan chunk / IQ span assumption): #{sample_rate} Hz" \
244
+ "#{" (band plan #{profile_key})" if profile_key}"
187
245
  nfft = opts[:nfft] || 2048
188
246
  nfft = nfft.to_i
189
247
  avgv = opts[:avg] || 8
@@ -200,6 +258,11 @@ begin
200
258
 
201
259
  if fft_scan
202
260
  puts '[*] --fft-scan requested: using fast FFT panoramic mode (#fast_scan_range)'
261
+ refine_flag = opts.fetch(:refine, true)
262
+ puts "[*] band-plan / session params: mode=#{demodulator_mode.inspect} bw=#{bandwidth.inspect} " \
263
+ "squelch=#{squelch.inspect} precision=#{precision} decoder=#{decoder.inspect} " \
264
+ "rf_gain=#{rf_gain.inspect} if_gain=#{intermediate_gain.inspect} bb_gain=#{baseband_gain.inspect} " \
265
+ "refine=#{refine_flag}"
203
266
  fast_resp = PWN::SDR::GQRX.fast_scan_range(
204
267
  gqrx_sock: gqrx_sock,
205
268
  ranges: ranges,
@@ -213,9 +276,15 @@ begin
213
276
  min_snr_db: min_snr_db,
214
277
  precision: precision,
215
278
  min_bw_ratio: min_bw_ratio,
279
+ refine: opts.fetch(:refine, true),
280
+ refine_mode: opts[:refine_mode] || :lock,
216
281
  demodulator_mode: demodulator_mode,
217
282
  bandwidth: bandwidth,
218
283
  squelch: squelch,
284
+ audio_gain_db: audio_gain_db,
285
+ rf_gain: rf_gain,
286
+ intermediate_gain: intermediate_gain,
287
+ baseband_gain: baseband_gain,
219
288
  decoder: decoder,
220
289
  location: location,
221
290
  scan_log: scan_log
@@ -6,7 +6,7 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
6
6
 
7
7
  ![Tool registry](diagrams/agent-tool-registry.svg)
8
8
 
9
- ## Toolsets → Tools (10 toolsets · 54 tools)
9
+ ## Toolsets → Tools (10 toolsets · 61 tools)
10
10
 
11
11
  | Toolset | Tools | Backed by |
12
12
  |---|---|---|
@@ -17,7 +17,7 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
17
17
  | `sessions` | `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` | `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` · **`mistakes_list`** · **`mistakes_record`** · **`mistakes_resolve`** · **`mistakes_reset`** | `PWN::AI::Agent::Learning` + `PWN::AI::Agent::Mistakes` → `~/.pwn/learning.jsonl` + `~/.pwn/mistakes.json` |
19
19
  | `metrics` | `metrics_summary` · `metrics_reset` | `PWN::AI::Agent::Metrics` → `~/.pwn/metrics.json` |
20
- | `extrospection` | `extro_snapshot` · `extro_drift` · `extro_observe` · `extro_observations` · `extro_intel` · **`extro_watch`** · **`extro_verify`** · `extro_correlate` · `extro_stats` · `extro_reset` · `extro_auto_toggle` | `PWN::AI::Agent::Extrospection` (+ `PWN::Plugins::TransparentBrowser`) → `~/.pwn/extrospection.json` |
20
+ | `extrospection` | `extro_snapshot` · `extro_drift` · `extro_observe` · `extro_observations` · `extro_intel` · **`extro_watch`** · **`extro_verify`** · **`extro_rf_tune`** · **`extro_osint`** · **`extro_serial`** · **`extro_telecomm`** · **`extro_packet`** · **`extro_vision`** · **`extro_voice`** · `extro_correlate` · `extro_stats` · `extro_reset` · `extro_auto_toggle` | `PWN::AI::Agent::Extrospection` (+ Serial/Packet/OCR/Voice/BareSIP/TransparentBrowser) → `~/.pwn/extrospection.json` |
21
21
  | `cron` | `cron_list` · `cron_create` · `cron_run` · `cron_enable` · `cron_disable` · `cron_remove` | `PWN::Cron` → `~/.pwn/cron/jobs.yml` |
22
22
  | `swarm` | `agent_list` · `agent_spawn` · `agent_ask` · `agent_debate` · `agent_broadcast` · `swarm_bus` · `swarm_list` | `PWN::AI::Agent::Swarm` → `~/.pwn/agents.yml` + `~/.pwn/swarm/` |
23
23
 
@@ -82,7 +82,7 @@ ai:
82
82
  max_iters: 25 # Hard cap on tool-call rounds per user turn before a forced final answer.
83
83
  max_depth: 3 # Recursion guard: how many levels deep agent_ask/agent_debate sub-agents may spawn sub-agents.
84
84
  auto_introspect: true # Run Learning.auto_introspect (outcome logging + lesson mining) after every final answer.
85
- auto_extrospect: false # Also run Extrospection.auto_extrospect (host/toolchain/net/repo drift capture) after every final answer.
85
+ 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.
86
86
  toolsets: ~ # Allow-list of toolsets exposed to the agent. nil = all. Valid: cron, extrospection, learning, memory, metrics, pwn, sessions, skills, swarm, terminal.
87
87
  extrospection:
88
88
  web:
@@ -94,6 +94,11 @@ ai:
94
94
  per_page_timeout: 15 # Seconds before a single page render is abandoned and recorded as unreachable.
95
95
  screenshot: false # Persist a PNG per anchor to ~/.pwn/extrospection/web/ (disk-heavy; off by default).
96
96
  allow_targets: false # true → also merge top-level `targets:` into anchors (opt-in — off so in-scope hosts aren't touched unprompted).
97
+ rf:
98
+ host: 127.0.0.1 # GQRX remote-control host for extro_rf_tune.
99
+ port: 7356 # GQRX remote-control port.
100
+ settle_secs: 8 # Seconds to sample RDS after tuning (max 30).
101
+ ttl: 300 # Observation TTL for :rf (songs change — keep short).
97
102
 
98
103
  plugins:
99
104
  asm:
@@ -154,6 +159,10 @@ cron:
154
159
 
155
160
  targets: # Optional — engagement-scope URLs/hosts. Merged into :web snapshot anchors
156
161
  - https://target.example.com # ONLY when ai.agent.extrospection.web.allow_targets: true.
162
+ | `ai.agent.extrospection.rf.host` | String | `127.0.0.1` | `Extrospection.rf_tune` | GQRX remote-control host for the RF sense organ. |
163
+ | `ai.agent.extrospection.rf.port` | Integer | `7356` | `Extrospection.rf_tune` | GQRX remote-control port. |
164
+ | `ai.agent.extrospection.rf.settle_secs` | Integer | `8` | `Extrospection.rf_tune` | Seconds to sample RDS after tuning (capped at 30). |
165
+ | `ai.agent.extrospection.rf.ttl` | Integer | `300` | `Extrospection.rf_tune` | TTL (seconds) for `:rf` observations written by `extro_rf_tune` (ephemeral radio content). |
157
166
  ```
158
167
 
159
168
  ---
@@ -206,7 +215,7 @@ PWN::Config.refresh_env
206
215
  | `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. |
207
216
  | `ai.agent.max_depth` | Integer | `3` | `PWN::AI::Agent::Swarm` | Recursion guard for `agent_ask` / `agent_debate` sub-agents spawning sub-agents. |
208
217
  | `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`. |
209
- | `ai.agent.auto_extrospect` | Boolean | `false` | `PWN::AI::Agent::Extrospection.auto_extrospect` | Also capture host/toolchain/net/repo drift after every final answer. Toggle live via `extro_auto_toggle`. |
218
+ | `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`. |
210
219
  | `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`, `extrospection`, `learning`, `memory`, `metrics`, `pwn`, `sessions`, `skills`, `swarm`, `terminal`. |
211
220
  | `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`. |
212
221
  | `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`). |
@@ -37,9 +37,11 @@ cron_create(
37
37
  ```
38
38
 
39
39
  At 02:00 the system cron fires `PWN::Cron.run`, which spins up a headless
40
- `pwn-ai` turn. Because `auto_introspect` and `auto_extrospect` are on, the run
41
- also updates Learning/Metrics/Extrospectionso tomorrow's interactive
42
- session already knows what changed overnight.
40
+ `pwn-ai` turn. With `auto_introspect` on (and optional `auto_extrospect` for
41
+ the cheap `AUTO_SECTIONS` baseline), the run updates Learning/Metrics — and,
42
+ if enabled, host/repo/env posture so tomorrow's interactive session already
43
+ knows what changed overnight. Sense tools (`intel`/`verify`/`watch`) stay
44
+ on-demand; cron is not expected to launch Burp/ZAP/msf/GQRX.
43
45
 
44
46
  ```ruby
45
47
  cron_create(
@@ -59,7 +59,7 @@ groups) so lines never criss-cross.
59
59
  [source](diagrams/dot/ai-integration-tool-calling.dot) · doc: [AI Integration](AI-Integration.md)
60
60
  ![ai-integration-tool-calling](diagrams/ai-integration-tool-calling.svg)
61
61
 
62
- ### Agent Tool Registry (10 toolsets · 54 tools)
62
+ ### Agent Tool Registry (10 toolsets · 61 tools)
63
63
  [source](diagrams/dot/agent-tool-registry.dot) · doc: [Agent Tool Registry](Agent-Tool-Registry.md)
64
64
  ![agent-tool-registry](diagrams/agent-tool-registry.svg)
65
65