pwn 0.5.628 → 0.5.631

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -36
  3. data/bin/pwn +35 -1
  4. data/bin/pwn_setup +64 -0
  5. data/documentation/AI-Integration.md +50 -11
  6. data/documentation/AWS.md +3 -3
  7. data/documentation/Agent-Tool-Registry.md +24 -0
  8. data/documentation/Banner.md +1 -1
  9. data/documentation/Blockchain.md +3 -3
  10. data/documentation/Bounty.md +4 -4
  11. data/documentation/BurpSuite.md +5 -2
  12. data/documentation/CLI-Drivers.md +29 -12
  13. data/documentation/Configuration.md +92 -65
  14. data/documentation/Contributing.md +14 -4
  15. data/documentation/Cron.md +5 -5
  16. data/documentation/Diagrams.md +4 -4
  17. data/documentation/Drivers.md +4 -4
  18. data/documentation/Extrospection.md +162 -152
  19. data/documentation/FFI.md +61 -24
  20. data/documentation/Fuzzing.md +4 -1
  21. data/documentation/General-PWN-Usage.md +13 -1
  22. data/documentation/Hardware.md +11 -7
  23. data/documentation/Home.md +9 -9
  24. data/documentation/How-PWN-Works.md +13 -12
  25. data/documentation/Installation.md +201 -37
  26. data/documentation/Metasploit.md +7 -4
  27. data/documentation/Mistakes.md +22 -22
  28. data/documentation/NmapIt.md +3 -0
  29. data/documentation/Persistence.md +8 -5
  30. data/documentation/Plugins.md +11 -11
  31. data/documentation/Reporting.md +5 -2
  32. data/documentation/SAST.md +1 -1
  33. data/documentation/SDR.md +55 -17
  34. data/documentation/Sessions.md +5 -5
  35. data/documentation/Skills-Memory-Learning.md +82 -69
  36. data/documentation/Swarm.md +26 -6
  37. data/documentation/Transparent-Browser.md +11 -8
  38. data/documentation/Troubleshooting.md +66 -10
  39. data/documentation/WWW.md +2 -2
  40. data/documentation/What-is-PWN.md +11 -11
  41. data/documentation/Why-PWN.md +4 -4
  42. data/documentation/diagrams/agent-tool-registry.svg +120 -109
  43. data/documentation/diagrams/ai-integration-tool-calling.svg +76 -65
  44. data/documentation/diagrams/aws-cloud-security.svg +1 -1
  45. data/documentation/diagrams/burp-vs-zap-preference.svg +27 -27
  46. data/documentation/diagrams/code-scanning-sast.svg +1 -1
  47. data/documentation/diagrams/cron-scheduling.svg +1 -1
  48. data/documentation/diagrams/dot/_THEME.md +1 -1
  49. data/documentation/diagrams/dot/agent-tool-registry.dot +6 -4
  50. data/documentation/diagrams/dot/ai-integration-tool-calling.dot +4 -3
  51. data/documentation/diagrams/dot/aws-cloud-security.dot +1 -1
  52. data/documentation/diagrams/dot/burp-vs-zap-preference.dot +1 -1
  53. data/documentation/diagrams/dot/code-scanning-sast.dot +1 -1
  54. data/documentation/diagrams/dot/cron-scheduling.dot +1 -1
  55. data/documentation/diagrams/dot/driver-framework.dot +1 -1
  56. data/documentation/diagrams/dot/extrospection-world-awareness.dot +1 -1
  57. data/documentation/diagrams/dot/history-to-drivers.dot +1 -1
  58. data/documentation/diagrams/dot/memory-skills-detailed.dot +27 -5
  59. data/documentation/diagrams/dot/mistakes-negative-feedback.dot +6 -6
  60. data/documentation/diagrams/dot/overall-pwn-architecture.dot +7 -5
  61. data/documentation/diagrams/dot/persistence-filesystem.dot +6 -4
  62. data/documentation/diagrams/dot/plugin-ecosystem.dot +1 -1
  63. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +31 -10
  64. data/documentation/diagrams/dot/pwn-repl-prototyping.dot +1 -1
  65. data/documentation/diagrams/dot/reporting-pipeline.dot +1 -1
  66. data/documentation/diagrams/dot/sdr-radio-flow.dot +16 -12
  67. data/documentation/diagrams/dot/sessions-cron-automation.dot +1 -1
  68. data/documentation/diagrams/dot/swarm-multi-agent.dot +8 -2
  69. data/documentation/diagrams/driver-framework.svg +1 -1
  70. data/documentation/diagrams/extrospection-world-awareness.svg +129 -129
  71. data/documentation/diagrams/history-to-drivers.svg +32 -32
  72. data/documentation/diagrams/memory-skills-detailed.svg +268 -137
  73. data/documentation/diagrams/mistakes-negative-feedback.svg +51 -51
  74. data/documentation/diagrams/overall-pwn-architecture.svg +188 -171
  75. data/documentation/diagrams/persistence-filesystem.svg +120 -89
  76. data/documentation/diagrams/plugin-ecosystem.svg +1 -1
  77. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +407 -255
  78. data/documentation/diagrams/pwn-repl-prototyping.svg +1 -1
  79. data/documentation/diagrams/reporting-pipeline.svg +1 -1
  80. data/documentation/diagrams/sdr-radio-flow.svg +181 -146
  81. data/documentation/diagrams/sessions-cron-automation.svg +1 -1
  82. data/documentation/diagrams/swarm-multi-agent.svg +156 -119
  83. data/documentation/pwn-REPL.md +8 -7
  84. data/documentation/pwn-ai-Agent.md +57 -29
  85. data/lib/pwn/ai/agent/dispatch.rb +1 -1
  86. data/lib/pwn/ai/agent/extrospection.rb +39 -39
  87. data/lib/pwn/ai/agent/learning.rb +1 -1
  88. data/lib/pwn/ai/agent/loop.rb +40 -0
  89. data/lib/pwn/ai/agent/metrics.rb +1 -1
  90. data/lib/pwn/ai/agent/tools/extrospection.rb +20 -20
  91. data/lib/pwn/config.rb +3 -3
  92. data/lib/pwn/ffi/hack_rf.rb +119 -0
  93. data/lib/pwn/ffi/soapy_sdr.rb +165 -3
  94. data/lib/pwn/memory_index.rb +1 -1
  95. data/lib/pwn/plugins/repl.rb +26 -2
  96. data/lib/pwn/sdr/decoder/adsb.rb +1 -1
  97. data/lib/pwn/sdr/decoder/base.rb +30 -16
  98. data/lib/pwn/sdr/decoder/flex.rb +378 -120
  99. data/lib/pwn/sdr/decoder/rtl433.rb +1 -1
  100. data/lib/pwn/sdr/decoder/rtty.rb +1 -1
  101. data/lib/pwn/sdr/decoder.rb +1 -1
  102. data/lib/pwn/sdr/gqrx.rb +7 -7
  103. data/lib/pwn/setup.rb +563 -0
  104. data/lib/pwn/version.rb +1 -1
  105. data/lib/pwn.rb +1 -0
  106. data/spec/lib/pwn/sdr/decoder/flex_spec.rb +67 -0
  107. data/spec/lib/pwn/setup_spec.rb +28 -0
  108. data/third_party/pwn_rdoc.jsonl +40 -12
  109. metadata +5 -1
