pwn 0.5.780 → 0.5.782

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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/documentation/AI-Integration.md +4 -4
  4. data/documentation/AWS.md +10 -9
  5. data/documentation/Agent-Tool-Registry.md +20 -17
  6. data/documentation/Blockchain.md +3 -2
  7. data/documentation/Bounty.md +8 -6
  8. data/documentation/BurpSuite.md +6 -10
  9. data/documentation/CLI-Drivers.md +7 -4
  10. data/documentation/Capability-Broker-Sandbox.md +1 -1
  11. data/documentation/Configuration.md +23 -15
  12. data/documentation/Contributing.md +3 -3
  13. data/documentation/Cron.md +3 -2
  14. data/documentation/Diagrams.md +9 -3
  15. data/documentation/Drivers.md +12 -6
  16. data/documentation/Extrospection.md +25 -5
  17. data/documentation/FFI.md +15 -25
  18. data/documentation/Fuzzing.md +13 -13
  19. data/documentation/General-PWN-Usage.md +7 -4
  20. data/documentation/Harness-Evaluation.md +90 -3
  21. data/documentation/Home.md +6 -5
  22. data/documentation/How-PWN-Works.md +9 -10
  23. data/documentation/Installation.md +12 -11
  24. data/documentation/Metasploit.md +13 -19
  25. data/documentation/Mistakes.md +2 -2
  26. data/documentation/NmapIt.md +6 -3
  27. data/documentation/Operability.md +99 -0
  28. data/documentation/Persistence.md +3 -2
  29. data/documentation/Plugin-Degradation.md +4 -2
  30. data/documentation/Plugins.md +4 -11
  31. data/documentation/Policy-Benchmark.md +4 -0
  32. data/documentation/Reinforcement-Learning.md +19 -3
  33. data/documentation/Reporting.md +6 -5
  34. data/documentation/SAST.md +15 -10
  35. data/documentation/SDR-Decoder-Coverage.md +10 -4
  36. data/documentation/SDR.md +28 -40
  37. data/documentation/Session-Workflow.md +25 -12
  38. data/documentation/Sessions.md +7 -0
  39. data/documentation/Skills-Memory-Learning.md +11 -4
  40. data/documentation/Swarm.md +6 -0
  41. data/documentation/Transparent-Browser.md +1 -1
  42. data/documentation/Troubleshooting.md +6 -3
  43. data/documentation/What-is-PWN.md +4 -4
  44. data/documentation/Why-PWN.md +1 -1
  45. data/documentation/diagrams/agent-tool-registry.svg +219 -180
  46. data/documentation/diagrams/ai-integration-tool-calling.svg +35 -34
  47. data/documentation/diagrams/code-scanning-sast.svg +78 -78
  48. data/documentation/diagrams/cron-scheduling.svg +165 -145
  49. data/documentation/diagrams/dot/_THEME.md +6 -4
  50. data/documentation/diagrams/dot/agent-tool-registry.dot +6 -2
  51. data/documentation/diagrams/dot/ai-integration-tool-calling.dot +1 -1
  52. data/documentation/diagrams/dot/code-scanning-sast.dot +8 -8
  53. data/documentation/diagrams/dot/cron-scheduling.dot +2 -0
  54. data/documentation/diagrams/dot/driver-framework.dot +1 -1
  55. data/documentation/diagrams/dot/extrospection-world-awareness.dot +37 -92
  56. data/documentation/diagrams/dot/fuzzing-workflow.dot +3 -3
  57. data/documentation/diagrams/dot/history-to-drivers.dot +1 -1
  58. data/documentation/diagrams/dot/memory-skills-detailed.dot +33 -98
  59. data/documentation/diagrams/dot/mistakes-negative-feedback.dot +2 -2
  60. data/documentation/diagrams/dot/overall-pwn-architecture.dot +46 -112
  61. data/documentation/diagrams/dot/persistence-filesystem.dot +2 -2
  62. data/documentation/diagrams/dot/plugin-ecosystem.dot +2 -2
  63. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +44 -157
  64. data/documentation/diagrams/dot/pwn-repl-prototyping.dot +1 -1
  65. data/documentation/diagrams/dot/reinforcement-learning.dot +46 -103
  66. data/documentation/diagrams/dot/reporting-pipeline.dot +5 -3
  67. data/documentation/diagrams/dot/reverse-engineering-flow.dot +3 -3
  68. data/documentation/diagrams/dot/sdr-radio-flow.dot +5 -5
  69. data/documentation/diagrams/dot/sessions-cron-automation.dot +1 -1
  70. data/documentation/diagrams/dot/swarm-multi-agent.dot +36 -61
  71. data/documentation/diagrams/dot/task-summarizer.dot +2 -2
  72. data/documentation/diagrams/dot/web-application-testing.dot +4 -3
  73. data/documentation/diagrams/dot/zero-day-research-flow.dot +4 -3
  74. data/documentation/diagrams/driver-framework.svg +1 -1
  75. data/documentation/diagrams/extrospection-world-awareness.svg +139 -510
  76. data/documentation/diagrams/fuzzing-workflow.svg +58 -58
  77. data/documentation/diagrams/history-to-drivers.svg +42 -42
  78. data/documentation/diagrams/memory-skills-detailed.svg +126 -475
  79. data/documentation/diagrams/mistakes-negative-feedback.svg +116 -116
  80. data/documentation/diagrams/overall-pwn-architecture.svg +118 -424
  81. data/documentation/diagrams/persistence-filesystem.svg +143 -143
  82. data/documentation/diagrams/plugin-ecosystem.svg +100 -100
  83. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +164 -769
  84. data/documentation/diagrams/pwn-repl-prototyping.svg +27 -27
  85. data/documentation/diagrams/reinforcement-learning.svg +238 -455
  86. data/documentation/diagrams/reporting-pipeline.svg +94 -80
  87. data/documentation/diagrams/reverse-engineering-flow.svg +31 -31
  88. data/documentation/diagrams/sdr-radio-flow.svg +157 -155
  89. data/documentation/diagrams/sessions-cron-automation.svg +13 -13
  90. data/documentation/diagrams/swarm-multi-agent.svg +104 -233
  91. data/documentation/diagrams/task-summarizer.svg +57 -57
  92. data/documentation/diagrams/web-application-testing.svg +81 -75
  93. data/documentation/diagrams/zero-day-research-flow.svg +101 -92
  94. data/documentation/pwn-REPL.md +5 -3
  95. data/documentation/pwn-ai-Agent.md +18 -14
  96. data/documentation/pwn_silent_help_learn_demo.gif +0 -0
  97. data/etc/default_skills/pwn/ai/agent/learning/SKILL.md +1 -0
  98. data/lib/pwn/ai/agent/learning.rb +46 -1
  99. data/lib/pwn/ai/agent/policy_evaluation.rb +5 -1
  100. data/lib/pwn/ai/agent/reward.rb +9 -0
  101. data/lib/pwn/version.rb +1 -1
  102. data/spec/fixtures/harness/completion_regressions.json +10 -0
  103. data/spec/fixtures/harness/completion_regressions.json.sha256 +1 -0
  104. data/spec/integration/harness_evaluation_spec.rb +13 -0
  105. data/spec/lib/pwn/ai/agent/learning_spec.rb +22 -0
  106. data/spec/lib/pwn/ai/agent/policy_evaluation_spec.rb +6 -1
  107. data/spec/lib/pwn/ai/agent/reward_spec.rb +21 -0
  108. data/spec/support/harness/evaluate.rb +1 -1
  109. data/third_party/pwn_rdoc.jsonl +2 -1
  110. metadata +8 -5
