pwn 0.5.638 → 0.5.642
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.
- checksums.yaml +4 -4
- data/.github/workflows/install-matrix.yml +14 -0
- data/Gemfile +3 -3
- data/documentation/Cron.md +10 -8
- data/documentation/Reinforcement-Learning.md +43 -21
- data/documentation/diagrams/cron-scheduling.svg +134 -93
- data/documentation/diagrams/dot/cron-scheduling.dot +9 -3
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +2 -2
- data/documentation/diagrams/dot/reinforcement-learning.dot +9 -3
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +103 -101
- data/documentation/diagrams/reinforcement-learning.svg +211 -166
- data/documentation/pwn-ai-Agent.md +12 -0
- data/lib/pwn/ai/agent/curriculum.rb +647 -56
- data/lib/pwn/ai/agent/learning.rb +87 -15
- data/lib/pwn/ai/agent/loop.rb +164 -13
- data/lib/pwn/ai/agent/metrics.rb +32 -13
- data/lib/pwn/ai/agent/mistakes.rb +139 -8
- data/lib/pwn/ai/agent/prompt_builder.rb +2 -2
- data/lib/pwn/ai/agent/registry.rb +13 -3
- data/lib/pwn/ai/agent/result.rb +19 -2
- data/lib/pwn/ai/agent/reward.rb +415 -42
- data/lib/pwn/ai/agent/tools/curriculum.rb +51 -0
- data/lib/pwn/ai/agent/tools/reward.rb +15 -4
- data/lib/pwn/ai/ollama.rb +274 -10
- data/lib/pwn/config.rb +87 -3
- data/lib/pwn/cron.rb +24 -2
- data/lib/pwn/memory.rb +13 -1
- data/lib/pwn/version.rb +1 -1
- data/spec/documentation/installation_md_spec.rb +10 -5
- data/spec/integration/persistence_roundtrip_spec.rb +6 -1
- data/spec/integration/reinforced_feedback_loop_spec.rb +144 -8
- data/spec/lib/pwn/ai/agent/mistakes_spec.rb +27 -0
- data/spec/lib/pwn/ai/agent/result_spec.rb +11 -0
- data/spec/lib/pwn/ai/agent/reward_spec.rb +89 -0
- data/spec/lib/pwn/ai/ollama_spec.rb +251 -0
- data/third_party/pwn_rdoc.jsonl +47 -7
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 191435688dbf322cbae6cc09116253b08831fce203ebdded672e6b19021a30ff
|
|
4
|
+
data.tar.gz: 8ecb562e1d87bf8ad036e8ced596bdd37ab76dc24464a3a2dbb6133011b263c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 27b7a67355852e7a017016acdc3e10a6929c7d679d37aff6a7d0b183e347480b340ddd9fceb39cc70f8d1c77e13eeb6d49685213a9678576cfd4f921828d9cfc
|
|
7
|
+
data.tar.gz: 846879b068546b96f8b40e54a5b454b7234823612403a4eb4bfef3be42c1682e1ef219a85097c72f6edbdf8db23905cfef38ccf8fb615302cd6ecdc489a93b83
|
|
@@ -92,6 +92,13 @@ jobs:
|
|
|
92
92
|
{ sed -i '/--user-install/d' /etc/gemrc || true; }
|
|
93
93
|
env:
|
|
94
94
|
DEBIAN_FRONTEND: noninteractive
|
|
95
|
+
# Minimal debian/ubuntu/fedora containers ship with no LANG →
|
|
96
|
+
# Encoding.default_external == US-ASCII → any regex over the
|
|
97
|
+
# UTF-8 doc/bin files raises `invalid byte sequence in US-ASCII`
|
|
98
|
+
# (kali/arch already default to UTF-8, which is why only 6/12
|
|
99
|
+
# legs failed). C.UTF-8 exists on every glibc ≥ 2.35 image.
|
|
100
|
+
LANG: C.UTF-8
|
|
101
|
+
LC_ALL: C.UTF-8
|
|
95
102
|
PWN_FRESH_INSTALL: '1'
|
|
96
103
|
PWN_EXPECTED_PM: ${{ matrix.pm }}
|
|
97
104
|
PWN_PROFILE: ${{ matrix.profile }}
|
|
@@ -183,6 +190,13 @@ jobs:
|
|
|
183
190
|
image: kalilinux/kali-rolling
|
|
184
191
|
env:
|
|
185
192
|
DEBIAN_FRONTEND: noninteractive
|
|
193
|
+
# Minimal debian/ubuntu/fedora containers ship with no LANG →
|
|
194
|
+
# Encoding.default_external == US-ASCII → any regex over the
|
|
195
|
+
# UTF-8 doc/bin files raises `invalid byte sequence in US-ASCII`
|
|
196
|
+
# (kali/arch already default to UTF-8, which is why only 6/12
|
|
197
|
+
# legs failed). C.UTF-8 exists on every glibc ≥ 2.35 image.
|
|
198
|
+
LANG: C.UTF-8
|
|
199
|
+
LC_ALL: C.UTF-8
|
|
186
200
|
PWN_FRESH_INSTALL: '1'
|
|
187
201
|
PWN_EXPECTED_PM: apt
|
|
188
202
|
PWN_PROFILE: core
|
data/Gemfile
CHANGED
|
@@ -20,7 +20,7 @@ gem 'base32', '0.3.4'
|
|
|
20
20
|
gem 'bitcoin-ruby', '0.0.20'
|
|
21
21
|
gem 'brakeman', '8.0.5'
|
|
22
22
|
gem 'bson', '5.2.0'
|
|
23
|
-
gem 'bundler', '>=4.0.
|
|
23
|
+
gem 'bundler', '>=4.0.17'
|
|
24
24
|
gem 'bundler-audit', '>=0.9.3'
|
|
25
25
|
gem 'bunny', '3.1.0'
|
|
26
26
|
gem 'colorize', '1.1.0'
|
|
@@ -49,10 +49,10 @@ gem 'jwt', '3.2.0'
|
|
|
49
49
|
gem 'libusb', '0.7.2'
|
|
50
50
|
gem 'luhn', '3.0.0'
|
|
51
51
|
gem 'mail', '2.9.1'
|
|
52
|
-
gem 'mcp', '0.
|
|
52
|
+
gem 'mcp', '0.25.0'
|
|
53
53
|
gem 'meshtastic', '0.0.172'
|
|
54
54
|
gem 'metasm', '1.0.6'
|
|
55
|
-
gem 'mongo', '2.
|
|
55
|
+
gem 'mongo', '2.25.0'
|
|
56
56
|
gem 'msfrpc-client', '1.1.2'
|
|
57
57
|
gem 'netaddr', '2.0.6'
|
|
58
58
|
gem 'net-ldap', '0.20.0'
|
data/documentation/Cron.md
CHANGED
|
@@ -26,20 +26,22 @@ invokes `PWN::Cron.run(<id>)` on schedule.
|
|
|
26
26
|
|
|
27
27
|
## Seeded self-improvement jobs (`PWN::Cron.install_defaults`)
|
|
28
28
|
|
|
29
|
-
`pwn setup --migrate` (schema `v1`) seeds
|
|
30
|
-
`~/.pwn/cron/jobs.yml`:
|
|
29
|
+
`pwn setup --migrate` (schema `v1`) seeds four jobs into every fresh
|
|
30
|
+
`~/.pwn/cron/jobs.yml` via `PWN::Cron.install_defaults`:
|
|
31
31
|
|
|
32
32
|
| Name | Schedule | Ruby |
|
|
33
33
|
|---|---|---|
|
|
34
34
|
| `curriculum_practice_nightly` | `0 3 * * *` | `PWN::AI::Agent::Curriculum.practice(limit: 3)` |
|
|
35
|
+
| `curriculum_offline_judge` | `30 3 * * *` | `PWN::AI::Agent::Curriculum.offline_judge(since_hours: 24, limit: 40)` |
|
|
35
36
|
| `curriculum_train_weekly` | `0 4 * * 0` | `PWN::AI::Agent::Curriculum.train_and_gate(dry_run: true)` |
|
|
37
|
+
| `learning_consolidate_nightly` | `0 5 * * *` | `PWN::AI::Agent::Learning.consolidate` |
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
- **practice** — top unresolved `Mistakes` under `Reward.judge`; auto-`resolve` with ≥2 holdouts
|
|
40
|
+
- **offline_judge** — P3 backfill of ORM/PRM labels + W3 calibration from PLAN `p(success)=` so `:failure_only` local introspect does not starve the corpus
|
|
41
|
+
- **train** — export SFT + balanced DPO, LoRA-train `pwn-vN+1`, replay Mistakes.top, promote only on win. `dry_run: false` only with a trainer+GPU
|
|
42
|
+
- **consolidate** — M1/M3 memory GC so the injected MEMORY block stays high-signal
|
|
43
|
+
|
|
44
|
+
See [Reinforcement Learning](Reinforcement-Learning.md).
|
|
43
45
|
|
|
44
46
|
`cron_disable(id:)` turns either off; `install_defaults` is idempotent and
|
|
45
47
|
never overwrites a job you already have with the same name.
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Reinforcement Learning in pwn-ai
|
|
2
2
|
|
|
3
|
-
pwn-ai implements a **six-tier** in-context → weight-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`Curriculum.practice → Reward.export_dpo → Curriculum.train_and_gate`
|
|
3
|
+
pwn-ai implements a **six-tier** in-context → weight-export RL loop that
|
|
4
|
+
combines ORM/PRM, preference ledger, mistake curriculum, env-drift blame,
|
|
5
|
+
balanced DPO export, and regression-gated LoRA promotion. On hosts **with a
|
|
6
|
+
trainer + GPU**, the full
|
|
7
|
+
`Curriculum.practice → Reward.export_dpo → Curriculum.train_and_gate`
|
|
8
|
+
path closes the weight loop; without a trainer the path is **export-ready**
|
|
9
|
+
(datasets + manual CLI) and the live learning is in-context only.
|
|
8
10
|
|
|
9
11
|

