pwn 0.5.618 → 0.5.620

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/README.md +14 -6
  4. data/bin/pwn_gqrx_scanner +25 -5
  5. data/documentation/Agent-Tool-Registry.md +3 -3
  6. data/documentation/Diagrams.md +6 -2
  7. data/documentation/Extrospection.md +30 -11
  8. data/documentation/Home.md +5 -4
  9. data/documentation/How-PWN-Works.md +7 -4
  10. data/documentation/Mistakes.md +96 -0
  11. data/documentation/Persistence.md +3 -1
  12. data/documentation/SDR.md +23 -5
  13. data/documentation/Skills-Memory-Learning.md +15 -5
  14. data/documentation/diagrams/agent-tool-registry.svg +94 -92
  15. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -2
  16. data/documentation/diagrams/dot/extrospection-world-awareness.dot +9 -7
  17. data/documentation/diagrams/dot/memory-skills-detailed.dot +12 -5
  18. data/documentation/diagrams/dot/mistakes-negative-feedback.dot +93 -0
  19. data/documentation/diagrams/dot/overall-pwn-architecture.dot +7 -5
  20. data/documentation/diagrams/dot/persistence-filesystem.dot +3 -2
  21. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +19 -7
  22. data/documentation/diagrams/dot/sdr-radio-flow.dot +13 -11
  23. data/documentation/diagrams/extrospection-world-awareness.svg +111 -93
  24. data/documentation/diagrams/memory-skills-detailed.svg +146 -97
  25. data/documentation/diagrams/mistakes-negative-feedback.svg +266 -0
  26. data/documentation/diagrams/overall-pwn-architecture.svg +184 -173
  27. data/documentation/diagrams/persistence-filesystem.svg +77 -62
  28. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +217 -149
  29. data/documentation/diagrams/sdr-radio-flow.svg +76 -56
  30. data/documentation/pwn-ai-Agent.md +28 -15
  31. data/lib/pwn/ai/agent/extrospection.rb +65 -6
  32. data/lib/pwn/ai/agent/learning.rb +67 -7
  33. data/lib/pwn/ai/agent/loop.rb +72 -6
  34. data/lib/pwn/ai/agent/mistakes.rb +369 -0
  35. data/lib/pwn/ai/agent/prompt_builder.rb +10 -1
  36. data/lib/pwn/ai/agent/tools/extrospection.rb +2 -2
  37. data/lib/pwn/ai/agent/tools/mistakes.rb +132 -0
  38. data/lib/pwn/ai/agent.rb +1 -0
  39. data/lib/pwn/plugins/jira_data_center.rb +2 -2
  40. data/lib/pwn/sdr/decoder/adsb.rb +101 -0
  41. data/lib/pwn/sdr/decoder/apt.rb +75 -0
  42. data/lib/pwn/sdr/decoder/bluetooth.rb +78 -0
  43. data/lib/pwn/sdr/decoder/dect.rb +84 -0
  44. data/lib/pwn/sdr/decoder/gps.rb +83 -0
  45. data/lib/pwn/sdr/decoder/gsm.rb +50 -29
  46. data/lib/pwn/sdr/decoder/iridium.rb +81 -0
  47. data/lib/pwn/sdr/decoder/lora.rb +87 -0
  48. data/lib/pwn/sdr/decoder/lte.rb +88 -0
  49. data/lib/pwn/sdr/decoder/morse.rb +64 -0
  50. data/lib/pwn/sdr/decoder/p25.rb +71 -0
  51. data/lib/pwn/sdr/decoder/pager.rb +77 -0
  52. data/lib/pwn/sdr/decoder/pocsag.rb +26 -11
  53. data/lib/pwn/sdr/decoder/rfid.rb +88 -0
  54. data/lib/pwn/sdr/decoder/rtl433.rb +95 -0
  55. data/lib/pwn/sdr/decoder/rtty.rb +66 -0
  56. data/lib/pwn/sdr/decoder/wifi.rb +98 -0
  57. data/lib/pwn/sdr/decoder/zigbee.rb +96 -0
  58. data/lib/pwn/sdr/decoder.rb +67 -7
  59. data/lib/pwn/sdr/frequency_allocation.rb +82 -41
  60. data/lib/pwn/sdr/gqrx.rb +186 -95
  61. data/lib/pwn/version.rb +1 -1
  62. data/spec/lib/pwn/ai/agent/mistakes_spec.rb +36 -0
  63. data/spec/lib/pwn/ai/agent/tools/mistakes_spec.rb +12 -0
  64. data/spec/lib/pwn/sdr/decoder/adsb_spec.rb +15 -0
  65. data/spec/lib/pwn/sdr/decoder/apt_spec.rb +15 -0
  66. data/spec/lib/pwn/sdr/decoder/bluetooth_spec.rb +15 -0
  67. data/spec/lib/pwn/sdr/decoder/dect_spec.rb +15 -0
  68. data/spec/lib/pwn/sdr/decoder/gps_spec.rb +15 -0
  69. data/spec/lib/pwn/sdr/decoder/iridium_spec.rb +15 -0
  70. data/spec/lib/pwn/sdr/decoder/lora_spec.rb +15 -0
  71. data/spec/lib/pwn/sdr/decoder/lte_spec.rb +15 -0
  72. data/spec/lib/pwn/sdr/decoder/morse_spec.rb +15 -0
  73. data/spec/lib/pwn/sdr/decoder/p25_spec.rb +15 -0
  74. data/spec/lib/pwn/sdr/decoder/pager_spec.rb +15 -0
  75. data/spec/lib/pwn/sdr/decoder/rfid_spec.rb +15 -0
  76. data/spec/lib/pwn/sdr/decoder/rtl433_spec.rb +15 -0
  77. data/spec/lib/pwn/sdr/decoder/rtty_spec.rb +15 -0
  78. data/spec/lib/pwn/sdr/decoder/wifi_spec.rb +15 -0
  79. data/spec/lib/pwn/sdr/decoder/zigbee_spec.rb +15 -0
  80. data/third_party/pwn_rdoc.jsonl +92 -3
  81. metadata +44 -6
  82. data/README.md.bak +0 -200
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d2c26dca00a6c45a763df37f813f0d789098ed87f8b7c5296dca5a7a72d4281
4
- data.tar.gz: fc40bc082f3d549efd2cef1fbb11807a53b416caf2a8190769818f681cc600dd
3
+ metadata.gz: d7b52a560de426b6b9c99fa2716b8e93a948e66088e0e1ae78d28f8633417cea
4
+ data.tar.gz: f94969b76a9ad4b856a9b5db25647f41d57f600f0c331ebde29c24b35ab59cd1
5
5
  SHA512:
6
- metadata.gz: f0269c36ff988d1817214345cf77c347a8c1f22104ba822b6982aa4fe6318086e69793f42a5d563bb061ec543cf7a5bb99877649f7f1554c8d6a182ab281356a
7
- data.tar.gz: 269676fd1f2dbd6f5f78c3e645d0d4675df08d681b7db21d49c7937fc121bd1b74dfbd4f82b1a049c9e6f4579ed7e2d697403f28c45312dffbc29b6557cbb16a
6
+ metadata.gz: dcd6287345b8f7230aeeeddc8a5d8de97d4000ae6bddecd77b4b2957f8ddf480de5c9ba8ba6a96a9fcf77f64a30f0b3d9a41219ad15512deab556c5b7e60c360
7
+ data.tar.gz: 92b3f2b90679984a47ed9cff3e1440100803e4220fc6f78eac386bd5cd125f24acbdd7b44504c20f783ba653895726495a69b7ce5d9cd5fd883a98cb67a11ef9
data/Gemfile CHANGED
@@ -50,7 +50,7 @@ gem 'libusb', '0.7.2'
50
50
  gem 'luhn', '3.0.0'
51
51
  gem 'mail', '2.9.1'
52
52
  gem 'mcp', '0.23.0'
53
- gem 'meshtastic', '0.0.167'
53
+ gem 'meshtastic', '0.0.169'
54
54
  gem 'metasm', '1.0.6'
55
55
  gem 'mongo', '2.24.1'
56
56
  gem 'msfrpc-client', '1.1.2'
@@ -81,7 +81,7 @@ gem 'rmagick', '7.0.5'
81
81
  gem 'rqrcode', '3.2.0'
82
82
  gem 'rspec', '3.13.2'
83
83
  gem 'rtesseract', '3.1.4'
84
- gem 'rubocop', '1.88.1'
84
+ gem 'rubocop', '1.88.2'
85
85
  gem 'rubocop-rake', '0.7.1'
86
86
  gem 'rubocop-rspec', '3.10.2'
87
87
  gem 'ruby-audio', '1.6.1'
data/README.md CHANGED
@@ -51,19 +51,26 @@ Five layers, edges only ever go down:
51
51
  ![PWN Overall Architecture](documentation/diagrams/overall-pwn-architecture.svg)
52
52
 
53
53
  The AI layer closes a **self-improvement loop** on every turn — Metrics +
54
- Learning (introspection) joined with Snapshot + Drift + Intel (extrospection)
55
- via `extro_correlate`, so the agent knows whether a failure was *its* fault or
56
- *the world* changed:
54
+ Learning + **Mistakes** (introspection / negative feedback) joined with
55
+ Snapshot + Drift + Intel + RF (extrospection) via `extro_correlate`, so the
56
+ agent knows whether a failure was *its* fault or *the world* changed
57
+ **and does not repeat the same mistake twice**:
57
58
 
58
59
  ![pwn-ai Feedback Learning Loop](documentation/diagrams/pwn-ai-feedback-learning-loop.svg)
59
60
 
61
+ Failures are fingerprinted cross-session (`~/.pwn/mistakes.json`), tagged
62
+ `[REPEATING]` / `[REGRESSED]`, and their **fix** is handed straight back inline
63
+ on the next recurrence:
64
+
65
+ ![Mistakes Negative-Feedback Loop](documentation/diagrams/mistakes-negative-feedback.svg)
66
+
60
67
  And **Swarm** runs multiple personas — each a full tool-calling agent,
61
68
  optionally on a *different* LLM engine — over a shared append-only bus:
62
69
 
63
70
  ![Swarm Multi-Agent](documentation/diagrams/swarm-multi-agent.svg)
64
71
 
65
72
  Full pages: [How PWN Works](documentation/How-PWN-Works.md) ·
66
- [All 26 Data-Flow Diagrams](documentation/Diagrams.md)
73
+ [All 27 Data-Flow Diagrams](documentation/Diagrams.md)
67
74
 
68
75
  ---
69
76
 