@@ -1,4 +1,4 @@
1
- # Extrospection World Awareness (on-demand sensing)
1
+ # Extrospection - World Awareness (on-demand sensing)
2
2
 
3
3
  `PWN::AI::Agent::Extrospection` is the **outward-facing** counterpart to
4
4
  [Learning](Skills-Memory-Learning.md). Where Learning/Metrics/Mistakes ask
@@ -7,7 +7,7 @@ say when I need it for a better answer?"*
7
7
 
8
8
  **Primary intent = sense tools on demand**, not ambient inventory of the local host.
9
9
 
10
- | You need | Call |
10
+ | You need... | Call... |
11
11
  |---|---|
12
12
  | Weather / public page content | `extro_watch` / `extro_verify` / TransparentBrowser |
13
13
  | Song on 101.1 FM (RDS) | **`extro_rf_tune(freq: "101.1")`** → RDS `now_playing` / `station` |
@@ -20,14 +20,14 @@ say when I need it for a better answer?"*
20
20
  | OCR image / barcode-QR | **`extro_vision`** |
21
21
  | Text-to-speech / speech-to-text | **`extro_voice`** |
22
22
 
23
- **Secondary** cheap ambient baseline (`snapshot` / `drift` / `correlate`) so the
23
+ **Secondary** - cheap ambient baseline (`snapshot` / `drift` / `correlate`) so the
24
24
  agent can distinguish "I called the API wrong" from "the world moved"
25
25
  (kernel upgrade, dongle unplugged). That baseline must never launch GUI / JVM /
26
26
  heavy REPL binaries.
27
27
 
28
28
  ![Extrospection engine](diagrams/extrospection-world-awareness.svg)
29
29
 
30
- ## Snapshot sections (`extro_snapshot(sections: [])`)
30
+ ## Snapshot sections (`extro_snapshot(sections: [...])`)
31
31
 
32
32
  | Section | Probe | Captures | Auto? |
33
33
  |---|---|---|---|
@@ -38,7 +38,7 @@ heavy REPL binaries.
38
38
  | `:env` | `probe_env` | ruby / gem / bundler / PWN version / AI engine | ✅ `AUTO_SECTIONS` |
39
39
  | **`:rf`** | **`probe_rf`** | **RTL-SDR / HackRF presence · SoapySDR · GQRX sock · Flipper · serial · band-plans** | ❌ on-demand |
40
40
  | **`:web`** | **`probe_web`** | **Headless render of `web_anchors` (status / title / DOM sha / TLS / screenshot)** | ❌ on-demand |
41
- | **`:osint`** | **`probe_osint`** | **Public OSINT feed catalogue · keyed flags (Shodan/Hunter) · whois/dig bins** | ❌ on-demand |
41
+ | **`:osint`** | **`probe_osint`** | **Public OSINT feed catalog · keyed flags (Shodan/Hunter) · whois/dig bins** | ❌ on-demand |
42
42
  | **`:serial`** | **`probe_serial`** | **`/dev/ttyUSB*` `/dev/ttyACM*` · by-id · minicom/picocom presence** | ❌ on-demand |
43
43
  | **`:telecomm`** | **`probe_telecomm`** | **BareSIP HTTP · SIP ports · baresip/asterisk/linphone bins** | ❌ on-demand |
44
44
  | **`:packet`** | **`probe_packet`** | **tshark/tcpdump/tcpreplay · ifaces · cap dir** | ❌ on-demand |
@@ -49,7 +49,7 @@ heavy REPL binaries.
49
49
 
50
50
  ```ruby
51
51
  SAFE_VERSION_BINS = %w[nmap curl git ruby python3 gcc openssl docker] # --version OK
52
- PRESENCE_ONLY_BINS = %w[burpsuite zaproxy msfconsole gqrx sqlmap] # path only NEVER spawn
52
+ PRESENCE_ONLY_BINS = %w[burpsuite zaproxy msfconsole gqrx sqlmap] # path only - NEVER spawn
53
53
  RF_BINS = %w[rtl_sdr rtl_test rtl_433 hackrf_info gqrx dump1090 multimon-ng SoapySDRUtil]
54
54
  OSINT_BINS = %w[whois dig host curl jq]
55
55
  SERIAL_BINS = %w[minicom picocom screen cu]
@@ -60,7 +60,7 @@ VOICE_BINS = %w[sox espeak-ng espeak festival whisper spd-say arecord ap
60
60
  AUTO_SECTIONS = %i[host repo env] # what auto_extrospect actually runs
61
61
  ```
62
62
 
63
- `burpsuite` is a Java launcher (`run_java -jar …/burpsuite.jar`). Running it for
63
+ `burpsuite` is a Java launcher (`run_java -jar .../burpsuite.jar`). Running it for
64
64
  `--version` opens the real GUI → splash screen after every pwn-ai turn when
65
65
  `auto_extrospect` was wiring `probe_toolchain` into the default section set.
66
66
  **That was the bug.** Presence-only bins + `AUTO_SECTIONS` remove it.
@@ -74,9 +74,9 @@ Override / extend via `PWN::Env[:ai][:agent][:extrospection][:web][:anchors]`; s
74
74
  | Tool | Does | Persists to |
75
75
  |---|---|---|
76
76
  | `extro_snapshot` | Fingerprint host/net/toolchain/repo/env/**rf**/*web* → hash | `extrospection.json` (`snapshot` + rotates `previous`) |