data/documentation/FFI.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # `PWN::FFI` - Native Calls for DSP & RF Front-Ends
2
2
 
3
- Thin `ffi`-gem bindings to **already-installed** system shared objects. Nothing
4
- is compiled at `gem install` time, nothing shells out. If a `.so` is missing the
3
+ Thin `ffi`-gem bindings to **already-installed** system shared objects. The binding wrappers do not compile at `gem install` time or shell out.
4
+ Optional bundled DSP acceleration requires a separate explicit build. If a `.so` is missing the
5
5
  module still loads and `.available?` returns `false` so callers fall back to
6
6
  pure Ruby.
7
7
 
@@ -35,6 +35,8 @@ as `ok` / `MISSING` and knows the correct package name on `apt` / `dnf` /
35
35
  | **`HackRF`** | `libhackrf` | Open/tune/rate/gains + **callback RX streaming** (`start_rx`/`read_sync`/`stop_rx`/`capture`) of raw cs8 I/Q. |
36
36
  | **`AdalmPluto`** | `libiio` (+ `libad9361`) | ADALM-Pluto (ad9361-phy). `open`/`configure`/`start_rx`/`read_sync`/`stop_rx`/`capture` of cs16 I/Q; USB or `ip:192.168.2.1`. |
37
37
  | **`SoapySDR`** | `libSoapySDR` | Enumerate every Soapy-backed front-end (RTL-SDR, HackRF, Airspy, Pluto, LimeSDR, UHD, ...) **and** stream cs16 I/Q from any of them (`open`/`configure`/`start_rx`/`read_sync`/`stop_rx`/`close`). |
38
+ | `DSPNative` | bundled PWN DSP shared object | Optional packed DSP kernels; requires an explicit native build |
39
+ | `Capstone` / `Keystone` | libcapstone / libkeystone | Optional disassembly/assembly backends |
38
40
  | `Stdio` | `libc` | Classic `puts` / `printf` / `scanf` for shellcode / format-string research. |
39
41
 
40
42
  ## Design rules
@@ -44,8 +46,8 @@ as `ok` / `MISSING` and knows the correct package name on `apt` / `dnf` /
44
46
  2. **No install-time compile.** Use the system package (`libvolk-dev`,
45
47
  `libliquid-dev`, `libfftw3-dev`, `libhackrf-dev`, `libiio-dev`, ...). Install
46
48
  them all with **`pwn setup --profile sdr`** (see [Installation](Installation.md)).
47
- On hosts without them every `.available?` is `false` and pure-Ruby paths
48
- keep working.
49
+ Missing numerical backends can use supported Ruby fallbacks; missing
50
+ radio libraries cannot manufacture hardware I/O or protocol support.
49
51
  3. **Namespace hygiene.** `PubFFI = ::FFI` (defined once in `lib/pwn/ffi.rb`)
50
52
  avoids the `PWN::FFI` vs `::FFI` collision when modules `extend PubFFI::Library`.
51
53
  4. **Uniform front-end contract.** Every hardware binding exposes the same
@@ -86,29 +88,17 @@ PWN::FFI::SoapySDR.close(handle: h)
86
88
  iq = PWN::FFI::HackRF.capture(freq_hz: 1_090_000_000, rate_hz: 2_000_000, samples: 262_144)
87
89
  ```
88
90
 
89
- ## True-air decode: how this drives `PWN::SDR::Decoder::*`
91
+ ## Decoder integration boundaries
90
92
 
91
- Every decoder module now has a **true over-the-air I/Q path** via
92
- `PWN::SDR::Decoder::Base.run_iq`, which:
93
+ Shared Base/DSP code can use these bindings for integer IQ streams and numerical
94
+ acceleration. Available bindings are not proof of a connected radio, supported
95
+ protocol mode, sufficient sample rate or realtime throughput. A detector output
96
+ is not a decoded payload. Protocol entry points and required native processes
97
+ are documented in [SDR Decoder Coverage](SDR-Decoder-Coverage.md).
93
98
 
94
- 1. Calls `Base.resolve_iq_source(source: :auto)` to pick the first working
95
- front-end in order `:file` -> `:rtlsdr` -> `:adalm_pluto` -> `:hackrf` ->
96
- `:soapy` (or a forced `:source`).
97
- 2. Streams raw I/Q via the uniform `read_sync` contract above.
98
- 3. Unpacks (`cu8`/`cs8`/`cs16`) and either hands complex samples to
99
- `demod#feed_iq(iq, rate:)` or FM-demodulates first and calls
100
- `demod#feed(audio)` for narrowband protocols.
101
- 4. Emits the same JSONL-logged Hash frames every decoder already produces.
102
- 5. Falls back to `Base.run_detector` (energy characterizer) when no hardware
103
- or capture file is present, so the operator still gets structured output.
104
-
105
- | Decoder | Air path | I/Q entry point |
106
- |---|---|---|
107
- | ADSB, Bluetooth, DECT, GPS, GSM, Iridium, LoRa, LTE, P25, RFID, RTL433, WiFi, ZigBee | `run_iq` (wideband) | `#feed_iq(iq, rate:)` |
108
- | APT, FLEX, Morse, Pager, POCSAG, RTTY | `run_iq(fm_demod: true)` or `run_native` (GQRX 48 kHz UDP) | `#feed(audio)` |
109
- | RDS | GQRX built-in RDS decoder (`RDS.sample`) | n/a |
110
-
111
- No decoder shells out; Ruby remains the orchestrator.
99
+ Some protocol modes invoke native executables (for example `rtl_433`, `proxmark3`,
100
+ `gnss-sdr`, `redsea` and the LTE bridge); “no decoder shells out” is not a current
101
+ contract. Keep offline fixture, native-backend and live RF evidence separate.
112
102
 