@@ -76,8 +83,9 @@ The complete wiki lives in this repo at **[`documentation/Home.md`](documentatio
76
83
  | [What is PWN](documentation/What-is-PWN.md) | [`pwn` REPL](documentation/pwn-REPL.md) | [AI / LLM Integration](documentation/AI-Integration.md) | [Plugins (66)](documentation/Plugins.md) |
77
84
  | [Why PWN](documentation/Why-PWN.md) | [`pwn-ai` Agent](documentation/pwn-ai-Agent.md) | [Agent Tool Registry](documentation/Agent-Tool-Registry.md) | [SAST (48)](documentation/SAST.md) |
78
85
  | [How PWN Works](documentation/How-PWN-Works.md) | [CLI Drivers (52)](documentation/CLI-Drivers.md) | [Memory · Skills · Learning](documentation/Skills-Memory-Learning.md) | [AWS (90)](documentation/AWS.md) |
79
- | [Installation](documentation/Installation.md) | [Build a Driver](documentation/Drivers.md) | [Extrospection](documentation/Extrospection.md) | [WWW (21)](documentation/WWW.md) |
80
- | [General Usage](documentation/General-PWN-Usage.md) | | [Swarm (multi-agent)](documentation/Swarm.md) | [SDR / Radio](documentation/SDR.md) |
86
+ | [Installation](documentation/Installation.md) | [Build a Driver](documentation/Drivers.md) | [Mistakes (neg-feedback)](documentation/Mistakes.md) | [WWW (21)](documentation/WWW.md) |
87
+ | [General Usage](documentation/General-PWN-Usage.md) | | [Extrospection](documentation/Extrospection.md) | [SDR / Radio](documentation/SDR.md) |
88
+ | [Configuration](documentation/Configuration.md) | | [Swarm (multi-agent)](documentation/Swarm.md) | [Hardware](documentation/Hardware.md) |
81
89
  | [Configuration](documentation/Configuration.md) | | [Sessions](documentation/Sessions.md) · [Cron](documentation/Cron.md) | [Reports](documentation/Reporting.md) |
82
90
  | [`~/.pwn/` Persistence](documentation/Persistence.md) | | | [BurpSuite](documentation/BurpSuite.md) · [NmapIt](documentation/NmapIt.md) |
83
91
  | **[All Diagrams](documentation/Diagrams.md)** | | | [Metasploit](documentation/Metasploit.md) · [Fuzzing](documentation/Fuzzing.md) |
data/bin/pwn_gqrx_scanner CHANGED
@@ -76,7 +76,7 @@ PWN::Driver::Parser.new do |options|
76
76
  opts[:fft_scan] = f
77
77
  end
78
78
 
79
- options.on('-SRATE', '--sample-rate=RATE', '<Optional --fft-scan - Visible span/sample_rate in Hz (default 1_000_000)>') do |s|
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
80
  opts[:sample_rate] = s
81
81
  end
82
82
 
@@ -84,11 +84,11 @@ PWN::Driver::Parser.new do |options|
84
84
  opts[:nfft] = n
85
85
  end
86
86
 
87
- options.on('-AINT', '--avg=INT', '<Optional --fft-scan - FFT averages (default 2)>') do |a|
87
+ options.on('--avg=INT', '<Optional --fft-scan - FFT averages (default 8). NOTE: no short flag; -A is --audio-gain>') do |a|
88
88
  opts[:avg] = a
89
89
  end
90
90
 
91
- options.on('-CSEC', '--capture-secs=SEC', '<Optional --fft-scan - Capture seconds per chunk (default 0.03)>') do |c|
91
+ options.on('-CSEC', '--capture-secs=SEC', '<Optional --fft-scan - Capture seconds per chunk (default 0.10)>') do |c|
92
92
  opts[:capture_secs] = c
93
93
  end
94
94
 
@@ -99,6 +99,14 @@ PWN::Driver::Parser.new do |options|
99
99
  options.on('-ODB', '--strength-offset-db=FLOAT', '<Optional - Power offset in dB (default 0.0)>') do |o|
100
100
  opts[:strength_offset_db] = o
101
101
  end
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|
104
+ opts[:min_snr_db] = m
105
+ end
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|
108
+ opts[:min_bw_ratio] = r
109
+ end
102
110
  end.parse!
103
111
 
104
112
  begin
@@ -178,13 +186,17 @@ begin
178
186
  sample_rate = sample_rate.to_i
179
187
  nfft = opts[:nfft] || 2048
180
188
  nfft = nfft.to_i
181
- avgv = opts[:avg] || 2
189
+ avgv = opts[:avg] || 8
182
190
  avgv = avgv.to_i
183
- capture_secs = opts[:capture_secs] || 0.03
191
+ capture_secs = opts[:capture_secs] || 0.10
184
192
  capture_secs = capture_secs.to_f
185
193
  keep_spectrum = opts[:keep_spectrum] ? true : false
186
194
  strength_offset_db = opts[:strength_offset_db]
187
195
  strength_offset_db = strength_offset_db.to_f unless strength_offset_db.nil?
196
+ min_snr_db = opts[:min_snr_db]
197
+ min_snr_db = min_snr_db.to_f unless min_snr_db.nil?
198
+ min_bw_ratio = opts[:min_bw_ratio]
199
+ min_bw_ratio = min_bw_ratio.to_f unless min_bw_ratio.nil?
188
200
 
189
201
  if fft_scan
190
202
  puts '[*] --fft-scan requested: using fast FFT panoramic mode (#fast_scan_range)'
@@ -198,6 +210,14 @@ begin
198
210
  strength_lock: strength_lock,
199
211
  keep_spectrum: keep_spectrum,
200
212
  strength_offset_db: strength_offset_db,
213
+ min_snr_db: min_snr_db,
214
+ precision: precision,
215
+ min_bw_ratio: min_bw_ratio,
216
+ demodulator_mode: demodulator_mode,
217
+ bandwidth: bandwidth,
218
+ squelch: squelch,
219
+ decoder: decoder,
220
+ location: location,
201
221
  scan_log: scan_log
202
222
  )
203
223
  puts "FFT Scan complete: #{fast_resp[:total]} signals found."
@@ -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
9
+ ## Toolsets → Tools (10 toolsets · 52 tools)
10
10
 
11
11
  | Toolset | Tools | Backed by |
12
12
  |---|---|---|
@@ -15,7 +15,7 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
15
15
  | `memory` | `memory_remember` · `memory_recall` · `memory_forget` · `memory_clear` | `PWN::Memory` → `~/.pwn/memory.json` |
16
16
  | `skills` | `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` | `~/.pwn/skills/*.md` |
17
17
  | `sessions` | `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` | `PWN::Sessions` → `~/.pwn/sessions/` |