77
- | `extro_drift` | Diff live-vs-stored (or stored-vs-previous) | returns `{changed, added, removed}` with dotted keys |
78
- | `extro_observe` | Record a fact `category:` one of `recon vuln intel target network env` **`rf` `web` `osint` `serial` `telecomm` `packet` `vision` `voice`** `misc` | `observations[]` |
79
- | `extro_observations` | Query recorded facts by source/category/target/tag | |
77
+ | `extro_drift` | Diff live-vs-stored (or stored-vs-previous) | - returns `{changed, added, removed}` with dotted keys |
78
+ | `extro_observe` | Record a fact - `category:` one of `recon vuln intel target network env` **`rf` `web` `osint` `serial` `telecomm` `packet` `vision` `voice`** `misc` | `observations[]` |
79
+ | `extro_observations` | Query recorded facts by source/category/target/tag | - |
80
80
  | `extro_intel` | Query NVD / CIRCL / Exploit-DB for keyword or CVE | optional `record: true` → `:intel` observations |
81
81
  | **`extro_watch`** | **Render a URL headless, hash the *rendered* DOM, screenshot, diff vs prior** | `observations[]` (`category: :web`) |
82
82
  | **`extro_verify`** | **Browser-backed self fact-check of a claim (`:cve` `:version` `:doc` `:generic`) → `:confirmed`/`:refuted`/`:unknown`** | `Mistakes.record` / `observe(:intel)` / `Learning.note_outcome` |
@@ -87,12 +87,12 @@ Override / extend via `PWN::Env[:ai][:agent][:extrospection][:web][:anchors]`; s
87
87
  | **`extro_packet`** | **Inventory · bounded live capture · pcap summarise (tshark/PacketFu)** | `observations[]` (`category: :packet`) |
88
88
  | **`extro_vision`** | **OCR (tesseract/RTesseract) · barcode/QR (zbarimg)** | `observations[]` (`category: :vision`) |
89
89
  | **`extro_voice`** | **TTS (espeak-ng/festival/spd-say) · STT (whisper) · inventory** | `observations[]` (`category: :voice`) |
90
- | `extro_correlate` | **Join** introspection ↔ extrospection | actionable findings |
91
- | `extro_stats` | snapshot age · observation count · drift counts · **rf_devices** · **web_anchors** | |
92
- | `extro_reset` | Wipe snapshot + observations (new engagement) | |
90
+ | `extro_correlate` | **Join** introspection ↔ extrospection | - actionable findings |
91
+ | `extro_stats` | snapshot age · observation count · drift counts · **rf_devices** · **web_anchors** | - |
92
+ | `extro_reset` | Wipe snapshot + observations (new engagement) | - |
93
93
  | `extro_auto_toggle` | Enable/disable ambient baseline (`AUTO_SECTIONS` only) after every final answer | `PWN::Env[:ai][:agent][:auto_extrospect]` |
94
94
 
95
- ## `extro_correlate` the point of the whole thing
95
+ ## `extro_correlate` - the point of the whole thing
96
96
 
97
97
  ```text
98
98
  (a) Metrics tools with <50 % success × toolchain drift / missing binaries
@@ -106,11 +106,11 @@ Override / extend via `PWN::Env[:ai][:agent][:extrospection][:web][:anchors]`; s
106
106
 
107
107
  Output tells the agent whether a failure was **its own fault** ("I called the
108
108
  API wrong" → belongs in [Mistakes](Mistakes.md)) or **the world changed**
109
- ("nmap was upgraded and the flag moved", "the HackRF was unplugged") and
109
+ ("nmap was upgraded and the flag moved", "the HackRF was unplugged") - and
110
110
  that distinction is written back into MEMORY so the next run doesn't waste
111
111
  iterations rediscovering it.
112
112
 
113
- ## `extro_verify` proactive fact-checking (the browser as a sense organ)
113
+ ## `extro_verify` - proactive fact-checking (the browser as a sense organ)
114
114
 
115
115
  `probe_rf` is a passive **ear inventory**; `extro_rf_tune` actually **listens** (tune + RDS). `PWN::Plugins::TransparentBrowser` gives Extrospection **eyes**. `extro_verify(claim:)` renders a canonical source *with JavaScript
116
116
  executed* and returns a verdict:
@@ -123,7 +123,7 @@ executed* and returns a verdict:
123
123
  | `:generic` | DuckDuckGo HTML (proxy-able, no API key) | ≥ 50 % token overlap in top result snippets |
124
124
 
125
125
  ```text
126
- ┌── :refuted → Mistakes.record(tool:'assumption', ) → KNOWN MISTAKES block ∀ future runs
126
+ ┌── :refuted → Mistakes.record(tool:'assumption', ...) → KNOWN MISTAKES block ∀ future runs
127
127
  extro_verify ─────┼── :confirmed→ observe(category::intel, ttl:30d) → EXTROSPECTION block, freshness-bound
128
128
  └── :unknown → Learning.note_outcome(tags:[needs_human])
129
129
  ```
@@ -134,13 +134,13 @@ This adds a **proactive** trigger to the negative-feedback loop: today
134
134
  the world **before** a human does. `commit: false` returns the verdict without
135
135
  side-effects.
136
136
 
137
- ## `extro_rf_tune` the radio as a sense organ
137
+ ## `extro_rf_tune` - the radio as a sense organ
138
138
 
139
139
  `probe_rf` is a **passive inventory** (what radios are attached / is GQRX
140
- listening?). `extro_rf_tune` is the **active RF sense organ** the radio
140
+ listening?). `extro_rf_tune` is the **active RF sense organ** - the radio
141
141
  analogue of `extro_watch` / `extro_verify`. It never launches GQRX (presence-
142
142
  only bin); it connects to an already-running remote-control socket, tunes,
143
- demodulates, measures strength, and for FM broadcast samples RDS:
143
+ demodulates, measures strength, and - for FM broadcast - samples RDS:
144
144
 
145
145
  ```text
146
146
  extro_rf_tune(freq: "101.1")
@@ -148,7 +148,7 @@ extro_rf_tune(freq: "101.1")
148
148
  → M WFM_ST 200000 ; F 101100000
149
149
  → sample RDS for settle_secs (default 8s)
150
150
  → { ok, freq, strength_dbfs, station, now_playing, rds:{pi,ps_name,radiotext}, summary }