113
103
  **See also:** [SDR](SDR.md) - [Hardware](Hardware.md)
114
104
 
@@ -8,31 +8,31 @@
8
8
  ## Generate
9
9
 
10
10
  ```ruby
11
- payloads = PWN::Plugins::Fuzz.generate(
12
- seed: "GET / HTTP/1.1\r\nHost: t\r\n\r\n",
13
- strategy: :radamsa, # :radamsa | :bitflip | :dictionary
14
- count: 500
11
+ payloads = PWN::Plugins::Fuzz.http(
12
+ request: "GET /FUZZ HTTP/1.1\r\nHost: lab.invalid\r\n\r\n",
13
+ dictionary: ['a', 'long-input', '%00']
15
14
  )
16
- enc = PWN::Plugins::Char.url_encode(str: payloads.first)
17
15
  ```
18
16
 
19
17
  ## Deliver
20
18
 
21
19
  ```ruby
22
- payloads.each do |p|
23
- PWN::Plugins::Sock.connect(target: '10.0.0.5', port: 8080) do |s|
24
- s.write(p); s.read
25
- end
26
- end
20
+ # For authorized network tests, Fuzz.socket accepts target:, port:, request:,
21
+ # payload: and fuzz_delimeter:. Inspect its help for timeout/encoding controls.
22
+ PWN::Plugins::Fuzz.help
27
23
  ```
28
24
 
29
25
  For raw L2/L3: `PWN::Plugins::Packet`.
30
- CLI network fuzzer: `pwn_fuzz_net_app_proto -t HOST -p PORT -f seeds/`
26
+ CLI network fuzzer: `pwn_fuzz_net_app_proto --help` (requires a payload **file**,
27
+ request template and output directory; not `-f seeds/`).
31
28
 
32
29
  ## Monitor & report
33
30
 
34
- `PWN::Plugins::PS` watches the target process; `PWN::Plugins::Log` tails its
35
- log; `PWN::Reports::Fuzz` renders crash → HTML/JSON.
31
+ `Fuzz.http` expands templates only; it does not send traffic. `Fuzz.file_format`
32
+ appends dictionary blobs to a seed. `Fuzz.triage` deduplicates existing crash
33
+ files by hash and selects the smallest reproducer. `PWN::Reports::Fuzz.generate`
34
+ expects a `results_hash:` and output `dir_path:`; it is not a crash detector.
35
+ Use explicit target monitoring and retain actual crash evidence.
36
36
 
37
37
  Feed unique crashes back as new seeds (`Log → Fuzz` dashed edge in the diagram).
38
38
 
@@ -5,7 +5,7 @@
5
5
  ```bash
6
6
  $ pwn # interactive REPL
7
7
  $ pwn --ai "scan 10.0.0.0/24 with NmapIt and summarize open services"
8
- $ pwn_nmap_discover_tcp_udp -t 10.0.0.0/24 -o out/ # headless driver
8
+ $ pwn_nmap_discover_tcp_udp -t 10.0.0.0/24 -r out/ # headless driver
9
9
  ```
10
10
 
11
11
  ## Check / provision this host
@@ -24,7 +24,7 @@ See [Installation](Installation.md) for every flag and the
24
24
 
25
25
  ```ruby
26
26
  PWN.help # top-level help
27
- PWN::Plugins.constants.sort # list all 67 plugins
27
+ PWN::Plugins.constants.sort # list all 107 plugins
28
28
  PWN::Plugins::NmapIt.help # per-plugin usage
29
29
  PWN::Setup.check # capability doctor from inside the REPL
30
30
  PWN::Migrate.status # ~/.pwn state-file compatibility rows
@@ -45,7 +45,7 @@ history # what you've typed → copy into a driver
45
45
  | `pwn-ai-sessions` | List / view / delete transcripts |
46
46
  | `pwn-ai-cron` | List / run scheduled jobs |
47
47
  | `pwn-ai-delegate` | Hand a task to a Swarm persona |
48
- | `toggle-debug` | Stage log per request to `/tmp/pwn-ai-DEBUG-<SESSION_ID>-RN.log` |
48
+ | `toggle-debug` | Stage log per request to `~/.pwn/logs/pwn-ai-DEBUG-<SESSION_ID>-R<N>.log` (or `PWN_DEBUG_DIR`) |
49
49
  | `toggle-trace` | Same as `toggle-debug` plus TracePoint; ENTER after each loop step. Pry.config, not Env. Off turns both off. |
50
50
  | `toggle-pwn-ai-speaks` | TTS every final answer on/off |
51
51
  | `welcome-banner` | Redraw a random `PWN::Banner` |
@@ -141,7 +141,10 @@ scan = PWN::Plugins::BurpSuite.active_scan(burp_obj: burp,
141
141
  target_url: 'http://scanme.nmap.org')
142
142
 
143
143
  # 4. report
144
- PWN::Reports::SAST.generate(dir_path: '/tmp/src', output_dir: '/tmp/out')
144
+ # Burp output is not SAST input; use its own report generator.
145
+ PWN::Plugins::BurpSuite.generate_scan_report(
146
+ burp_obj: burp, target_url: 'http://scanme.nmap.org',
147
+ output_dir: '/tmp/out', report_type: 'HTML')
145
148
  ```
146
149
 
147
150
  Then say the same thing in English inside `pwn-ai` and watch the agent do it.
@@ -1,5 +1,90 @@
1
1
  # Deployment fingerprints and fair harness evaluation
2
2
 