18
- | `learning` | `learning_note_outcome` · `learning_reflect` · `learning_distill_skill` · `learning_stats` · `learning_outcomes` · `learning_consolidate` · `learning_reset` · `learning_auto_reflect_toggle` | `PWN::AI::Agent::Learning` → `~/.pwn/learning.jsonl` |
18
+ | `learning` | `learning_note_outcome` · `learning_reflect` · `learning_distill_skill` · `learning_stats` · `learning_outcomes` · `learning_consolidate` · `learning_reset` · `learning_auto_reflect_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
20
  | `extrospection` | `extro_snapshot` · `extro_drift` · `extro_observe` · `extro_observations` · `extro_intel` · `extro_correlate` · `extro_stats` · `extro_reset` · `extro_auto_toggle` | `PWN::AI::Agent::Extrospection` → `~/.pwn/extrospection.json` |
21
21
  | `cron` | `cron_list` · `cron_create` · `cron_run` · `cron_enable` · `cron_disable` · `cron_remove` | `PWN::Cron` → `~/.pwn/cron/jobs.yml` |
@@ -51,6 +51,6 @@ recon:
51
51
  engine: ollama
52
52
  ```
53
53
 
54
- **See also:** [pwn-ai Agent](pwn-ai-Agent.md) · [Swarm](Swarm.md)
54
+ **See also:** [pwn-ai Agent](pwn-ai-Agent.md) · [Mistakes](Mistakes.md) · [Swarm](Swarm.md)
55
55
 
56
56
  [← Home](Home.md)
@@ -1,6 +1,6 @@
1
1
  # PWN Data-Flow Diagrams
2
2
 
3
- 26 SVG diagrams, all rendered from Graphviz sources in
3
+ 27 SVG diagrams, all rendered from Graphviz sources in
4
4
  [`diagrams/dot/`](diagrams/dot/) with a single shared visual theme
5
5
  (see [`_THEME.md`](diagrams/dot/_THEME.md)). Rebuild everything with:
6
6
 
@@ -51,11 +51,15 @@ groups) so lines never criss-cross.
51
51
  [source](diagrams/dot/pwn-ai-feedback-learning-loop.dot) · doc: [Skills, Memory & Learning](Skills-Memory-Learning.md)
52
52
  ![pwn-ai-feedback-learning-loop](diagrams/pwn-ai-feedback-learning-loop.svg)
53
53
 
54
+ ### Mistakes — Negative-Feedback Loop
55
+ [source](diagrams/dot/mistakes-negative-feedback.dot) · doc: [Mistakes](Mistakes.md)
56
+ ![mistakes-negative-feedback](diagrams/mistakes-negative-feedback.svg)
57
+
54
58
  ### Multi-Provider LLM Integration
55
59
  [source](diagrams/dot/ai-integration-tool-calling.dot) · doc: [AI Integration](AI-Integration.md)
56
60
  ![ai-integration-tool-calling](diagrams/ai-integration-tool-calling.svg)
57
61
 
58
- ### Agent Tool Registry (10 toolsets)
62
+ ### Agent Tool Registry (10 toolsets · 52 tools)
59
63
  [source](diagrams/dot/agent-tool-registry.dot) · doc: [Agent Tool Registry](Agent-Tool-Registry.md)
60
64
  ![agent-tool-registry](diagrams/agent-tool-registry.svg)
61
65
 
@@ -1,23 +1,38 @@
1
1
  # Extrospection — World Awareness
2
2
 
3
3
  `PWN::AI::Agent::Extrospection` is the **outward-facing** counterpart to
4
- [Learning](Skills-Memory-Learning.md). Where Learning/Metrics ask *"how well
5
- did **I** do?"*, Extrospection asks *"what does the **world** look like right
6
- now, and has it changed under me?"*
4
+ [Learning](Skills-Memory-Learning.md). Where Learning/Metrics/Mistakes ask
5
+ *"how well did **I** do?"*, Extrospection asks *"what does the **world** look
6
+ like right now, and has it changed under me?"*
7
7
 
8
8
  ![Extrospection engine](diagrams/extrospection-world-awareness.svg)
9
9
 
10
+ ## Snapshot sections (`extro_snapshot(sections: […])`)
11
+
12
+ | Section | Probe | Captures |
13
+ |---|---|---|
14
+ | `:host` | `probe_host` | hostname · uname · distro · arch · CPU · mem |
15
+ | `:net` | `probe_net` | interfaces · listening ports · default route |
16
+ | `:toolchain` | `probe_toolchain` | `PROBE_BINS` — nmap curl git ruby python3 gcc msfconsole sqlmap burpsuite zaproxy openssl docker **+ RF_BINS** |
17
+ | `:repo` | `probe_repo` | HEAD · branch · dirty · origin |
18
+ | `:env` | `probe_env` | ruby / gem / bundler / PWN version |
19
+ | **`:rf`** | **`probe_rf`** | **RTL-SDR / HackRF presence · SoapySDR devices · GQRX socket (127.0.0.1:7356) · Flipper serial · `/dev/tty{USB,ACM}*` · band-plan count** |
20
+
21
+ `RF_BINS = %w[rtl_sdr rtl_test rtl_433 hackrf_info gqrx dump1090 multimon-ng SoapySDRUtil]`
22
+ — these are also merged into `PROBE_BINS` so RF-toolchain drift shows up under
23
+ `toolchain.*` diff keys.
24
+
10
25
  ## Verbs
11
26
 
12
27
  | Tool | Does | Persists to |
13
28
  |---|---|---|