151
- → observe(category: :rf, ttl: 300) # ephemeral songs change
151
+ → observe(category: :rf, ttl: 300) # ephemeral - songs change
152
152
  ```
153
153
 
154
154
  RDS sampling is **`PWN::SDR::Decoder::RDS.sample`** (non-interactive Hash:
@@ -164,7 +164,7 @@ Frequency parsing is free-form: `"101.1"`, `"101.1 FM"`, `"101.1 MHz"`,
164
164
  etc.). Override with `demodulator_mode:` / `bandwidth:` / `rds:`.
165
165
 
166
166
  Requires GQRX remote control listening and an SDR attached; returns
167
- `{ok:false, advice:…}` with a concrete recovery hint otherwise. Configure:
167
+ `{ok:false, advice:...}` with a concrete recovery hint otherwise. Configure:
168
168
 
169
169
  ```ruby
170
170
  PWN::Env[:ai][:agent][:extrospection][:rf] = {
@@ -172,12 +172,12 @@ PWN::Env[:ai][:agent][:extrospection][:rf] = {
172
172
  }
173
173
  ```
174
174
 
175
- ## `extro_osint` OSINT sense organ
175
+ ## `extro_osint` - OSINT sense organ
176
176
 
177
177
  Aggregates as many **public / free** OSINT APIs as practical into one verb.
178
178
  Optional keyed feeds (Shodan / Hunter) unlock when `SHODAN_API_KEY` /
179
- `HUNTER_API_KEY` or `PWN::Env` keys are present. Every feed is best-effort
180
- unreachable endpoints return `{error:…}` instead of raising.
179
+ `HUNTER_API_KEY` or `PWN::Env` keys are present. Every feed is best-effort -
180
+ unreachable endpoints return `{error:...}` instead of raising.
181
181
 
182
182
  ### Auto-detected kinds
183
183
 
@@ -186,14 +186,14 @@ unreachable endpoints return `{error:…}` instead of raising.
186
186
  | `:ip` | IPv4 / IPv6 | ip · geo · ipapi_is · iplocate · ipwhois · dns · rdap · bgpview · otx · abuseipdb · greynoise · shodan · hackertarget |
187
187
  | `:geo` | street-like address / geo query | geo · nominatim · ip |
188
188
  | `:domain` / `:dns` / `:whois` / `:rdap` | FQDN | dns · whois · rdap · crtsh · certspotter · wayback · otx · urlhaus · urlscan · shodan · securitytrails · hackertarget |
189
- | `:url` | `http(s)://…` | urlscan · otx · urlhaus · wayback · microlink · virustotal |
189
+ | `:url` | `http(s)://...` | urlscan · otx · urlhaus · wayback · microlink · virustotal |
190
190
  | `:email` | `a@b.c` | hunter · person · github · haveibeenpwned |
191
191
  | `:phone` | E.164 / NANP | phone · person |
192
192
  | `:fcc_id` | `2ABIP-ESP32` style | fcc_id |
193
- | `:patent` | `US10123456` / `patent …` | patent |
193
+ | `:patent` | `US10123456` / `patent ...` | patent |
194
194
  | `:person` | `Jane Doe` | person · username · github · open_sanctions · agify · genderize · nationalize · vital_records |
195
195
  | `:username` / `:github` | `@handle` / `gh:` | username · github |
196
- | `:company` | `… Inc.` / `LLC` / `Ltd` | opencorporates · sec_edgar · federal_register · person · courtlistener |
196
+ | `:company` | `... Inc.` / `LLC` / `Ltd` | opencorporates · sec_edgar · federal_register · person · courtlistener |
197
197
  | `:cik` | 10-digit CIK | sec_edgar · opencorporates |
198
198
  | `:vital_records` | birth/death/marriage keywords | vital_records · person |
199
199
  | `:threat` | forced | otx · urlhaus · threatfox · abuseipdb · greynoise · virustotal · epss · cisa_kev |
@@ -204,7 +204,7 @@ unreachable endpoints return `{error:…}` instead of raising.
204
204
  | `:npi` | `NPI 1679576722` (prefixed) | nppes |
205
205
  | `:cve` | `CVE-YYYY-NNNN` | epss · cisa_kev |
206
206
 
207
- ### Public feed catalogue (no key unless noted)
207
+ ### Public feed catalog (no key unless noted)
208
208
 
209
209
  | Feed | Sources | Notes |
210
210
  |---|---|---|
@@ -236,8 +236,8 @@ unreachable endpoints return `{error:…}` instead of raising.
236
236
  | `:ipapi_is` | api.ipapi.is | IP company/ASN/hosting/proxy/crawler flags (free) |
237
237
  | `:iplocate` | iplocate.io | IP geo + threat (proxy/VPN/hosting) |
238
238
  | `:ipwhois` | ipwho.is | Free IP geo / connection / timezone |
239
- | `:abuseipdb` | api.abuseipdb.com | IP reputation **needs** `ABUSEIPDB_API_KEY` |
240
- | `:virustotal` | virustotal.com API v3 | URL/domain/IP analysis **needs** `VIRUSTOTAL_API_KEY` |
239
+ | `:abuseipdb` | api.abuseipdb.com | IP reputation - **needs** `ABUSEIPDB_API_KEY` |
240
+ | `:virustotal` | virustotal.com API v3 | URL/domain/IP analysis - **needs** `VIRUSTOTAL_API_KEY` |
241
241
  | `:greynoise` | greynoise.io community / v2 | Internet scanner noise (community free; key upgrades) |
242
242
  | `:certspotter` | api.certspotter.com | Certificate Transparency issuances |
243
243
  | `:epss` | api.first.org/data/v1/epss | Exploit Prediction Scoring System for a CVE |
@@ -245,14 +245,14 @@ unreachable endpoints return `{error:…}` instead of raising.
245
245
  | `:nhtsa` | vpic.nhtsa.dot.gov + `PWN::Plugins::VIN` | VIN decode / make-model |
246
246
  | `:nppes` | npiregistry.cms.hhs.gov | US healthcare NPI provider lookup |
247
247
  | `:federal_register` | federalregister.gov API | US Federal Register document search |
248
- | `:uk_police` | data.police.uk | UK street-level crime / force catalogue |
248
+ | `:uk_police` | data.police.uk | UK street-level crime / force catalog |
249
249
  | `:callook` | callook.info | US amateur-radio callsign (FCC ULS) |
250
250
  | `:mac_vendor` | maclookup.app · macvendors.com | MAC OUI → vendor |
251
251
  | `:universities` | universities.hipolabs.com | University name / domain / country |
252
252
  | `:microlink` | api.microlink.io | Link unfurl (OG title/desc/image) |
253
253
  | `:agify` / `:genderize` / `:nationalize` | agify.io · genderize.io · nationalize.io | First-name age/gender/nationality estimates |
254
- | `:haveibeenpwned` | haveibeenpwned.com v3 | Breach membership **needs** `HIBP_API_KEY` |
255
- | `:securitytrails` | api.securitytrails.com | Domain DNS history **needs** `SECURITYTRAILS_API_KEY` |
254
+ | `:haveibeenpwned` | haveibeenpwned.com v3 | Breach membership - **needs** `HIBP_API_KEY` |
255
+ | `:securitytrails` | api.securitytrails.com | Domain DNS history - **needs** `SECURITYTRAILS_API_KEY` |
256
256
 
257
257
  > Feed selection inspired by [public-api-lists/public-api-lists](https://github.com/public-api-lists/public-api-lists) (Anti-Malware, Security, Geocoding, Government, Health, Open Data, Vehicle, Development).
258
258
 
@@ -302,13 +302,13 @@ Configure:
302
302
  PWN::Env[:ai][:agent][:extrospection][:osint] = {
303
303
  ttl: 86_400,
304
304
  api_keys: {
305
- shodan: '',
306
- hunter: '',
307
- abuseipdb: '',
308
- virustotal: '',
309
- greynoise: '',
310
- haveibeenpwned: '',
311
- securitytrails: ''
305
+ shodan: '...',
306
+ hunter: '...',
307
+ abuseipdb: '...',
308
+ virustotal: '...',
309
+ greynoise: '...',
310
+ haveibeenpwned: '...',
311
+ securitytrails: '...'
312
312
  }
313
313
  }
314
314
  # ENV fallbacks also accepted:
@@ -317,7 +317,7 @@ PWN::Env[:ai][:agent][:extrospection][:osint] = {
317
317
  ```
318
318
 
319
319
 
320
- ## `extro_serial` Serial sense organ
320
+ ## `extro_serial` - Serial sense organ
321
321
 
322
322
  Passive inventory via `snapshot(sections: [:serial])` (`/dev/ttyUSB*`,
323
323
  `/dev/ttyACM*`, `/dev/serial/by-id/*`). The active verb opens a device through
@@ -331,7 +331,7 @@ extro_serial(block_dev: "/dev/ttyUSB0", baud: 115200, payload: "ATI\r")
331
331
  → observe(category: :serial)
332
332
  ```
333
333
 
334
- ## `extro_telecomm` SIP / VoIP / PSTN sense organ
334
+ ## `extro_telecomm` - SIP / VoIP / PSTN sense organ
335
335
 
336
336
  Telecomm analogue of `extro_rf_tune`. Talks to a **running** BareSIP HTTP
337
337
  control socket (never launches it). Actions:
@@ -339,7 +339,7 @@ control socket (never launches it). Actions:
339
339
  | action | Effect |
340
340
  |---|---|
341
341
  | `:inventory` / `:status` | bins · SIP listen ports · BareSIP HTTP reachability · status text |
342
- | `:dial` | require `target:` SIP URI or E.164 **OPSEC: real call** |
342
+ | `:dial` | require `target:` SIP URI or E.164 - **OPSEC: real call** |
343
343
  | `:hangup` | hang up active call |
344
344
 
345
345
  ```ruby
@@ -348,7 +348,7 @@ PWN::Env[:ai][:agent][:extrospection][:telecomm] = {
348
348
  }
349
349
  ```
350
350
 
351
- ## `extro_packet` Packet sense organ
351
+ ## `extro_packet` - Packet sense organ
352
352
 
353
353
  Bounded L2/L3 sensing via `tshark` / `tcpdump` + pcap summarisation through
354
354
  `PWN::Plugins::Packet` / tshark hierarchy & conversations:
@@ -362,7 +362,7 @@ Bounded L2/L3 sensing via `tshark` / `tcpdump` + pcap summarisation through
362
362
  Capture is hard-capped (`count` ≤ 200, `timeout` ≤ 60s) so the agent never
363
363
  hangs mid-turn.
364
364
 
365
- ## `extro_vision` Vision / OCR sense organ
365
+ ## `extro_vision` - Vision / OCR sense organ
366
366
 
367
367
  Eyes on the host:
368
368
 
@@ -377,7 +377,7 @@ extro_vision(file: "/tmp/shot.png", action: :ocr)
377
377
  → { text, chars, preview } → observe(category: :vision)
378
378
  ```
379
379
 
380
- ## `extro_voice` Voice (TTS / STT) sense organ
380
+ ## `extro_voice` - Voice (TTS / STT) sense organ
381
381
 
382
382
  | action | Backend |
383
383
  |---|---|
@@ -385,9 +385,9 @@ extro_vision(file: "/tmp/shot.png", action: :ocr)
385
385
  | `:stt` | OpenAI whisper binary / `PWN::Plugins::Voice.speech_to_text` |
386
386
  | `:inventory` | VOICE_BINS presence |
387
387
 
388
- Artefacts land under `~/.pwn/extrospection/voice/`.
388
+ Artifacts land under `~/.pwn/extrospection/voice/`.
389
389
 
390
- ## `revalidate_memory` the browser as GC for `PWN::Memory`
390
+ ## `revalidate_memory` - the browser as GC for `PWN::Memory`
391
391
 
392
392
 
393
393
  `learning_consolidate` only dedupes/truncates; it never asks *"is this still
@@ -405,8 +405,8 @@ cron_create(name: 'memory_revalidate', schedule: '0 4 * * 0',
405
405
 
406
406
  ```ruby
407
407
  PWN::Env[:ai][:agent][:extrospection][:web] = {
408
- anchors: ['https://target.acme/api/version', ], # else DEFAULT_WEB_ANCHORS
409
- proxy: 'tor', # or 'http://127.0.0.1:8080' (Burp) honoured by verify/watch/probe_web
408
+ anchors: ['https://target.acme/api/version', ...], # else DEFAULT_WEB_ANCHORS
409
+ proxy: 'tor', # or 'http://127.0.0.1:8080' (Burp) - honoured by verify/watch/probe_web
410
410
  max_anchors: 8,
411
411
  per_page_timeout: 15,
412
412
  screenshot: false, # → ~/.pwn/extrospection/web/<host>.png
@@ -420,11 +420,11 @@ PWN::Env[:ai][:agent][:extrospection][:web] = {
420
420
  ```ruby
421
421
  extro_reset(confirm: true) # clean slate for new scope
422
422
  extro_snapshot # baseline (host/net/toolchain/repo/env/rf; add sections:%i[web] for anchors)
423
- # recon
423
+ # ... recon ...
424
424
  extro_observe(source: 'nmap', target: '10.0.0.5',
425
425
  category: 'recon', data: 'OpenSSH 8.2p1 Ubuntu')
426
426
  extro_observe(source: 'gqrx', target: '433.920MHz',
427
- category: 'rf', data: 'peak -34.2 dBFS bw=200k FSK likely garage remote')
427
+ category: 'rf', data: 'peak -34.2 dBFS bw=200k FSK - likely garage remote')
428
428
  extro_rf_tune(freq: '101.1') # live RDS → now_playing / station (category: :rf)
429
429
  extro_osint(query: '10.0.0.5', kind: :ip)
430
430
  extro_osint(query: '2ABIP-ESP32', kind: :fcc_id)
@@ -435,149 +435,159 @@ extro_voice(action: :tts, text: 'recon complete')
435
435
  extro_intel(query: 'OpenSSH 8.2p1', record: true)
436
436
  extro_watch(url: 'https://target.acme/api/version') # DOM-hash + screenshot; changed:true on next run
437
437
  extro_verify(claim: 'CVE-2026-12345 affects OpenSSL 3.2.1') # → Mistakes/Memory/observe on verdict
438
- # days later, something breaks
438
+ # ... days later, something breaks ...
439
439
  extro_drift # what moved?
440
440
  extro_correlate # why did it break?
441
441
  ```
442
442
 
443
443
  ## Example questions that trigger Extrospection
444
444
 
445
- Natural-language prompts that should fire **outward** sensing (grouped by sense organ).
446
- Location-specific details use **Chicago** as the canonical city so the catalog stays
447
- portable across deployments.
448
-
449
- ### RF sense organ (`extro_rf_tune` + RF observations)
450
-
451
- - “What’s playing on 101.1 right now?”
452
- - “What’s on Q101 / 101.1 FM in Chicago?”
453
- - “Is NOAA weather radio for the Chicago area broadcasting an alert?”
454
- - “Tune 433.92 MHz and report signal strength.”
455
- - “Any ADS-B traffic near Chicago O’Hare (ORD) right now?”
456
- - Sample RDS on 93.1 for 15 seconds station name and radiotext?”
457
- - “Is the local Chicago 2 m repeater on 146.x active?”
458
-
459
- ### Web sense organ (`extro_watch`, `extro_verify`, `snapshot(sections: [:web])`)
460
-
461
- - “Did the vendor status page change since last check?”
462
- - “Watch https://status.example.com for DOM changes.”
463
- - “Has the bug-bounty scope page been updated?”
464
- - “What’s the weather in Chicago today?” *(live external page)*
465
- - “Fingerprint that login portal’s generator / title / tech stack.”
466
- - “Screenshot + hash https://target/app/version for drift tracking.”
445
+ Natural-language prompts that should route to **outward** sensing rather than
446
+ introspection. These are phrased the way an offensive security researcher
447
+ actually asks them mid-engagement - attack-surface discovery, zero-day
448
+ hunting, hardware/RF poking, and disclosure prep. Location-specific examples
449
+ use **Chicago** so the catalog stays portable.
450
+
451
+ ### RF / SDR sense organ (`extro_rf_tune` + `:rf` observations)
452
+
453
+ - "Tune 433.92 MHz - is the target's garage/gate remote fixed-code or rolling?"
454
+ - "Sweep the 900 MHz ISM band near the badge reader and log anything > −40 dBFS."
455
+ - "What's broadcasting on 101.1 FM right now - grab RDS PI/PS so we can prove SDR is live."
456
+ - "Sample 868.3 MHz for 15 s - does the smart-meter mesh look like Wireless M-Bus?"
457
+ - "Any ADS-B traffic squawking over the client's campus (near ORD)?"
458
+ - "Listen on the pager band (929.x MHz) - are unencrypted POCSAG pages leaking PHI?"
459
+ - "Is the site's DMR/TETRA handheld traffic on 462.x actually encrypted?"
460
+ - "Park on 315 MHz and tell me if the target's TPMS / key-fob replays cleanly."
461
+
462
+ ### Web / browser sense organ (`extro_watch`, `extro_verify`, `snapshot(sections: [:web])`)
463
+
464
+ - "Watch the target's `/api/version` endpoint - alert me the moment the build string changes."
465
+ - "Has the vendor silently patched? Diff today's changelog DOM against our last hash."
466
+ - "Did the bug-bounty scope page add or drop assets since we baselined it?"
467
+ - "Fingerprint the login portal's JS bundle - framework, version, source-map leakage."
468
+ - "Screenshot + DOM-hash the admin panel so we can prove pre-auth state for the report."
469
+ - "Render the CSP/`.well-known/security.txt` and tell me who to disclose to."
470
+ - "Has the target's TLS cert or issuer rotated since the last watch?"
467
471
 
468
472
  ### OSINT sense organ (`extro_osint`)
469
473
 
470
- - “Reverse lookup +1 312 555 1212.”
471
- - Who is the registrant for example.com?”
472
- - “What device is FCC ID 2ABIP-ESP32?”
473
- - “Find patents related to software-defined radio receivers.”
474
- - “Pivot on username @octocat across GitHub/GitLab/Reddit.”
475
- - “Is Jane Doe listed on OpenSanctions / Wikipedia?”
476
- - “CT certs for target.acme via crt.sh.”
477
- - “ASN / BGP neighbours for 1.1.1.1.”
478
- - “Any Wayback snapshots of https://target.acme/login?”
474
+ - "Enumerate every subdomain for `*.target.tld` via CT logs (crt.sh + CertSpotter)."
475
+ - "Who owns AS-XXXXX and what netblocks does it announce - expand our in-scope ranges."
476
+ - "Pull EPSS + CISA KEV for CVE-2024-3094 - is this worth weaponising first?"
477
+ - "What's Shodan / GreyNoise saying about `203.0.113.10` - already mass-exploited?"
478
+ - "Decode this VIN off the fleet vehicle - what telematics head-unit ships in that trim?"
479
+ - "FCC ID `2ABIP-...` on the IoT doorbell - pull the internal photos and RF test report."
480
+ - "MAC OUI `AC:DE:48` on the rogue AP - which vendor, and do they have default creds?"
481
+ - "Any prior litigation or SEC 8-K breach filings for `Target Corp` before we disclose?"
482
+ - "Wayback the old `/admin` path - did an earlier deploy expose a debug console?"
483
+ - "Pivot `@lead-dev` across GitHub/GitLab - hardcoded secrets in personal repos?"
479
484
 
480
- ### Serial sense organ (`extro_serial`)
485
+ ### Serial / hardware sense organ (`extro_serial`)
481
486
 
482
- - What USB serial devices are attached?”
483
- - Send ATI to the modem on /dev/ttyUSB0 and show the banner.”
484
- - “Talk to the Flipper / RFID reader on ttyACM and dump response hex.”
485
- - Probe the Arduino console at 115200 8N1.”
487
+ - "What just enumerated on `/dev/ttyUSB*` when I plugged in the router's UART header?"
488
+ - "Send `AT+GMR` to the ESP32 on `/dev/ttyUSB0` - firmware version and SDK build?"
489
+ - "Dump the boot banner at 115200 8N1 - does it drop to an unauthenticated U-Boot shell?"
490
+ - "Probe the Flipper on `ttyACM0` and pull the last captured Sub-GHz raw."
491
+ - "Talk to the smart-lock's BLE-UART bridge and echo back whatever it volunteers."
486
492
 
487
- ### Telecomm sense organ (`extro_telecomm`)
493
+ ### Telecomm / VoIP sense organ (`extro_telecomm`)
488
494
 
489
- - Is BareSIP running and what is its status?”
490
- - “List SIP ports listening on this host.”
491
- - Dial sip:echo@example.com via BareSIP.” *(OPSEC: real call)*
492
- - Hang up the active VoIP call.”
495
+ - "Is BareSIP registered to the client's PBX, and what codecs did it negotiate?"
496
+ - "Enumerate SIP `OPTIONS` against the exposed SBC - does it leak `User-Agent`/version?"
497
+ - "Dial the IVR at `sip:ivr@target` and record the prompt tree for the social-eng playbook." *(OPSEC: real call)*
498
+ - "Hang up and note whether the PBX exposed internal extension ranges in the `BYE`."
493
499
 
494
500
  ### Packet sense organ (`extro_packet`)
495
501
 
496
- - “Inventory capture-capable interfaces and tshark/tcpdump.”
497
- - “Capture 20 packets on eth0 for tcp/443 and summarise.”
498
- - “Summarise this pcap: /tmp/eng.pcap.”
499
- - “What IP conversations dominate that capture?”
502
+ - "Capture 30 s on `eth0` while I trigger the IoT hub - what does it phone home to?"
503
+ - "Summarise `/tmp/eng.pcap` - top talkers, cleartext creds, weird ports."
504
+ - "BPF `udp port 5353` - is mDNS leaking hostnames and service records on the guest VLAN?"
505
+ - "Grab 50 packets of the OT segment - Modbus/TCP or something proprietary?"
506
+ - "Do we see the camera's RTSP creds in the clear during that capture?"
500
507
 
501
508
  ### Vision / OCR sense organ (`extro_vision`)
502
509
 
503
- - OCR this screenshot of the login page.”
504
- - Decode the QR code on /tmp/badge.png.”
505
- - “What languages does tesseract have installed?”
510
+ - "OCR the photo of the switch label - model, firmware, and default-cred sticker."
511
+ - "Decode the QR on the badge printer - is that a provisioning URL with an embedded token?"
512
+ - "OCR the BIOS/BMC screenshot and pull the exact firmware build for CVE matching."
513
+ - "Read the barcode on the HSM - serial + part number for supply-chain lookup."
506
514
 
507
515
  ### Voice sense organ (`extro_voice`)
508
516
 
509
- - “Speak ‘engagement complete’ via TTS.”
510
- - “Transcribe /tmp/voicemail.wav.”
511
- - “What TTS/STT engines are available on this host?”
517
+ - "Transcribe `/tmp/voicemail.wav` - did the helpdesk leak the temp-password format?"
518
+ - "STT the recorded IVR tree so we can grep it for extension numbers."
519
+ - "TTS this vishing pretext to a `.wav` for the approved social-engineering call."
520
+ - "Which STT/TTS engines are installed - can we run whisper offline on the drop box?"
512
521
 
513
522
  ### Fact-check / claim verification (`extro_verify`)
514
523
 
515
- - “Is CVE-2024-3094 still rated Critical on NVD?”
516
- - Confirm the latest `pwn` gem on RubyGems is 0.5.x.”
517
- - “Is it true that OpenSSH 9.8p1 is the current stable?”
518
- - “Verify this claim from the advisory against the official page.”
519
- - “Does that docs page actually say what we quoted?”
524
+ - "Before I file this: does CVE-2024-3094 actually list our target's distro package as affected?"
525
+ - "Confirm the latest upstream OpenSSH is 9.x - is the target's 8.2p1 genuinely EOL?"
526
+ - "Verify the vendor advisory URL really says 'remote unauthenticated' - quote it back."
527
+ - "Is `pwn` on RubyGems still at the version we ship in the report appendix?"
528
+ - "Fact-check my claim that this library has no maintained fork - search says otherwise?"
520
529
 
521
530
  ### Threat intel (`extro_intel` ± `record:true`)
522
531
 
523
- - Any known exploits for Apache 2.4.58?”
524
- - “Look up CVE-2025-XXXX across NVD / CIRCL / Exploit-DB.”
525
- - “What CVEs hit `libssl` in the last year?”
526
- - “Is there a public PoC for that JetBrains CVE?”
527
- - “Correlate installed nmap version against known CVEs.”
532
+ - "Any public PoC or Exploit-DB entry for the exact `nginx 1.25.3` build we bannered?"
533
+ - "Pull NVD + CIRCL for `libwebp` since 2023 - which are pre-auth RCE vs local?"
534
+ - "Cross-ref this router's firmware components against known-exploited (KEV)."
535
+ - "What's the newest CVE touching `Fortinet FortiOS` and is there an exploit module yet?"
536
+ - "Record everything for `Apache Struts` so `extro_correlate` can match our target stack."
528
537
 
529
538
  ### Host / env / toolchain drift (`extro_snapshot`, `extro_drift`, `extro_stats`)
530
539
 
531
- - “Did the environment change under us since last session?”
532
- - “Take a full extrospection snapshot and show drift.”
533
- - “Is nmap / gqrx / SoapySDR still the version we expect?”
534
- - “What’s listening on this host right now?”
535
- - Show toolchain + repo HEAD fingerprint.”
536
- - “Why did that tool start failing — world drift or operator error?” → pairs with `extro_correlate`
540
+ - "Snapshot the drop box before we start - I want a defensible 'this is what we brought' baseline."
541
+ - "Did anything on this attack host change overnight (kernel, nmap, listening ports)?"
542
+ - "Which offensive bins are actually present in PATH on this jump host?"
543
+ - "Is the SDR / HackRF still attached, or did the USB hub flake again?"
544
+ - "Show repo HEAD + dirty state so the finding is reproducible from a commit hash."
537
545
 
538
546
  ### Recon memory / observations (`extro_observe`, `extro_observations`)
539
547
 
540
- - Remember that target X bannered as nginx/1.25.3 on 443.”
541
- - “What recon findings do we have for 10.0.0.5?”
542
- - “List RF observations from today.”
543
- - “Any :web watches that changed this week?”
544
- - “Show intel hits we recorded against this product.”
548
+ - "Remember: `10.0.0.5:8443` self-signed CN leaks internal AD domain - tag `recon,pivot`."
549
+ - "Log the RF finding: 433.92 MHz fixed-code, 24-bit, replayable - tag `rf,physical`."
550
+ - "What have we already observed about `*.target.tld` this engagement?"
551
+ - "List every `:intel` observation still fresh so I don't re-run the same CVE queries."
552
+ - "Which `:web` watches flipped `changed:true` this week - silent patch candidates?"
545
553
 
546
- ### Correlation / am I wrong or did the world move?” (`extro_correlate`)
554
+ ### Correlation - "am I wrong or did the world move?" (`extro_correlate`)
547
555
 
548
- - “Cross-check recent tool failures against host/toolchain drift.”
549
- - “Did any of our recorded CVEs match installed package versions?”
550
- - “Is that failed shell call explained by missing binaries?”
551
- - “Any refuted claims that should invalidate old memory facts?”
556
+ - "My exploit stopped landing - did the target's DOM/TLS drift or did I break the payload?"
557
+ - "Cross recorded CVE intel against the versions we actually bannered on scope hosts."
558
+ - "Are any of my `PWN::Memory` facts about this target now refuted by fresh `extro_verify` runs?"
559
+ - "Do the `nmap`/`msf` failures line up with a toolchain upgrade rather than operator error?"
560
+ - "Which watched anchors went unreachable - down-weight intel sourced from them."
552
561
 
553
562
  ### Operational / lifecycle
554
563
 
555
- - “Enable ambient auto-extrospect after every answer.”
556
- - “Reset extrospection for a new engagement.” *(destructive)*
557
- - How stale is the current world snapshot?”
558
- - “Toggle auto-extrospect off while we fuzz.”
564
+ - "New engagement, new client - wipe extrospection so old recon doesn't bleed into this report." *(destructive)*
565
+ - "Turn ambient auto-extrospect **off** while I fuzz - I don't want baseline noise per turn."
566
+ - "How stale is our world snapshot - is it still from the pre-patch window?"
567
+ - "Re-enable auto-extrospect for the wrap-up so drift is captured in the final deliverable."
559
568
 
560
- ### Short trigger patterns the agent should recognize
569
+ ### Short trigger patterns the agent should recognize
561
570
 
562
571
  | Pattern | Likely tools |
563
- |--------|----------------|
564
- | “What’s on MHz / FM / station” | `extro_rf_tune` |
565
- | “Reverse phone / FCC ID / patent / whois / person” | `extro_osint` |
566
- | “Serial / AT modem / ttyUSB / Flipper console” | `extro_serial` |
567
- | SIP / VoIP / BareSIP / dial | `extro_telecomm` |
568
- | “Capture packets / summarise pcap | `extro_packet` |
569
- | OCR / barcode / QR this image” | `extro_vision` |
570
- | “Speak this / transcribe that audio” | `extro_voice` |
571
- | “Did page change / watch URL” | `extro_watch` |
572
- | “Is it true that / confirm CVE / latest version | `extro_verify` |
573
- | “Known vulns / CVE / exploit for…” | `extro_intel` |
574
- | “What changed on this host / drift” | `extro_snapshot` + `extro_drift` |
575
- | “Remember this finding about…” | `extro_observe` |
576
- | “Why did X start failing?” | `extro_correlate` + metrics/mistakes |
577
- | “Weather in Chicago / public page content” | `extro_watch` / TransparentBrowser |
572
+ |---|---|
573
+ | "tune / MHz / FM / RDS / ISM / key-fob / pager / ADS-B" | `extro_rf_tune` |
574
+ | "subdomain / CT log / ASN / whois / FCC ID / VIN / MAC OUI / EPSS / KEV / Wayback / pivot @user" | `extro_osint` |
575
+ | "UART / ttyUSB / U-Boot / AT command / Flipper / JTAG banner" | `extro_serial` |
576
+ | "SIP / PBX / IVR / BareSIP / dial / hangup" | `extro_telecomm` |
577
+ | "capture on iface / summarise pcap / mDNS / Modbus / RTSP creds" | `extro_packet` |
578
+ | "OCR sticker / decode QR / read badge / BIOS screenshot" | `extro_vision` |
579
+ | "transcribe wav / TTS pretext / whisper offline" | `extro_voice` |
580
+ | "watch URL / did the page change / silent patch / scope updated / TLS rotated" | `extro_watch` |
581
+ | "is it true that / confirm CVE / verify advisory / latest version of" | `extro_verify` |
582
+ | "known exploits for / any PoC / CVEs affecting / KEV for" | `extro_intel` |
583
+ | "what changed on this host / baseline the box / SDR still attached" | `extro_snapshot` + `extro_drift` |
584
+ | "remember this finding / what did we observe about / tag it recon" | `extro_observe` / `extro_observations` |
585
+ | "why did X stop working / my fault or theirs / down-weight that source" | `extro_correlate` |
586
+ | "new engagement clean slate / stop baselining while I fuzz" | `extro_reset` / `extro_auto_toggle` |
578
587
 
579
588
  The **inward** half of the loop (Memory · Skills · Learning · Mistakes · Metrics)
580
- has a matching example catalog in [Skills, Memory & Learning](Skills-Memory-Learning.md#example-questions-that-trigger-introspection).
589
+ has a matching example catalog in
590
+ [Skills, Memory & Learning](Skills-Memory-Learning.md#example-questions-that-trigger-introspection).
581
591
 
582
592
  **See also:** [Skills, Memory & Learning](Skills-Memory-Learning.md) ·
583
593
  [Mistakes](Mistakes.md) · [SDR](SDR.md) · [Transparent Browser](Transparent-Browser.md) · [Cron](Cron.md) · [pwn-ai Agent](pwn-ai-Agent.md)