3
+ ## Evidence-backed improvement lifecycle
4
+
5
+ This extends the existing `Verification` → `Reward` → `Learning` ledger and
6
+ `PolicyEvaluation`/RSpec harness; there is no second evaluator or automatic
7
+ self-promotion loop.
8
+
9
+ ### Completion accounting
10
+
11
+ `Reward.resolve_outcome` exposes `verified_completion` independently of the
12
+ legacy judge-quality `success` field. It is true only for complete host check
13
+ coverage, false for a verifier failure, and null when evidence is unavailable.
14
+ `Reward.judge` preserves the evaluator's pre-verification `solved` verdict in
15
+ `claimed_completion`. `false_completion` is true when that claim is independently
16
+ refuted, null when a claim has not been checked, and false for a checked pass or
17
+ an explicit nonclaim. These are **judge claims**, not a semantic classifier of
18
+ arbitrary assistant prose. Trusted host callers may explicitly supply the claim
19
+ to `resolve_outcome`; model-facing tools cannot create trusted checks.
20
+
21
+ `Learning.note_outcome` persists these fields without reinterpreting them.
22
+ `Learning.stats` reports completion claims, checked claims, verified completions,
23
+ false completions, and a false-completion rate whose denominator is **checked
24
+ claims**, not all attempts. The rate is null without checked claims. Old ledger
25
+ rows remain unknown for these new metrics; no migration fabricates labels.
26
+ Existing quality scores and training eligibility retain their previous semantics;
27
+ use verified completion, not legacy success rate, as acceptance evidence.
28
+
29
+ The executable harness independently counts a released success marker as false
30
+ success whenever the whole run is not PASS. Empty checks, failed processes and
31
+ resource-capped runs cannot hide behind correct bytes or vacuous `all?` checks.
32
+ The locked `completion_regressions.json` corpus records those source-reproduced
33
+ accounting defects; RSpec executes it alongside the existing CLI fault lanes.
34
+
35
+ ### Turn observed failures into reviewable regressions
36
+
37
+ Use the exact persisted outcome ID, original request, and independently authored
38
+ expected bytes (never derive gold from the failed answer):
39
+
40
+ ```ruby
41
+ recipe = PWN::AI::Agent::Learning.regression_task(
42
+ outcome_id: failure_id,
43
+ request: original_request,
44
+ checks: [{ requirement: original_request, kind: :file,
45
+ path: 'result.txt', expected: "correct\n" }]
46
+ )
47
+ # Within an RSpec example, using a fresh disposable fixture directory:
48
+ report = PWN::AI::Agent::Verification.run(recipe[:contract].merge(root: fixture_root))
49
+ expect(report[:status]).to eq(:pass)
50
+ ```
51
+
52
+ Export is read-only and only accepts a persisted verifier failure among the most
53
+ recent 10,000 outcomes. The request digest and original requirement coverage must
54
+ match. Recipes contain source outcome identity, verification/contract SHA-256,
55
+ and a fixed `regression` split. Only relative file/JSON checks are supported;
56
+ commands, HTTP checks and raw tool traces are not mined or executed. Expected
57
+ content remains an operator-reviewed input, not independently attested history.
58
+ Review/redact the request and gold before saving a recipe in `spec/fixtures/harness`
59
+ and add its reproduction/setup under RSpec. Do not put an inspected regression in
60
+ the held-out split. The recipe itself verifies outputs; it does not autonomously
61
+ replay potentially destructive historical actions.
62
+
63
+ ### Frozen acceptance and versioned local promotion
64
+
65
+ Reuse the existing policy CLI (`pwn-ai --policy evaluate`, `promote`, `rollback`)
66
+ and frozen snapshots, rather than updating live stores during evaluation.
67
+ `PolicyEvaluation.evaluate` runs the existing standalone worker with a cleared
68
+ environment and disposable HOME; off/baseline/candidate use frozen policy bytes
69
+ and independently checked tasks. The split-corpus executable experiments clone
70
+ frozen training HOMEs per trial, check input/snapshot hashes and reject duplicate
71
+ cross-split prompts or inputs. The held-out set is public and fixed: it tests
72
+ infrastructure and this local controller, not general live model intelligence.
73
+
74
+ Promotion still re-executes each submitted acceptance report, checks provenance,
75
+ requires both filesystem environments, rejects aggregate **and per-task**
76
+ regressions, and requires an independent held-out gain. Successful receipts now
77
+ include `receipt_version: 1`, `change_kind: routing_policy`, and
78
+ `acceptance_sha256` over deterministic fresh reports in addition to exact baseline
79
+ and candidate digests. Preserve the returned JSON in a distinct receipt file.
80
+ Rollback requires that successful versioned receipt and refuses intervening live
81
+ updates or changed backups. Old unversioned receipts are deliberately rejected;
82
+ retain their backups for explicit operator recovery rather than guessing a version.
83
+ These receipts are local audit records, not cryptographic attestations against a
84
+ hostile local writer. Both writes still require explicit approval, an explicit
85
+ live path and operator-attested stopped policy writers. This does not promote
86
+ arbitrary skills, model weights or external service changes.
87
+
3
88
  ## Deployment diagnosis
4
89
 
5
90
  `PWN::RuntimeFingerprint.report(expected_root: '/intended/gem/lib')` is read-only.
@@ -179,10 +264,12 @@ Unknown usage/cost and uninstrumented all-learning activity remain null. The
179
264
  parent supervisor kills the process group on wall cap and records INCOMPLETE,
180
265
  never success. A generic child error is not silently converted into a pass.
181
266
 
182
- ## Recorded offline integration acceptance
267
+ ## Historical offline integration acceptance
183
268
 
184
- Final integration artifacts are retained under `/tmp/pwn-harness-final-acceptance`.
185
- These are local execution results, not live provider scores:
269
+ The prior integration recorded artifacts under `/tmp/pwn-harness-final-acceptance`.
270
+ That temporary path is not a shipped or durable evidence archive. The following
271
+ counts describe that historical run, not a rerun of the current checkout or live
272
+ provider scores; reproduce the commands above for current acceptance:
186
273
 
187
274
  - `HOME=/tmp/pwn-harness-final-acceptance/home bundle exec rake`:
188
275
  **4369 examples, 0 failures**, then **1150 files, no RuboCop offenses**, exit 0
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **PWN** (/pōn/) - an open-source offensive-security automation framework and
4
4
  > continuous-security-integration platform written in Ruby.
5
- > 67 plugins · 48 SAST modules · 90 AWS wrappers · 22 WWW drivers · 54 CLI
5
+ > 107 plugins · 48 SAST modules · 90 AWS wrappers · 22 WWW drivers · 56 CLI
6
6
  > executables · 6 LLM engines · a self-improving multi-agent AI · one REPL.
7
7
 
8
8
  **Repo root:** `/opt/pwn` · **This wiki:** `/opt/pwn/documentation/` ·
@@ -19,6 +19,7 @@
19
19
  | [How PWN Works](How-PWN-Works.md) | The five layers, with the architecture diagram |
20
20
  | [Installation](Installation.md) | `gem install --verbose pwn` → `pwn setup` doctor/provisioner · capability profiles · `--migrate` state doctor |
21
21
  | [General Usage](General-PWN-Usage.md) | Day-one cheat sheet |
22
+ | [Operability and Evidence](Operability.md) | Completion, regressions, frozen evaluation, mesh and deployment boundaries |
22
23
  | [Configuration](Configuration.md) | `~/.pwn/pwn.yaml` (encrypted) - engines, keys, agent options · `pwn-vault` |