|
|
10
12
|
|
|
@@ -50,7 +52,7 @@ on at least one axis, and on **five axes simultaneously** for the full
|
|
|
50
52
|
|----|-------|------|
|
|
51
53
|
| **C1** | `Registry.rank` + `Metrics.{ucb,thompson,advantage}` | score = α·keyword_sim + β·advantage + γ·UCB1. Untried tools get exploration bonus. |
|
|
52
54
|
| **C2** | `Learning.exemplars_for` | priority = judge_score × e^(−Δt/30d) × keyword_sim. |
|
|
53
|
-
| **C3** | `Curriculum.hindsight` | HER — relabel failed trajectory with achieved-goal as `success:
|
|
55
|
+
| **C3** | `Curriculum.hindsight` | HER — relabel failed trajectory with achieved-goal as `success: 'soft'` + tags `hindsight/her/soft`. Soft rows are excluded from SFT and 0.35×-weighted in C2 exemplars. |
|
|
54
56
|
| **C4** | `Learning.{compress_exemplar,build_skill_from_session}` | keep only `step_reward > 0` — minimal sufficient trace. |
|
|
55
57
|
|
|
56
58
|
## Tier 3 — Memory that stays high-signal
|
|
@@ -75,8 +77,8 @@ on at least one axis, and on **five axes simultaneously** for the full
|
|
|
75
77
|
|
|
76
78
|
| ID | Where | What |
|
|
77
79
|
|----|-------|------|
|
|
78
|
-
| **W1** | `Reward.{record_preference,export_dpo}` | 5 free preference sources: user_correction, mistakes_resolve, counterfactual, curriculum, critic. |
|
|
79
|
-
| **W2** | `Curriculum.train_and_gate` | SFT+DPO → unsloth/axolotl LoRA → `ollama create pwn-vN+1` → replay `Mistakes.top` on vN vs vN+1 → promote iff `resolved(N+1) > resolved(N)`. |
|
|
80
|
+
| **W1** | `Reward.{record_preference,export_dpo}` | 5 free preference sources: user_correction, mistakes_resolve, counterfactual, curriculum, critic. `export_dpo` enforces ≤40% per-source (`DPO_SOURCE_CAP`); pass `balance: false` for a raw dump. |
|
|
81
|
+
| **W2** | `Curriculum.train_and_gate` | SFT+DPO → unsloth/axolotl LoRA → `ollama create pwn-vN+1` → replay `Mistakes.top` on vN vs vN+1 → promote iff `resolved(N+1) > resolved(N)`. **Without a trainer: export-only** (`weight_loop: :export_ready`). |
|
|
80
82
|
| **W3** | `Curriculum.calibrate` + `Metrics.{record_calibration,calibration}` | plan_first `p(success)` vs actual → per-engine Brier/overconfidence. |
|
|
81
83
|
|
|
82
84
|
## Tier 6 — Deepen the intro↔extro join
|
|
@@ -91,32 +93,37 @@ on at least one axis, and on **five axes simultaneously** for the full
|
|
|
91
93
|
|
|
92
94
|
```yaml
|
|
93
95
|
:ai:
|
|
96
|
+
:module_reflection: false # gates Reflect lesson writing (not ORM alone)
|
|
94
97
|
:agent:
|
|
95
|
-
:critic:
|
|
96
|
-
:red_team_plan:
|
|
97
|
-
:counterfactual:
|
|
98
|
-
:hindsight: true # C3 (default true)
|
|
99
|
-
:verify_as_reward:
|
|
98
|
+
:critic: null # S3 — nil = ON for remote engines, OFF for ollama
|
|
99
|
+
:red_team_plan: null # S4 — same auto policy
|
|
100
|
+
:counterfactual: null # S2 — same auto policy
|
|
101
|
+
:hindsight: true # C3 (default true; soft-success, 0.35× in C2)
|
|
102
|
+
:verify_as_reward: null # E3 — nil = auto (~10% local / always remote on CLAIM_RX)
|
|
103
|
+
:reward_llm: null # nil = ORM/PRM use LLM teacher on remote even if module_reflection is false
|
|
104
|
+
:local_introspect: :failure_only # ollama cost policy; remote always introspects
|
|
105
|
+
:introspect_every_n: 3
|
|
100
106
|
```
|
|
101
107
|
|
|
102
108
|
## Cron self-improvement
|
|
103
109
|
|
|
104
110
|
```ruby
|
|
105
|
-
PWN::Cron.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
# Seeded idempotently by PWN::Cron.install_defaults (pwn setup --migrate):
|
|
112
|
+
PWN::Cron.install_defaults
|
|
113
|
+
# → curriculum_practice_nightly 0 3 * * * Curriculum.practice(limit: 3)
|
|
114
|
+
# → curriculum_offline_judge 30 3 * * * Curriculum.offline_judge(since_hours: 24, limit: 40)
|
|
115
|
+
# → curriculum_train_weekly 0 4 * * 0 Curriculum.train_and_gate(dry_run: true) # false only with trainer+GPU
|
|
116
|
+
# → learning_consolidate_nightly 0 5 * * * Learning.consolidate
|
|
111
117
|
```
|
|
112
118
|
|
|
113
119
|
## Tools exposed to the model
|
|
114
120
|
|
|
115
121
|
`reward_judge` · `reward_prm` · `reward_sentinel` · `reward_preferences` ·
|
|
116
122
|
`reward_export_dpo` · `curriculum_practice` · `curriculum_train` ·
|
|
117
|
-
`curriculum_hindsight` · `
|
|
123
|
+
`curriculum_hindsight` · `curriculum_offline_judge` ·
|
|
124
|
+
`curriculum_preference_balance` · `learning_purge_noise`
|
|
118
125
|
|
|
119
|
-
##
|
|
126
|
+
## Design claims (architecture — weight promotion requires a trainer)
|
|
120
127
|
|
|
121
128
|
1. **Process reward on real security tool traces** (R2)
|
|
122
129
|
2. **Automatic blame attribution** self vs env-drift via CUSUM×correlate (E1+E2)
|
|
@@ -124,6 +131,21 @@ PWN::Cron.create(name: 'mem_gc', schedule: '0 5 * * *',
|
|
|
124
131
|
4. **Mistake-driven curriculum with regression-gated LoRA promotion** (S1+W2)
|
|
125
132
|
5. **Five naturally-generated DPO sources** with zero human labelling (W1)
|
|
126
133
|
|
|
134
|
+
|
|
135
|
+
## Operational controls (priority fixes)
|
|
136
|
+
|
|
137
|
+
| ID | Control | What |
|
|
138
|
+
|----|---------|------|
|
|
139
|
+
| **P1** | `Curriculum.practice` cooldown + natural prompts | Hard-skips `reward_signal` / parked / `needs_code_change`; N-night zero-score cooldown parks thrash; reproducers are natural user tasks, never signature dumps. |
|
|
140
|
+
| **P2** | R4 `semantic_ok` + structured resolve | `31f1871b8a15`-class exit≠0 phantoms stay closed via structured holdouts. |
|
|
141
|
+
| **P3** | `Curriculum.offline_judge` | Scores last-24h sessions under ORM/PRM so local `:failure_only` introspect does not starve labels. Cron nightly. |
|
|
142
|
+
| **P4** | `Reward.proxy_distrust` | When sentinel fires, Metrics.to_context / Registry.rank haircut proxy rates — actionable, not just another Mistakes row. |
|
|
143
|
+
| **R3** | `Reward.sentinel` ring buffer | Fixed-N (`SENTINEL_WINDOW=40`) `{judge,proxy}` window replaces decaying `proxy_sum`/`proxy_n`. Means are always ∈[0,1]; `set_proxy_distrust` refuses proxy∉[0,1]; `reset_sentinel` wipes corrupt state without touching prefs. Legacy decay×`to_i` files auto-clear stuck distrust on load. |
|
|
144
|
+
| **P5** | `Curriculum.preference_balance` + `export_dpo` source-cap | Surfaces W1 monoculture **and enforces** ≤40% per source at export (`DPO_SOURCE_CAP`); critic/counterfactual auto-ON for remote engines so the diet rebalances online. |
|
|
145
|
+
| **P6** | W2 honesty | Docs + `train_and_gate` return `weight_loop: :export_ready` when `trainer: null`. |
|
|
146
|
+
| **P7** | W3 as controller | Engine Brier > 0.35 or overconfidence > 0.25 (n≥8) → force plan_first + critic, cap max_iters at 12. `offline_judge` also records calibration from PLAN `p(success)=` so the controller can fire under `:failure_only`. |
|
|
147
|
+
| **P8** | Remote reward teacher | `agent.reward_llm` nil → ORM/PRM use the LLM teacher on remote engines even when `module_reflection` is false. Local ollama stays heuristic unless explicitly enabled. PRM prompts carry R4 tags so benign recon exits score 0 not −1. |
|
|
148
|
+
|
|
127
149
|
**See also:** [Skills, Memory & Learning](Skills-Memory-Learning.md) ·
|
|
128
150
|
[Mistakes](Mistakes.md) · [Cron](Cron.md) · [pwn-ai Agent](pwn-ai-Agent.md)
|
|
129
151
|
|