14
- | `extro_snapshot` | Fingerprint host/net/toolchain/repo/env → hash | `extrospection.json` (`snapshot` + rotates `previous`) |
29
+ | `extro_snapshot` | Fingerprint host/net/toolchain/repo/env/**rf** → hash | `extrospection.json` (`snapshot` + rotates `previous`) |
15
30
  | `extro_drift` | Diff live-vs-stored (or stored-vs-previous) | — returns `{changed, added, removed}` with dotted keys |
16
- | `extro_observe` | Record a recon fact (banner, CVE match, topology note) | `observations[]` |
31
+ | `extro_observe` | Record a fact — `category:` one of `recon vuln intel target network env` **`rf`** `misc` | `observations[]` |
17
32
  | `extro_observations` | Query recorded facts by source/category/target/tag | — |
18
33
  | `extro_intel` | Query NVD / CIRCL / Exploit-DB for keyword or CVE | optional `record: true` → `:intel` observations |
19
34
  | `extro_correlate` | **Join** introspection ↔ extrospection | — actionable findings |
20
- | `extro_stats` | snapshot age · observation count · drift counts | — |
35
+ | `extro_stats` | snapshot age · observation count · drift counts · **rf_devices** | — |
21
36
  | `extro_reset` | Wipe snapshot + observations (new engagement) | — |
22
37
  | `extro_auto_toggle` | Enable/disable auto-snapshot after every final answer | `PWN::Env[:ai][:agent][:auto_extrospect]` |
23
38
 
@@ -27,21 +42,25 @@ now, and has it changed under me?"*
27
42
  (a) Metrics tools with <50 % success × toolchain drift / missing binaries
28
43
  (b) Learning failures on day X × host/net/repo drift on day X
29
44
  (c) recorded :intel observations × installed component versions
45
+ (d) recorded :rf observations × missing SDR hardware / RF_BINS
30
46
  ```
31
47
 
32
48
  Output tells the agent whether a failure was **its own fault** ("I called the
33
- API wrong") or **the world changed** ("nmap was upgraded and the flag moved")
34
- and that distinction is written back into MEMORY so the next run doesn't
35
- waste iterations rediscovering it.
49
+ API wrong" → belongs in [Mistakes](Mistakes.md)) or **the world changed**
50
+ ("nmap was upgraded and the flag moved", "the HackRF was unplugged") and
51
+ that distinction is written back into MEMORY so the next run doesn't waste
52
+ iterations rediscovering it.
36
53
 
37
54
  ## Typical engagement flow
38
55
 
39
56
  ```ruby
40
57
  extro_reset(confirm: true) # clean slate for new scope
41
- extro_snapshot # baseline
58
+ extro_snapshot # baseline (all six sections)
42
59
  # … recon …
43
60
  extro_observe(source: 'nmap', target: '10.0.0.5',
44
61
  category: 'recon', data: 'OpenSSH 8.2p1 Ubuntu')
62
+ extro_observe(source: 'gqrx', target: '433.920MHz',
63
+ category: 'rf', data: 'peak -34.2 dBFS bw=200k FSK — likely garage remote')
45
64
  extro_intel(query: 'OpenSSH 8.2p1', record: true)
46
65
  # … days later, something breaks …
47
66
  extro_drift # what moved?
@@ -49,6 +68,6 @@ extro_correlate # why did it break?
49
68
  ```
50
69
 
51
70
  **See also:** [Skills, Memory & Learning](Skills-Memory-Learning.md) ·
52
- [pwn-ai Agent](pwn-ai-Agent.md)
71
+ [Mistakes](Mistakes.md) · [SDR](SDR.md) · [pwn-ai Agent](pwn-ai-Agent.md)
53
72
 
54
73
  [← Home](Home.md)
@@ -20,7 +20,7 @@
20
20
  | [Installation](Installation.md) | RVM, gem, `./install.sh`, first launch |
21
21
  | [General Usage](General-PWN-Usage.md) | Day-one cheat sheet |
22
22
  | [Configuration](Configuration.md) | `~/.pwn/config.yml` — engines, keys, agent options |
23
- | **[All Data-Flow Diagrams](Diagrams.md)** | **26 SVGs** in one scrollable page |
23
+ | **[All Data-Flow Diagrams](Diagrams.md)** | **27 SVGs** in one scrollable page |
24
24
 
25
25
  ## 🚪 Entry Points
26
26
 
@@ -36,9 +36,10 @@
36
36
  | | |
37
37
  |---|---|
38
38
  | [AI / LLM Integration](AI-Integration.md) | OpenAI · Anthropic · Grok (OAuth) · Gemini · Ollama |
39
- | [Agent Tool Registry](Agent-Tool-Registry.md) | 10 toolsets · 45+ LLM-callable tools |
39
+ | [Agent Tool Registry](Agent-Tool-Registry.md) | 10 toolsets · 52 LLM-callable tools |
40
40
  | [Memory · Skills · Learning](Skills-Memory-Learning.md) | Introspection — the self-improvement loop |
41
- | [Extrospection](Extrospection.md) | World-awarenesssnapshot · drift · intel · correlate |
41
+ | [Mistakes](Mistakes.md) | **Negative feedback** fingerprint failures · do-NOT-repeat · `[REPEATING]`/`[REGRESSED]` · inline self-correction |
42
+ | [Extrospection](Extrospection.md) | World-awareness — snapshot · drift · intel · correlate · **rf** |
42
43
  | [Swarm (Multi-Agent)](Swarm.md) | Personas · ask · debate · broadcast · shared bus |
43
44
  | [Sessions](Sessions.md) | Transcript persistence + reflection |
44
45
  | [Cron](Cron.md) | Scheduled autonomous jobs |
@@ -57,7 +58,7 @@
57
58
  | [SAST (48 rules)](SAST.md) | Static analysis + test-case engine |
58
59
  | [WWW (21 drivers)](WWW.md) | Browser automations for real sites |
59
60
  | [AWS (90 services)](AWS.md) | Cloud-security enumeration |
60
- | [SDR](SDR.md) | GQRX · FlipperZero · RFIDler · SonMicro |
61
+ | [SDR](SDR.md) | GQRX · FlipperZero · RFIDler · SonMicro · **Decoder::* (20 protocols)** |
61
62
  | [Blockchain](Blockchain.md) | BTC · ETH helpers |
62
63
  | [Bounty](Bounty.md) | Lifecycle / auth-replay tooling |
63
64
  | [Reports](Reporting.md) | HTML/JSON output + DefectDojo/Jira |
@@ -27,11 +27,12 @@ hardware).
27
27
  | Module | Role |
28
28
  |---|---|
29
29
  | `Loop` | plan → dispatch tool_calls → observe → repeat until final answer |
30
- | `Registry` | JSON-Schema function definitions grouped into 10 **toolsets** |
30
+ | `Registry` | JSON-Schema function definitions grouped into 10 **toolsets** · 52 tools |
31
31
  | `Dispatch` / `Result` | execute a tool, capture stdout/value/error/duration |
32
- | `PromptBuilder` | inject MEMORY / SKILLS / LEARNING / EXTROSPECTION blocks |
32
+ | `PromptBuilder` | inject MEMORY / SKILLS / LEARNING / **KNOWN MISTAKES + FIXES** / METRICS / EXTROSPECTION blocks |
33
33
  | `Metrics` · `Learning` | **introspection** — how well am I doing? |
34
- | `Extrospection` | **extrospection** — what does the world look like? |
34
+ | `Mistakes` | **negative feedback** — fingerprint failures, do NOT repeat, `[REPEATING]`/`[REGRESSED]`, inline `correction_hint` |
35
+ | `Extrospection` | **extrospection** — what does the world look like? (host · net · toolchain · repo · env · **rf**) |
35
36
  | `Swarm` | multi-agent personas over a shared JSONL bus |
36
37
 
37
38
  See [Agent Tool Registry](Agent-Tool-Registry.md) for every tool the LLM can call.
@@ -53,7 +54,9 @@ See [Persistence](Persistence.md) for the byte-level layout of each file.
53
54
 
54
55
  ## The feedback loop
55
56
 
56
- The reason L2 exists is to close this loop on every turn:
57
+ The reason L2 exists is to close this loop on every turn — successes
58
+ become skills/lessons, **failures become fingerprinted mistakes with fixes**,
59
+ and both are re-injected into the very next system prompt:
57
60
 
58
61
  ![Self-improvement loop](diagrams/pwn-ai-feedback-learning-loop.svg)
59
62
 
@@ -0,0 +1,96 @@
1
+ # Mistakes — The Negative-Feedback Loop
2
+
3
+ `PWN::AI::Agent::Mistakes` is the **negative** half of the pwn-ai learning
4
+ loop. Where [Learning](Skills-Memory-Learning.md) records *what worked* and
5
+ [Metrics](Skills-Memory-Learning.md) records *how often* a tool worked,
6
+ Mistakes records **specific failure patterns** with a stable fingerprint so
7
+ the agent can (a) recognise it is repeating itself, (b) be told exactly what
8
+ **not** to do again in every future system prompt, and (c) capture the **fix**
9
+ once one is found so the avoidance lesson becomes an actionable correction.
10
+
11
+ ![Mistakes negative-feedback loop](diagrams/mistakes-negative-feedback.svg)
12
+
13
+ ## The failure fingerprint
14
+
15
+ A "mistake" is keyed by `sha12(tool + normalised_error)`. Normalisation strips
16
+ volatile bits — paths, hex addresses, `:LINE`, `port N`, timestamps, UUIDs,
17
+ PIDs — so `NoMethodError … at foo.rb:42` and `… at foo.rb:99` collapse to
18
+ **one** signature and its `:count` climbs. **That count *is* the repeat
19
+ detector**, and it survives across sessions.
20
+
21
+ | Field | Meaning |
22
+ |---|---|
23
+ | `signature` | 12-hex-char sha of `(tool, normalised_error)` — stable across runs |
24
+ | `tool` | component the failure was in (`shell`, `pwn_eval`, `assumption`, `assistant_answer`, a module name…) |
25
+ | `error` | normalised error text (paths/lines/addrs/ts stripped) |
26
+ | `count` | **cross-session** recurrence count — drives `[REPEATING]` at ≥ 3 |
27
+ | `resolved` / `fix` | set by `mistakes_resolve` — promoted to a `PWN::Memory` `:lesson` |
28
+ | `regressed` | auto-set when a *resolved* signature recurs — reopened as `[REGRESSED]` |
29
+ | `sessions` | last 10 session_ids that hit it |
30
+
31
+ ## How the loop closes (why it does **not** repeat mistakes)
32
+
33
+ ```text
34
+ Loop.run --(tool failure)---------> Mistakes.record (persist + count++)
35
+ Loop.run --(same sig, count≥3)----> guard_repeated_failure (uses PERSISTENT count →
36
+ fires on the 1st recurrence
37
+ in a NEW session, not the 3rd)
38
+ Loop.run --(failure w/ known fix)-> inline correction_hint ("seen 5×, sig=…, KNOWN FIX: …"
39
+ → self-corrects NEXT iteration)
40
+ Loop.run --(user says "wrong")----> check_user_correction (flip last outcome + record)
41
+ PromptBuilder <-------------------- Mistakes.to_context (KNOWN MISTAKES + KNOWN FIXES)
42
+ model --(tool call)---------------> mistakes_record / mistakes_resolve
43
+ ```
44
+
45
+ ## Four ingest paths — nothing slips through
46
+
47
+ | Source | Trigger | What is recorded |
48
+ |---|---|---|
49
+ | `:tool` | any tool dispatch returns `success:false` / raises | *automatic* — `Loop.record_metrics` |
50
+ | `:loop` | iteration budget exhausted with no final answer | *automatic* — `Loop.run` epilogue |
51
+ | `:user_correction` | next user message matches `CORRECTION_RX` (*"no that's wrong"*, *"still broken"*, *"try again"*, …) | `check_user_correction` — also flips the previous `Learning` outcome to `success:false` |
52
+ | `:model` | the model itself calls `mistakes_record` | wrong assumption, wrong file, hallucinated API — failures that are **not** dispatch errors |
53
+
54
+ ## Tools
55
+
56
+ | Tool | Does |
57
+ |---|---|
58
+ | `mistakes_list` | count-sorted fingerprints (signature · tool · error · count · resolved · fix) |
59
+ | `mistakes_record` | proactively fingerprint a semantic mistake YOU just made |
60
+ | `mistakes_resolve` | attach the **fix** → promoted to `PWN::Memory` `:lesson` **and** handed straight back inline via `correction_hint` on the next recurrence. If the same sig recurs it auto-reopens as `[REGRESSED]`. |
61
+ | `mistakes_reset` | wipe `~/.pwn/mistakes.json` (new engagement) |
62
+
63
+ ## What the model sees every turn
64
+
65
+ `PromptBuilder` injects `Mistakes.to_context` between the `LEARNING` and
66
+ `TOOL EFFECTIVENESS` blocks:
67
+
68
+ ```text
69
+ KNOWN MISTAKES (do NOT repeat — call mistakes_resolve once fixed)
70
+ ✗ [a1b2c3d4e5f6] shell ×4 [REPEATING]: nmpa: command not found
71
+ ✗ [7f8e9d0c1b2a] pwn_eval ×2 [REGRESSED]: nomethoderror: undefined method `scan_range' — last fix (insufficient): use fast_scan_range
72
+ KNOWN FIXES (apply these instead of repeating the mistake)
73
+ ✓ [c0ffee123456] shell: connection refused port N — FIX: start ZAP first via PWN::Plugins::Zaproxy.start
74
+ ```
75
+
76
+ …and every failed dispatch gets an **inline** postscript:
77
+
78
+ ```text
79
+ [pwn-ai/mistakes] seen 4× across 3 session(s), sig=a1b2c3d4e5f6 | KNOWN FIX: binary is spelled `nmap`
80
+ ```
81
+
82
+ so the very next iteration self-corrects without re-discovering the fix.
83
+
84
+ ## Regression detection
85
+
86
+ Resolving a mistake does **not** delete it. If the same signature fires again
87
+ after `mistakes_resolve`, `record()` clears `:resolved`, sets `:regressed`,
88
+ and the entry re-enters the `KNOWN MISTAKES` block tagged `[REGRESSED]` with
89
+ its (now-insufficient) previous fix shown inline — the strongest possible
90
+ "your last fix didn't hold" signal.
91
+
92
+ **See also:** [Skills, Memory & Learning](Skills-Memory-Learning.md) ·
93
+ [Extrospection](Extrospection.md) · [Persistence](Persistence.md) ·
94
+ [pwn-ai Agent](pwn-ai-Agent.md)
95
+
96
+ [← Home](Home.md)
@@ -10,8 +10,9 @@ Every byte PWN remembers between processes lives here.
10
10
  | `memory.json` | `PWN::Memory` | JSON array | `memory_clear` | facts · prefs · lessons · env — injected into every prompt |
11
11
  | `skills/*.md` | `PWN::Config.load_skills` | Markdown + YAML front-matter | `skill_delete` | reusable procedures + `references:` (CWE/CVE/ATT&CK/NIST) |
12
12
  | `learning.jsonl` | `PWN::AI::Agent::Learning` | JSON-per-line | `learning_reset` | task outcome log → success_rate |
13
+ | **`mistakes.json`** | **`PWN::AI::Agent::Mistakes`** | **JSON `{sig → entry}`** | **`mistakes_reset`** | **failure fingerprints · cross-session count · fix · `[REPEATING]` · `[REGRESSED]`** |
13
14
  | `metrics.json` | `PWN::AI::Agent::Metrics` | JSON | `metrics_reset` | per-tool calls · success · avg_duration · last_error |
14
- | `extrospection.json` | `PWN::AI::Agent::Extrospection` | JSON | `extro_reset` | host snapshot + previous baseline + observations[] |
15
+ | `extrospection.json` | `PWN::AI::Agent::Extrospection` | JSON | `extro_reset` | host/net/toolchain/repo/env/**rf** snapshot + previous baseline + observations[] |
15
16
  | `sessions/*.jsonl` | `PWN::Sessions` | JSON-per-line | `sessions_delete` | full transcript per pwn-ai run |
16
17
  | `cron/jobs.yml` | `PWN::Cron` | YAML | `cron_remove` | scheduled prompt/ruby/script jobs |
17
18
  | `cron/log/*.log` | `PWN::Cron` | text | rm | last_run output |
@@ -31,6 +32,7 @@ tar czf pwn-state-$(date +%F).tgz -C "$HOME" .pwn
31
32
  ```ruby
32
33
  # inside pwn-ai — keeps config & skills, wipes engagement-specific state
33
34
  extro_reset(confirm: true) # host snapshot + observations
35
+ mistakes_reset(confirm: true) # failure fingerprints (host-specific errors)
34
36
  learning_reset(confirm: true) # task outcomes (optional)
35
37
  metrics_reset(confirm: true) # tool telemetry (optional)
36
38
  ```
data/documentation/SDR.md CHANGED
@@ -6,18 +6,23 @@
6
6
 
7
7
  | Module | Purpose |
8
8
  |---|---|
9
- | **`GQRX`** | Remote-control a running GQRX instance over TCP: tune, set demod, squelch, record, `get_spectrum_snapshot` (pure-Ruby FFT), scan ranges |
9
+ | **`GQRX`** | Remote-control a running GQRX instance over TCP: tune, set demod, squelch, record, `get_spectrum_snapshot` (pure-Ruby FFT — median noise floor, DC/LO-leakage null, band-edge guard), `fast_scan_range` |
10
10
  | `FlipperZero` | Serial control of Flipper (sub-GHz, NFC, IR, iButton) |
11
11
  | `RFIDler` | 125 kHz RFID reader/emulator |
12
12
  | `SonMicroRFID` | SM130 13.56 MHz reader |
13
13
  | `FrequencyAllocation` | ITU/FCC band-plan lookup — "what lives at 433.92 MHz?" |
14
- | `Decoder::*` | Demodulator/protocol helpers |
14
+ | **`Decoder::*`** | 20 protocol demodulators/decoders — `ADSB APT Bluetooth DECT FLEX GPS GSM Iridium LoRa LTE Morse P25 Pager POCSAG RDS RFID RTL433 RTTY WiFi ZigBee` |
15
15
 
16
16
  ## CLI
17
17
 
18
18
  ```bash
19
- pwn_gqrx_scanner --start 430e6 --stop 440e6 --step 12.5e3 --mode fast
20
- pwn_gqrx_scanner --start 118e6 --stop 137e6 --mode iterative --squelch -60
19
+ # FFT sweep SNR-gated peak detection (no false-positive flood)
20
+ pwn_gqrx_scanner --start 430e6 --stop 440e6 --fft-scan \
21
+ --avg 8 --min-snr-db 10 --capture-secs 0.10
22
+
23
+ # Classic iterative S-meter scan
24
+ pwn_gqrx_scanner --start 118e6 --stop 137e6 --step 12.5e3 \
25
+ --strength-lock -60 --audio-gain-db 6
21
26
  ```
22
27
 
23
28
  See skill `pwn_gqrx_scanner_fast_vs_iterative_scanning` for the trade-off.
@@ -33,7 +38,20 @@ PWN::SDR::FrequencyAllocation.lookup(freq: 433_920_000)
33
38
  # => { band: 'ISM 433', typical: ['garage doors', 'weather stations', …] }
34
39
  ```
35
40
 
36
- Record signal intel with `extro_observe(source: 'gqrx', category: 'recon', …)`.
41
+ ## RF Extrospection
42
+
43
+ The AI agent is RF-aware. `extro_snapshot(sections: [:rf])` runs `probe_rf`
44
+ (RTL-SDR / HackRF / SoapySDR / Flipper / GQRX-socket inventory) and RF signal
45
+ intel is recorded with a first-class `:rf` observation category:
46
+
47
+ ```ruby
48
+ extro_observe(source: 'gqrx', category: :rf, target: '433.920MHz',
49
+ data: 'peak -34.2 dBFS bw=200k FSK — likely garage remote')
50
+ ```
51
+
52
+ `extro_correlate` then cross-references `:rf` observations against missing
53
+ `RF_BINS` / unplugged hardware so the agent can tell "no signal" from "no
54
+ dongle".
37
55
 
38
56
  **See also:** [Hardware](Hardware.md) · [Extrospection](Extrospection.md)
39
57
 
@@ -1,29 +1,37 @@
1
- # Memory · Skills · Learning · Metrics — Introspection
1
+ # Memory · Skills · Learning · Mistakes · Metrics — Introspection
2
2
 
3
3
  The **inward-facing** half of the pwn-ai feedback loop: how the agent measures
4
- its own performance and turns wins into permanent capability.
4
+ its own performance, turns wins into permanent capability, and — critically —
5
+ **learns from its own mistakes so it does not repeat them**.
5
6
 
6
7
  ![Memory / Skills detail](diagrams/memory-skills-detailed.svg)
7
8
 
8
- ## The four stores
9
+ ## The five stores
9
10
 
10
11
  | Store | File | Write tool | Read tool | Injected as |
11
12
  |---|---|---|---|---|
12
13
  | **Memory** | `memory.json` | `memory_remember` | `memory_recall` | `MEMORY` block — durable facts / prefs / lessons / env |
13
14
  | **Skills** | `skills/*.md` | `skill_create` · `learning_distill_skill` | `skill_list` · `skill_view` | `SKILLS` list — reusable procedures + `references:` (CWE/CVE/ATT&CK/NIST/URL) |
14
15
  | **Learning** | `learning.jsonl` | `learning_note_outcome` · `learning_reflect` | `learning_outcomes` · `learning_stats` | `LEARNING` block — recent outcomes + success_rate |
16
+ | **Mistakes** | `mistakes.json` | `mistakes_record` · `mistakes_resolve` · *auto on failure* | `mistakes_list` | `KNOWN MISTAKES` + `KNOWN FIXES` blocks — do-NOT-repeat + do-THIS-instead |
15
17
  | **Metrics** | `metrics.json` | *automatic* (every Dispatch) | `metrics_summary` | `TOOL EFFECTIVENESS` block — steer tool choice |
16
18
 
17
19
  ## The lifecycle of a lesson
18
20
 
19
21
  ```text
20
22
  1. Dispatch runs a tool → Metrics.record(tool, ok?, ms)
23
+ ↳ tool FAILED? → Mistakes.record(tool, error) (count++, cross-session)
24
+ ↳ same sig ≥3×? → guard_repeated_failure + inline correction_hint
21
25
  2. Final answer produced → Learning.auto_reflect(session_id)
22
26
  3. Reflect finds a durable insight → Memory.remember(lesson_xxxx, …)
23
27
  4. A whole workflow succeeded → Learning.distill_skill(name, session_id, references:)
24
- 5. Next launch: PromptBuilder injects all four blocksthe model already knows.
28
+ 5. Found a fix for a mistake → mistakes_resolve(sig, fix) Memory :lesson "AVOID X — FIX: Y"
29
+ 6. Next launch: PromptBuilder injects all five blocks → the model already knows.
25
30
  ```
26
31
 
32
+ See **[Mistakes](Mistakes.md)** for the full negative-feedback mechanics
33
+ (fingerprinting, `[REPEATING]`, `[REGRESSED]`, user-correction detection).
34
+
27
35
  ## Skill file format
28
36
 
29
37
  ```markdown
@@ -54,11 +62,13 @@ the `## References` section, deduplicates, and exposes them via
54
62
  |---|---|
55
63
  | `learning_consolidate(max_entries: 200)` | MEMORY block getting long/noisy |
56
64
  | `learning_reset(confirm: true)` | dev-experiment noise polluted success_rate |
65
+ | `mistakes_reset(confirm: true)` | new host/engagement — prior failure patterns no longer apply |
57
66
  | `metrics_reset(confirm: true)` | fixed a broken tool; stale 0 % is misleading |
58
67
  | `skill_delete(name)` | auto-distilled skill turned out low-quality |
59
68
  | `learning_auto_reflect_toggle(enabled: false)` | during noisy fuzz loops |
60
69
 
61
- **See also:** [Extrospection](Extrospection.md) — the outward-facing half ·
70
+ **See also:** [Mistakes](Mistakes.md) — the negative-feedback half ·
71
+ [Extrospection](Extrospection.md) — the outward-facing half ·
62
72
  [Sessions](Sessions.md) · [Persistence](Persistence.md)
63
73
 
64
74
  [← Home](Home.md)