23
24
  | **[All Data-Flow Diagrams](Diagrams.md)** | **29 SVGs** in one scrollable page |
24
25
 
@@ -28,7 +29,7 @@
28
29
  |---|---|
29
30
  | [The `pwn` REPL](pwn-REPL.md) | Pry shell with the whole `PWN::` namespace pre-loaded |
30
31
  | [`pwn-ai` Autonomous Agent](pwn-ai-Agent.md) | Natural-language TUI + `pwn --ai PROMPT` one-shot · **TaskSummarizer** briefs · CORE_TOOLS until `may_finalize?` |
31
- | [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) | 54 headless executables (`pwn` + 53 `pwn_*`) for CI/CD |
32
+ | [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) | 56 executables (`pwn`, `pwn-ai`, `pwn-capd` + 53 `pwn_*`) for CI/CD |
32
33
  | [Drivers (build your own)](Drivers.md) | Turn a REPL session into a shipped binary |
33
34
 
34
35
  ## 🤖 AI Subsystem (`PWN::AI`)
@@ -37,7 +38,7 @@
37
38
  |---|---|
38
39
  | [AI / LLM Integration](AI-Integration.md) | OpenAI · Anthropic · Grok (OAuth) · Gemini · Ollama · Open WebUI |
39
40
  | [Agent Tool Registry](Agent-Tool-Registry.md) | 16 toolsets · **150** LLM-callable tools |
40
- | [Memory · Skills · Learning](Skills-Memory-Learning.md) | Introspection - self-improvement loop + 10 bundled skills on first launch |
41
+ | [Memory · Skills · Learning](Skills-Memory-Learning.md) | Introspection, reviewed skill updates and bundled SOP/module skills on first launch |
41
42
  | [Mistakes](Mistakes.md) | **Negative feedback** - fingerprint failures · do-NOT-repeat · `[REPEATING]`/`[REGRESSED]` · inline self-correction |
42
43
  | [Reinforcement Learning](Reinforcement-Learning.md) | **`Reward` + `Curriculum` + `Policy`** - outcome/process judges · preference ledger · self-play practice · live Q / REINFORCE (advisory) · export-ready LoRA gate |
43
44
  | [Extrospection](Extrospection.md) | World-awareness - snapshot · drift · intel · **watch** · **verify** · **rf_tune** · **osint** · serial · telecomm · packet · vision · voice · correlate |
@@ -50,7 +51,7 @@
50
51
 
51
52
  | | |
52
53
  |---|---|
53
- | [Plugins (67)](Plugins.md) | Every `PWN::Plugins::*` module by category |
54
+ | [Plugins (107)](Plugins.md) | Every `PWN::Plugins::*` module by category |
54
55
  | &nbsp;&nbsp;↳ [BurpSuite](BurpSuite.md) ⭐ | Preferred web proxy / scanner |
55
56
  | &nbsp;&nbsp;↳ [TransparentBrowser](Transparent-Browser.md) | Headless / visible browser automation |
56
57
  | &nbsp;&nbsp;↳ [NmapIt](NmapIt.md) | Network discovery |
@@ -60,7 +61,7 @@
60
61
  | [SAST (48 rules)](SAST.md) | Static analysis + test-case engine |
61
62
  | [WWW (22 drivers)](WWW.md) | Browser automations for real sites |
62
63
  | [AWS (90 services)](AWS.md) | Cloud-security enumeration |
63
- | [SDR](SDR.md) | GQRX · FlipperZero · RFIDler · SonMicro · **Decoder::* (20 protocols + Base/DSP)** · FFI-accelerated DSP |
64
+ | [SDR](SDR.md) | GQRX · FlipperZero · RFIDler · SonMicro · **Decoder::* (21 protocols + Base/DSP)** · FFI-accelerated DSP |
64
65
  | [Blockchain](Blockchain.md) | BTC · ETH helpers |
65
66
  | [Bounty](Bounty.md) | Lifecycle / auth-replay tooling |
66
67
  | [Reports](Reporting.md) | HTML/JSON output + DefectDojo/Jira |
@@ -1,8 +1,7 @@
1
1
  # How PWN Works
2
2
 
3
- PWN is five layers, each visible in the source tree. Edges only go
4
- **down** one layer (or sideways within a layer), which is why the diagrams
5
- below have no criss-crossing lines.
3
+ This conceptual layer map groups entry points, agent control, capabilities and
4
+ persistence. Feedback and cross-layer calls are explicit; layout is not a call graph.
6
5
 
7
6
  ![Overall Architecture](diagrams/overall-pwn-architecture.svg)
8
7
 
@@ -20,7 +19,7 @@ hardware).
20
19
  | `pwn-ai` | `lib/pwn/ai/agent/loop.rb` | Agent TUI inside the REPL |
21
20
  | `pwn --ai PROMPT` | `bin/pwn` | Headless one-shot agent (CI-friendly) |
22
21
  | `pwn setup` | `lib/pwn/setup.rb` · `bin/pwn_setup` | Post-install doctor + capability provisioner + `--migrate` state doctor (also `pwn --setup[=PROFILE]`) |
23
- | `bin/pwn_*` + `pwn` | 54 files | Thin OptionParser wrappers plus the `pwn` REPL / one-shot agent |
22
+ | `bin/` (including `pwn-ai` and `pwn-capd`) | 56 files | Thin OptionParser wrappers plus the `pwn` REPL / one-shot agent |
24
23
  | `PWN::Cron` | `lib/pwn/cron.rb` | Scheduled jobs + background worker (`pwn setup`). Fresh install seeds hygiene on (`learning_consolidate_nightly`, `pwn_stores_lean_nightly`) and curriculum practice/judge/train off |
25
24
 
26
25
  ## L2 - AI agent core (`lib/pwn/ai/agent/`)
@@ -29,7 +28,7 @@ hardware).
29
28
  |---|---|
30
29
  | `Loop` | plan → **TaskSummarizer** briefs → dispatch tool_calls → observe → repeat until `may_finalize?`. No iteration-budget abort |
31
30
  | **`TaskSummarizer`** | Executive UX: every request gets an English task compass (`emit_plan!` · `about_to` as `task k/n`) - no statement/question/goal type |
32
- | `Registry` | JSON-Schema function definitions grouped into 16 **toolsets** · **150 tools** · `CORE_TOOLS` = `DEFAULT_PREFERENCE` (`memory_recall` · `session_recall` · `skills_recall` · `pwn_eval` · `shell` · `mistakes_record` · `mistakes_resolve` · `learning_note_outcome` · `memory_remember` · `skills_update` · `artifact_read` · `artifact_grep`) |
31
+ | `Registry` | JSON-Schema function definitions grouped into 16 **toolsets** · **150 tools** · `CORE_TOOLS` = `DEFAULT_PREFERENCE` (`memory_recall` · `session_recall` · `skills_recall` · `pwn_eval` · `shell` · `mistakes_record` · `mistakes_resolve` · `learning_note_outcome` · `memory_remember` · `skills_update` · `artifact_read` · `artifact_grep` · `job_run` · `job_status` · `job_tail` · `job_result` · `job_kill`) |
33
32
  | `Dispatch` / `Result` | execute a tool, capture stdout/value/error/duration |
34
33
  | `PromptBuilder` | inject MEMORY / SKILLS / LEARNING / **KNOWN MISTAKES + FIXES** / METRICS / **POLICY** / EXTROSPECTION / RECENT TURNS |
35
34
  | `Metrics` · `Learning` · `Reflect` · **`Policy`** | **introspection** - how well am I doing? (Policy is live Q / REINFORCE, advisory rank only) |
@@ -45,14 +44,14 @@ call, and [Reinforcement Learning](Reinforcement-Learning.md) for how
45
44
 
46
45
  ## L3 - Capability namespaces (`lib/pwn/*`)
47
46
 
48
- `Plugins` (67) · `SAST` (48) · `WWW` (22) · `AWS` (90) · `SDR` · `Blockchain` ·
47
+ `Plugins` (107) · `SAST` (48) · `WWW` (22) · `AWS` (90) · `SDR` · `Blockchain` ·
49
48
  `Bounty` · `Reports` · `FFI` · `Banner` · **`Setup`** · **`Migrate`**. First launch also seeds bundled skills from `etc/default_skills/`. Each is
50
49
  a plain module of `public_class_method def self.x(opts = {})` methods -
51
50
  callable the same way from the REPL, from `pwn_eval`, or from a driver.
52
51
 
53
52
  ## L4 - Persistence (`~/.pwn/`)
54
53
 
55
- Everything the framework remembers between processes lives in one directory.
54
+ Most default user state lives under `~/.pwn`; explicit outputs and worktrees may live elsewhere.
56
55
  `PWN::Migrate` (schema-stamped, idempotent, dry-run capable) verifies and
57
56
  autofixes every file in it after a `gem update pwn`:
58
57
 
@@ -64,14 +63,14 @@ for the migrator.
64
63
 
65
64
  ## The feedback loop
66
65
 
67
- L2 exists to close this loop on every turn - successes become skills and
68
- lessons, **failures become fingerprinted mistakes with fixes**, **world state
66
+ L2 records outcomes and may propose skills or lessons; routine success does not
67
+ automatically create a skill. In the feedback loop, **failures become fingerprinted mistakes with fixes**, **world state
69
68
  is sensed on demand** (`extro_verify` / `extro_watch` / `extro_rf_tune` /
70
69
  `extro_osint` / `extro_serial` / `extro_telecomm` / `extro_packet` /
71
70
  `extro_vision` / `extro_voice` / `extro_intel`) and correlated against those
72
71
  failures, a **cheap LLM judge scores the final answer** (token overlap only if the engine is unavailable) and a **process reward
73
72
  model tags each tool step**, **Policy records the live MDP step** and updates
74
- Q / REINFORCE when the judge scores the turn, and **the prompt blocks**
73
+ Q / REINFORCE only for eligible resolved outcomes with independently attributed positive credit, and **the prompt blocks**
75
74
  (MEMORY · SKILLS · LEARNING · KNOWN MISTAKES/FIXES · TOOL EFFECTIVENESS ·
76
75
  POLICY · EXTROSPECTION · RECENT TURNS) are re-injected into the next system
77
76
  prompt.
@@ -5,7 +5,7 @@ a plugin whose native extension or OS binary is missing costs nothing until
5
5
  you actually touch that constant. That means the install is **two steps**:
6
6
 
7
7
  ```bash
8
- gem install --verbose pwn # 1. get the gem (pure-Ruby core always works)
8
+ gem install --verbose pwn # 1. install the gem and its Ruby/native dependencies
9
9
  pwn setup # 2. doctor + provision this host's capabilities
10
10
  ```
11
11
 
@@ -16,7 +16,7 @@ asked - installs exactly the OS headers, external tools, and native gems
16
16
  needed to unlock the ones you want. No `/opt/pwn` checkout, no `rvmsudo`
17
17
  chain, no bash provisioners required.
18
18
 
19
- Tested on **Kali / Debian / Ubuntu**, **Fedora**, **Arch**, and **macOS**
19
+ Provisioning mappings cover **Kali / Debian / Ubuntu**, **Fedora**, **Arch**, and **macOS**
20
20
  (Homebrew or MacPorts). Ruby ≥ 3.3 (RVM, rbenv, asdf, or system Ruby).
21
21
 
22
22
  ---
@@ -230,9 +230,8 @@ malformed or unsafe stores; cleanup fails closed when it is nonempty.
230
230
  The shared index follows defined structural fields, not ID-looking text.
231
231
  Dependency-backed sessions remain visible and resumable, not archived away.
232
232
  Vault/config/credential payloads and historical backups are not scanned.
233
- Same-user interactive PWN
234
- processes defer deletion because existing writers have no lifetime leases; this is a
235
- conservative guard, not a cross-process session lease. Inspect without deleting:
233
+ Current writers hold per-session lifetime leases; legacy installed writers
234
+ without that protocol cause conservative ownership uncertainty. Inspect without deleting:
236
235
  `ruby ~/.pwn/cron/session_cleanup.rb --dry-run`.
237
236
 
238
237
  `--apply` backs up eligible transcript/metadata bytes under
@@ -334,10 +333,12 @@ lists have been consolidated into `PWN::Setup::NATIVE_GEMS` / `::TOOLCHAIN`.
334
333
 
335
334
  `pwn setup` is the single provisioning entry point for every image builder:
336
335
 
337
- ```dockerfile
338
- FROM kalilinux/kali-rolling
339
- RUN gem install --verbose pwn && pwn setup --profile full --yes
340
- ```
336
+ Start from an image with a supported Ruby, RubyGems, compiler and required
337
+ native gem headers already installed. A bare `kalilinux/kali-rolling` image does
338
+ not establish those prerequisites. Review the repository Dockerfile/provisioners,
339
+ pin the base and gem version for reproducible deployments, then explicitly run
340
+ `gem install --verbose pwn` and the chosen `pwn setup --profile` command.
341
+ Image build success is not live provider/radio/browser acceptance.
341
342
 
342
343
  ```yaml
343
344
  # .gitlab-ci.yml - fail the job if the runner is missing a capability
@@ -378,7 +379,7 @@ The first `pwn` launch creates `~/.pwn/` and an **encrypted**
378
379
  Source lives in the gem at `etc/default_skills/`. `PWN::Config.install_default_skills`
379
380
  walks every `SKILL.md` recursively (idempotent SOP copies; never overwrites an
380
381
  edited SOP `SKILL.md`). Generated module skills under `etc/default_skills/pwn/`
381
- `PWN::` module, plus `references/` when the source has CWE/NIST/URLs) are
382
+ (one per `PWN::` module, plus `references/` when the source has CWE/NIST/URLs) are
382
383
  copied to `~/.pwn/skills/pwn/` and **are** overwritten on
383
384
  `pwn setup --migrate` / first launch so they stay in sync with `lib/pwn`.
384
385
  `bundle exec rake` does not rewrite `etc/default_skills/pwn`. `rake module_skills`
@@ -449,7 +450,7 @@ Vagrant, CI) picks it up automatically.
449
450
  ```ruby
450
451
  pwn[CURRENT_VERSION]:001 >>> PWN::Setup.check[:ok] # => true
451
452
  pwn[CURRENT_VERSION]:002 >>> PWN::Migrate.needed? # => false
452
- pwn[CURRENT_VERSION]:003 >>> PWN::Plugins.constants.count # => 67
453
+ pwn[CURRENT_VERSION]:003 >>> PWN::Plugins.constants.count # => 107
453
454
  pwn[CURRENT_VERSION]:004 >>> PWN::SAST.constants.count # => 48
454
455
  pwn[CURRENT_VERSION]:005 >>> pwn-ai # launches agent TUI
455
456
  ```
@@ -8,30 +8,24 @@ with sessions, all from Ruby.
8
8
 
9
9
  ## Configure
10
10
 
11
- ```yaml
12
- # ~/.pwn/pwn.yaml (edit via `pwn-vault`)
13
- metasploit:
14
- host: 127.0.0.1
15
- port: 55553
16
- user: msf
17
- pass: ...
18
- ```
19
-
20
- Start the daemon: `msfrpcd -U msf -P ... -a 127.0.0.1 -p 55553 -S`
11
+ `connect(yaml_conf:)` reads a separate operator-owned YAML file, not the
12
+ `metasploit:` block in the encrypted PWN vault. Required keys are
13
+ `msfrpcd_host`, `port`, `username`, and `password`. Keep that file private and
14
+ use only a trusted local daemon or protected transport. Without `yaml_conf`,
15
+ the legacy provider file is resolved using `PWN_ROOT` and `PWN_PROVIDER`.
16
+ Review `msfrpcd --help` for daemon transport/authentication settings; no daemon
17
+ or credential enrollment is performed by this documentation check.
21
18
 
22
19
  ## Use
23
20
 
24
21
  ```ruby
25
- msf = PWN::Plugins::Metasploit.connect
26
- mods = PWN::Plugins::Metasploit.search(msf_obj: msf, query: 'jenkins')
27
- PWN::Plugins::Metasploit.use(msf_obj: msf,
28
- module_type: 'exploit',
29
- module_name: 'multi/http/jenkins_script_console')
30
- PWN::Plugins::Metasploit.set_option(msf_obj: msf, opt: 'RHOSTS', val: '10.0.0.5')
31
- job = PWN::Plugins::Metasploit.run(msf_obj: msf)
32
- PWN::Plugins::Metasploit.sessions(msf_obj: msf)
22
+ console = PWN::Plugins::Metasploit.connect(yaml_conf: '/path/to/metasploit.yaml')
23
+ PWN::Plugins::Metasploit.console_exec(console_obj: console, cmd: 'search jenkins')
24
+ # Further commands use the same console_exec interface; inspect results before
25
+ # executing a module. This example does not launch an exploit.
26
+ PWN::Plugins::Metasploit.disconnect(console_obj: console)
33
27
  ```
34
28
 
35
- CLI: `pwn_msf_postgres_login -H 10.0.0.5 -U users.txt -P pass.txt`
29
+ CLI: `pwn_msf_postgres_login /path/to/private-msfrpcd.yaml 10.0.0.5 5432`
36
30
 
37
31
  [← Home](Home.md) · [Plugins](Plugins.md)
@@ -28,7 +28,7 @@ detector**, and it survives across sessions.
28
28
  | `regressed` | auto-set when a *resolved* signature recurs - reopened as `[REGRESSED]` |
29
29
  | `sessions` | last 10 session_ids that hit it |
30
30
 
31
- ## How the loop closes (why it does **not** repeat mistakes)
31
+ ## How the loop responds to repeated mistakes
32
32
 
33
33
  ```text
34
34
  Loop.run --(tool failure)---------> Mistakes.record (persist + count++)
@@ -45,7 +45,7 @@ model --(tool call)---------------> mistakes_record / mistakes_resolve
45
45
 
46
46
  Repeating shell failures with a known recipe (`command is required`, missing path, not-found junk, syntax, raw-socket deny) are resolved in place instead of parked as "needs human". Only scars the loop cannot close stay in the operator inbox.
47
47
 
48
- ## Five ingest paths - nothing slips through
48
+ ## Recorded ingest paths (not universal error detection)
49
49
 
50
50
  | Source | Trigger | What is recorded |
51
51
  |---|---|---|
@@ -8,17 +8,20 @@ Thin, composable wrapper over `nmap` with structured XML parsing.
8
8
  > pcaprub headers · whois. See [Installation](Installation.md).
9
9
 
10
10
  ```ruby
11
- r = PWN::Plugins::NmapIt.port_scan(
11
+ PWN::Plugins::NmapIt.port_scan(
12
12
  target: '10.0.0.0/24',
13
13
  ports: '1-1024',
14
14
  service_scan: true,
15
15
  script: 'default,vuln',
16
16
  output_xml: '/tmp/scan.xml'
17
17
  )
18
- r[:hosts].each { |h| puts "#{h[:ip]} → #{h[:ports].map { |p| p[:portid] }}" }
18
+ r = PWN::Plugins::NmapIt.inventory(xml_file: '/tmp/scan.xml')
19
+ r[:hosts].each { |h| puts "#{h[:host]} → #{h[:ports].map { |p| p[:port] }}" }
19
20
  ```
20
21
 
21
- CLI: `pwn_nmap_discover_tcp_udp -t 10.0.0.0/24 -o out/`
22
+ `port_scan` invokes `Nmap::Command.sudo`; it is not an unprivileged parser and
23
+ its return is not the inventory Hash. `inventory` reads an existing XML file.
24
+ Use `pwn_nmap_discover_tcp_udp --help` for the driver's separate options.
22
25
 
23
26
  Pairs with `extro_observe` to persist banners for later
24
27
  [correlation](Extrospection.md), and with `PWN::Plugins::Sock` /
@@ -0,0 +1,99 @@
1
+ # Operability and evidence boundaries
2
+
3
+ This guide connects the documentation to the current source interfaces. A module
4
+ or command being present is not proof that its external service, device or model
5
+ works on a particular deployment. Examples with targets, credentials or devices
6
+ require an operator-configured environment; they are not offline smoke tests.
7
+
8
+ ## Three different feedback paths
9
+
10
+ | Path | Authority and limit |
11
+ | --- | --- |
12
+ | Introspection | Metrics, Learning, Mistakes, Reward and Reflect record outcomes and propose corrections. A judge score, stored lesson or tool exit zero is not verified completion. |
13
+ | Extrospection | On-demand source observations and optional host/repo/env baselines support diagnosis. Correlation and browser token-overlap checks are fallible, not causal or semantic proof. |
14
+ | Living off the land | `DetectOS.living_off_the_land` returns OS metadata and `native` executable names discovered on PATH. PromptBuilder injects its OS summary alongside separate PreflightChecker health. Presence is neither authorization nor successful execution. |
15
+
16
+ Relevant source: `lib/pwn/plugins/detect_os.rb`,
17
+ `lib/pwn/ai/agent/{prompt_builder,extrospection,reward,learning,policy}.rb`.
18
+ See [Extrospection](Extrospection.md) and [Introspection](Skills-Memory-Learning.md).
19
+
20
+ ## Completion, regressions and evaluation
21
+
22
+ The original objective and additive amendments remain authoritative. A generated
23
+ plan, exhausted counter, child reply or empty tool-call list cannot independently
24
+ establish completion. Exact-target host observations and applicable authored
25
+ Verification checks must agree with current artifacts. Checks prove their own
26
+ assertions, not every possible interpretation of natural-language intent.
27
+
28
+ `claimed_completion` preserves the judge's claim; `verified_completion` is
29
+ true/false/null for checked pass/failure/unknown. `false_completion_rate` uses
30
+ checked claims as its denominator and is null with none. The executable harness
31
+ has a different false-success measure: a released success marker is false when
32
+ the whole run is not PASS, including empty checks, nonzero exit and resource caps.
33
+ Do not combine those denominators or substitute legacy `success_rate`.
34
+
35
+ Export a regression only from an exact persisted verifier failure and original
36
+ request digest, with independently authored expected file/JSON content. The
37
+ `Learning.regression_task` recipe is inert acceptance data, not a command replay.
38
+ Its split remains `regression`; an inspected failure is not held-out evidence.
39
+
40
+ Policy evaluation uses explicit frozen baseline/candidate snapshots and fresh
41
+ isolated workers. Promotion reruns reports, requires both filesystem environments,
42
+ rejects per-task and aggregate regressions, and needs operator approval, stopped
43
+ writers and an explicit target. Preserve the versioned receipt and prior bytes.
44
+ Rollback refuses intervening writes. This routing-policy gate does not promote
45
+ arbitrary skills or model weights and the public fixed local benchmark does not
46
+ establish live LLM improvement. See [Harness Evaluation](Harness-Evaluation.md)
47
+ and [Policy Benchmark](Policy-Benchmark.md) for exact commands and limits.
48
+
49
+ ## Mesh is a separate transport boundary
50
+
51
+ `pwn-mesh` uses the selected primary serial/Bluetooth/TCP/MQTT connection;
52
+ a configured secondary MQTT receiver is not automatic dual transmission or a
53
+ bridge. Eligible `@ai` requests require the dispatch toggle, private channel
54
+ and whitelist; replies retain their origin connection and durable session scope.
55
+ A local TX header or accepted PhoneAPI write is not RF delivery evidence. MQTT
56
+ PKI DMs remain unsupported. Topic `region` is an opaque prefix, not the radio's
57
+ regulatory-band setting; `radio_index` is distinct from legacy `channel_num`.
58
+ See [General Usage](General-PWN-Usage.md) and [REPL](pwn-REPL.md).
59
+
60
+ ## Deployment and safe verification
61
+
62
+ 1. Inspect the intended checkout and preserve existing changes before upgrading.
63
+ A source edit does not update the activated gem or a running process.
64
+ 2. Use `/status` or `RuntimeFingerprint.report` to compare loaded source paths and
65
+ observed/current digests. Unknown pre-observer bytes are not a match.
66
+ 3. Install the reviewed build, restart old processes, and recheck. Keep request
67
+ checkpoints; restoration is not permission to repeat an uncertain mutation.
68
+ 4. Apply configuration migration only to the intended user state after review.
69
+ A runtime default does not backfill an already-stamped encrypted vault.
70
+ 5. Run offline gates with installed dependencies and no live integration opt-ins:
71
+
72
+ ```sh
73
+ bundle check
74
+ bundle exec rspec spec/integration/documentation_sync_spec.rb spec/documentation spec/conventions_spec.rb
75
+ bundle exec rake
76
+ git diff --check
77
+ documentation/diagrams/build.sh
78
+ ```
79
+
80
+ The full rake gate includes RSpec, RuboCop and RDoc: await actual exit, not just
81
+ an RSpec zero-failure line. Serialize gates in one checkout because RDoc rebuilds
82
+ share an output directory. Missing dependencies are a blocked gate, not a pass;
83
+ do not weaken the Gemfile to hide them. Optional native/live suites remain
84
+ explicit opt-ins documented in [Contributing](Contributing.md).
85
+
86
+ ## Historical assets and scope
87
+
88
+ `PWN.png` and `pwn_wallpaper.jpg` are branding/artwork. `pwn_install.png`,
89
+ `pwn_android_war_dialer_session.png` and `pwn_silent_help_learn_demo.gif` are
90
+ historical presentation assets, not current installation or TUI acceptance.
91
+ The fax/ringing waveform and spectrogram pairs illustrate recorded signal
92
+ shapes; images alone cannot validate current telephony or decoder operation.
93
+ They remain preserved rather than being relabeled as newly executed evidence.
94
+
95
+ The SDR coverage matrix preserves historical per-mode evidence and explicit OPEN
96
+ requirements. Current registry enumeration does not close those rows. Native
97
+ backends, synthetic fixtures and live RF acceptance must remain separate.
98
+
99
+ [Home](Home.md) · [Installation](Installation.md) · [Diagrams](Diagrams.md)