pwn 0.5.779 → 0.5.781
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/Gemfile +3 -3
- data/documentation/AI-Integration.md +4 -4
- data/documentation/AWS.md +10 -9
- data/documentation/Agent-Tool-Registry.md +20 -17
- data/documentation/Blockchain.md +3 -2
- data/documentation/Bounty.md +8 -6
- data/documentation/BurpSuite.md +6 -10
- data/documentation/CLI-Drivers.md +7 -4
- data/documentation/Capability-Broker-Sandbox.md +1 -1
- data/documentation/Configuration.md +23 -15
- data/documentation/Contributing.md +3 -3
- data/documentation/Cron.md +3 -2
- data/documentation/Diagrams.md +9 -3
- data/documentation/Drivers.md +12 -6
- data/documentation/Extrospection.md +25 -5
- data/documentation/FFI.md +15 -25
- data/documentation/Fuzzing.md +13 -13
- data/documentation/General-PWN-Usage.md +7 -4
- data/documentation/Harness-Evaluation.md +90 -3
- data/documentation/Home.md +6 -5
- data/documentation/How-PWN-Works.md +9 -10
- data/documentation/Installation.md +12 -11
- data/documentation/Metasploit.md +13 -19
- data/documentation/Mistakes.md +2 -2
- data/documentation/NmapIt.md +6 -3
- data/documentation/Operability.md +99 -0
- data/documentation/Persistence.md +3 -2
- data/documentation/Plugin-Degradation.md +4 -2
- data/documentation/Plugins.md +4 -11
- data/documentation/Policy-Benchmark.md +4 -0
- data/documentation/Reinforcement-Learning.md +19 -3
- data/documentation/Reporting.md +6 -5
- data/documentation/SAST.md +15 -10
- data/documentation/SDR-Decoder-Coverage.md +10 -4
- data/documentation/SDR.md +28 -40
- data/documentation/Session-Workflow.md +25 -12
- data/documentation/Sessions.md +7 -0
- data/documentation/Skills-Memory-Learning.md +11 -4
- data/documentation/Swarm.md +6 -0
- data/documentation/Transparent-Browser.md +1 -1
- data/documentation/Troubleshooting.md +6 -3
- data/documentation/What-is-PWN.md +4 -4
- data/documentation/Why-PWN.md +1 -1
- data/documentation/diagrams/agent-tool-registry.svg +219 -180
- data/documentation/diagrams/ai-integration-tool-calling.svg +35 -34
- data/documentation/diagrams/code-scanning-sast.svg +78 -78
- data/documentation/diagrams/cron-scheduling.svg +165 -145
- data/documentation/diagrams/dot/_THEME.md +6 -4
- data/documentation/diagrams/dot/agent-tool-registry.dot +6 -2
- data/documentation/diagrams/dot/ai-integration-tool-calling.dot +1 -1
- data/documentation/diagrams/dot/code-scanning-sast.dot +8 -8
- data/documentation/diagrams/dot/cron-scheduling.dot +2 -0
- data/documentation/diagrams/dot/driver-framework.dot +1 -1
- data/documentation/diagrams/dot/extrospection-world-awareness.dot +2 -2
- data/documentation/diagrams/dot/fuzzing-workflow.dot +3 -3
- data/documentation/diagrams/dot/history-to-drivers.dot +1 -1
- data/documentation/diagrams/dot/memory-skills-detailed.dot +3 -3
- data/documentation/diagrams/dot/mistakes-negative-feedback.dot +2 -2
- data/documentation/diagrams/dot/overall-pwn-architecture.dot +33 -121
- data/documentation/diagrams/dot/persistence-filesystem.dot +2 -2
- data/documentation/diagrams/dot/plugin-ecosystem.dot +2 -2
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +31 -167
- data/documentation/diagrams/dot/pwn-repl-prototyping.dot +1 -1
- data/documentation/diagrams/dot/reinforcement-learning.dot +15 -7
- data/documentation/diagrams/dot/reporting-pipeline.dot +5 -3
- data/documentation/diagrams/dot/reverse-engineering-flow.dot +3 -3
- data/documentation/diagrams/dot/sdr-radio-flow.dot +5 -5
- data/documentation/diagrams/dot/sessions-cron-automation.dot +1 -1
- data/documentation/diagrams/dot/swarm-multi-agent.dot +3 -3
- data/documentation/diagrams/dot/task-summarizer.dot +2 -2
- data/documentation/diagrams/dot/web-application-testing.dot +4 -3
- data/documentation/diagrams/dot/zero-day-research-flow.dot +4 -3
- data/documentation/diagrams/driver-framework.svg +1 -1
- data/documentation/diagrams/extrospection-world-awareness.svg +178 -178
- data/documentation/diagrams/fuzzing-workflow.svg +58 -58
- data/documentation/diagrams/history-to-drivers.svg +42 -42
- data/documentation/diagrams/memory-skills-detailed.svg +210 -210
- data/documentation/diagrams/mistakes-negative-feedback.svg +116 -116
- data/documentation/diagrams/overall-pwn-architecture.svg +248 -404
- data/documentation/diagrams/persistence-filesystem.svg +143 -143
- data/documentation/diagrams/plugin-ecosystem.svg +100 -100
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +233 -752
- data/documentation/diagrams/pwn-repl-prototyping.svg +27 -27
- data/documentation/diagrams/reinforcement-learning.svg +295 -221
- data/documentation/diagrams/reporting-pipeline.svg +94 -80
- data/documentation/diagrams/reverse-engineering-flow.svg +31 -31
- data/documentation/diagrams/sdr-radio-flow.svg +157 -155
- data/documentation/diagrams/sessions-cron-automation.svg +13 -13
- data/documentation/diagrams/swarm-multi-agent.svg +86 -86
- data/documentation/diagrams/task-summarizer.svg +57 -57
- data/documentation/diagrams/web-application-testing.svg +81 -75
- data/documentation/diagrams/zero-day-research-flow.svg +101 -92
- data/documentation/pwn-REPL.md +5 -3
- data/documentation/pwn-ai-Agent.md +18 -14
- data/documentation/pwn_silent_help_learn_demo.gif +0 -0
- data/etc/default_skills/pwn/ai/agent/learning/SKILL.md +1 -0
- data/lib/pwn/ai/agent/learning.rb +46 -1
- data/lib/pwn/ai/agent/loop.rb +6 -3
- data/lib/pwn/ai/agent/policy_evaluation.rb +5 -1
- data/lib/pwn/ai/agent/reward.rb +9 -0
- data/lib/pwn/version.rb +1 -1
- data/spec/fixtures/harness/completion_regressions.json +10 -0
- data/spec/fixtures/harness/completion_regressions.json.sha256 +1 -0
- data/spec/integration/harness_evaluation_spec.rb +13 -0
- data/spec/lib/pwn/ai/agent/learning_spec.rb +22 -0
- data/spec/lib/pwn/ai/agent/loop_spec.rb +39 -0
- data/spec/lib/pwn/ai/agent/policy_evaluation_spec.rb +6 -1
- data/spec/lib/pwn/ai/agent/reward_spec.rb +21 -0
- data/spec/support/harness/evaluate.rb +1 -1
- data/third_party/pwn_rdoc.jsonl +2 -1
- metadata +10 -7
data/lib/pwn/ai/agent/loop.rb
CHANGED
|
@@ -2195,7 +2195,8 @@ module PWN
|
|
|
2195
2195
|
pairs.each do |pair|
|
|
2196
2196
|
tool = pair.find { |m| m[:role].to_s == 'tool' }
|
|
2197
2197
|
prev = collapsed.last&.find { |m| m[:role].to_s == 'tool' }
|
|
2198
|
-
|
|
2198
|
+
# Compare raw bytes: existing history may contain malformed tool output.
|
|
2199
|
+
next if tool && prev && tool[:content].to_s.b.strip == prev[:content].to_s.b.strip
|
|
2199
2200
|
|
|
2200
2201
|
collapsed << pair
|
|
2201
2202
|
end
|
|
@@ -2241,8 +2242,10 @@ module PWN
|
|
|
2241
2242
|
FileUtils.mkdir_p(dir)
|
|
2242
2243
|
path = File.join(dir, "#{digest[0, 12]}.txt")
|
|
2243
2244
|
File.binwrite(path, text) unless File.file?(path)
|
|
2244
|
-
|
|
2245
|
-
|
|
2245
|
+
# Keep the artifact/digest byte-exact; only the displayed excerpt is text.
|
|
2246
|
+
# Byte slicing can bisect a multibyte character at either boundary.
|
|
2247
|
+
head = text.byteslice(0, 2_048).to_s.dup.force_encoding(Encoding::UTF_8).scrub
|
|
2248
|
+
tail = text.bytesize > 3_072 ? text.byteslice(-1_024, 1_024).to_s.dup.force_encoding(Encoding::UTF_8).scrub : ''
|
|
2246
2249
|
mid = tail.empty? ? '' : "\n...\n#{tail}"
|
|
2247
2250
|
"#{head}#{mid}\n[compacted path=#{path} sha256=#{digest} bytes=#{text.bytesize} ref=#{path}]"
|
|
2248
2251
|
rescue StandardError
|
|
@@ -87,7 +87,9 @@ module PWN
|
|
|
87
87
|
File.open(backup, File::WRONLY | File::CREAT | File::EXCL, 0o600) { |file| file.write(baseline) }
|
|
88
88
|
end
|
|
89
89
|
replace(path: live, bytes: candidate)
|
|
90
|
-
{ promoted: true,
|
|
90
|
+
{ promoted: true, receipt_version: 1, change_kind: 'routing_policy',
|
|
91
|
+
acceptance_sha256: Digest::SHA256.hexdigest(JSON.generate(deterministic(value: replayed))),
|
|
92
|
+
live_path: live, rollback_path: backup, baseline_sha256: prior_digest,
|
|
91
93
|
candidate_sha256: candidate_digest, replayed_seeds: replayed.map { |r| r[:seed] } }
|
|
92
94
|
rescue StandardError => e
|
|
93
95
|
{ promoted: false, reason: e.message }
|
|
@@ -98,6 +100,8 @@ module PWN
|
|
|
98
100
|
raise ArgumentError, 'stop all policy writers and set quiescent: true' unless opts[:quiescent] == true
|
|
99
101
|
|
|
100
102
|
receipt = opts.fetch(:receipt)
|
|
103
|
+
raise ArgumentError, 'successful versioned policy promotion receipt required' unless receipt[:promoted] == true && receipt[:receipt_version] == 1 && receipt[:change_kind] == 'routing_policy' && receipt[:acceptance_sha256].to_s.match?(/\A[0-9a-f]{64}\z/)
|
|
104
|
+
|
|
101
105
|
live = File.expand_path(opts.fetch(:live_path))
|
|
102
106
|
prior_digest = receipt.fetch(:baseline_sha256)
|
|
103
107
|
raise ArgumentError, 'invalid rollback digest' unless prior_digest.is_a?(String) && prior_digest.match?(/\A[0-9a-f]{64}\z/)
|
data/lib/pwn/ai/agent/reward.rb
CHANGED
|
@@ -180,6 +180,9 @@ module PWN
|
|
|
180
180
|
v[:confidence] = [v[:confidence].to_f, ground[:confidence].to_f].max if ground[:confidence]
|
|
181
181
|
end
|
|
182
182
|
|
|
183
|
+
# Preserve the evaluator's original completion claim before verification
|
|
184
|
+
# can lower its verdict. This is diagnostic, never acceptance evidence.
|
|
185
|
+
v[:claimed_completion] = v[:verdict].to_s == 'solved'
|
|
183
186
|
v[:judge_score] = v[:score].to_f
|
|
184
187
|
v[:score_quality] = v[:score].to_f
|
|
185
188
|
v[:verification] = if opts[:verification].is_a?(Hash)
|
|
@@ -272,6 +275,12 @@ module PWN
|
|
|
272
275
|
:pass
|
|
273
276
|
end
|
|
274
277
|
end
|
|
278
|
+
v[:verified_completion] = vv.nil? ? nil : vv == :pass
|
|
279
|
+
v[:false_completion] = if v[:claimed_completion] == true
|
|
280
|
+
vv.nil? ? nil : vv == :fail
|
|
281
|
+
elsif v[:claimed_completion] == false
|
|
282
|
+
false
|
|
283
|
+
end
|
|
275
284
|
v[:verifier_verdict] = vv
|
|
276
285
|
v[:confidence] = 1.0 if vv
|
|
277
286
|
if vv == :fail || v.dig(:grounded, :verdict).to_s == 'refuted'
|
data/lib/pwn/version.rb
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "pwn-completion-regressions-v1",
|
|
3
|
+
"split": "regression",
|
|
4
|
+
"provenance": "Source-reproduced HarnessEvaluation.grade false-success accounting defects: vacuous empty checks, nonzero process exit despite correct bytes, and resource cap despite correct bytes. These are public regression stimuli, not held-out learning evidence.",
|
|
5
|
+
"cases": [
|
|
6
|
+
{"id": "empty-acceptance-claim", "checks": [], "result": {"stdout": "DONE", "exit_status": 0, "resource_cap": false}, "outcome": "FAIL"},
|
|
7
|
+
{"id": "failed-process-claim", "checks": [{"path": "result.txt", "bytes": "correct"}], "result": {"stdout": "DONE", "exit_status": 1, "resource_cap": false}, "outcome": "FAIL"},
|
|
8
|
+
{"id": "capped-process-claim", "checks": [{"path": "result.txt", "bytes": "correct"}], "result": {"stdout": "DONE", "exit_status": 0, "resource_cap": true}, "outcome": "INCOMPLETE"}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9368d0704929f9ed4ab448f8bfb0958d19de89cb09a934d20d2cb0a36a22ee7b
|
|
@@ -23,6 +23,19 @@ RSpec.describe 'offline harness evaluation' do
|
|
|
23
23
|
expect { HarnessEvaluation.validate_parity!(pinned, pinned.merge('provider' => 'different')) }.to raise_error(ArgumentError)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
it 'counts claims without checks, nonzero exits, and capped claims as false completion' do
|
|
27
|
+
Dir.mktmpdir do |root|
|
|
28
|
+
corpus = HarnessExperiments.locked_json(File.join(HarnessEvaluation::ROOT, 'spec/fixtures/harness/completion_regressions.json'))
|
|
29
|
+
expect(corpus.fetch('split')).to eq('regression')
|
|
30
|
+
File.write(File.join(root, 'result.txt'), 'correct')
|
|
31
|
+
corpus.fetch('cases').each do |failure|
|
|
32
|
+
task = { 'checks' => failure.fetch('checks'), 'success_marker' => 'DONE' }
|
|
33
|
+
result = failure.fetch('result').transform_keys(&:to_sym)
|
|
34
|
+
expect(HarnessEvaluation.grade(task, root, result)).to include(outcome: failure.fetch('outcome'), false_success: true), failure.fetch('id')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
26
39
|
it 'grades independent bytes and counts observed repeated identities, not tool attempts' do
|
|
27
40
|
Dir.mktmpdir do |root|
|
|
28
41
|
File.write(File.join(root, 'result.txt'), 'wrong')
|
|
@@ -5,6 +5,28 @@ require 'tmpdir'
|
|
|
5
5
|
require 'fileutils'
|
|
6
6
|
|
|
7
7
|
describe PWN::AI::Agent::Learning do
|
|
8
|
+
describe 'failure regression tasks' do
|
|
9
|
+
include_context 'pwn tmp sandbox'
|
|
10
|
+
|
|
11
|
+
it 'exports a reviewed replay recipe only for a persisted independently verified failure' do
|
|
12
|
+
request = 'Write result.txt'
|
|
13
|
+
checks = [{ requirement: request, kind: :file, path: 'result.txt', expected: 'correct' }]
|
|
14
|
+
verification = PWN::AI::Agent::Verification.run(request: request, requirements: [request], checks: checks, root: @tmp)
|
|
15
|
+
row = described_class.note_outcome(task: request, outcome: { score: 0.9, source: :llm_orm, claimed_completion: true, verification: verification })
|
|
16
|
+
recipe = described_class.regression_task(outcome_id: row[:id], request: request, checks: checks)
|
|
17
|
+
expect(recipe).to include(schema: 'pwn-failure-regression-v1', split: 'regression', source_outcome_id: row[:id])
|
|
18
|
+
expect(recipe[:source_verification_sha256]).to eq(Digest::SHA256.hexdigest(JSON.generate(row[:verification])))
|
|
19
|
+
replay = PWN::AI::Agent::Verification.run(recipe[:contract].merge(root: @tmp))
|
|
20
|
+
expect(replay[:status]).to eq(:fail)
|
|
21
|
+
File.write(File.join(@tmp, 'result.txt'), 'correct')
|
|
22
|
+
expect(PWN::AI::Agent::Verification.run(recipe[:contract].merge(root: @tmp))[:status]).to eq(:pass)
|
|
23
|
+
expect { described_class.regression_task(outcome_id: row[:id], request: 'other', checks: checks) }.to raise_error(ArgumentError, /request/)
|
|
24
|
+
expect { described_class.regression_task(outcome_id: row[:id], request: request, checks: []) }.to raise_error(ArgumentError, /coverage/)
|
|
25
|
+
expect { described_class.regression_task(outcome_id: row[:id], request: request, checks: checks.map { |c| c.merge(path: '../escape') }) }.to raise_error(ArgumentError, /relative/)
|
|
26
|
+
expect { described_class.regression_task(outcome_id: 'missing', request: request, checks: checks) }.to raise_error(ArgumentError, /verified failure/)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
8
30
|
describe 'evidence failure safety' do
|
|
9
31
|
before do
|
|
10
32
|
home = Dir.mktmpdir
|
|
@@ -1304,6 +1304,45 @@ describe PWN::AI::Agent::Loop do # rubocop:disable Metrics/BlockLength
|
|
|
1304
1304
|
expect(src).not_to match(/compact_history!\(messages: messages\) if local/)
|
|
1305
1305
|
end
|
|
1306
1306
|
|
|
1307
|
+
it 'keeps UTF-8 previews valid across repeated history compaction' do
|
|
1308
|
+
Dir.mktmpdir('pwn-history-encoding') do |dir|
|
|
1309
|
+
allow(Dir).to receive(:home).and_return(dir)
|
|
1310
|
+
messages = [{ role: 'system', content: 'sys' }, { role: 'user', content: 'goal' }]
|
|
1311
|
+
8.times do |n|
|
|
1312
|
+
messages << { role: 'assistant', content: '', tool_calls: [{ id: "c#{n}" }] }
|
|
1313
|
+
messages << { role: 'tool', tool_call_id: "c#{n}", content: "a#{'é' * 3000}#{n}" }
|
|
1314
|
+
end
|
|
1315
|
+
2.times do
|
|
1316
|
+
expect { described_class.send(:compact_history!, messages: messages) }.not_to output(/compact_history swallowed/).to_stderr
|
|
1317
|
+
expect(messages.all? { |msg| msg[:content].valid_encoding? }).to be(true)
|
|
1318
|
+
end
|
|
1319
|
+
end
|
|
1320
|
+
end
|
|
1321
|
+
|
|
1322
|
+
it 'preserves raw spilled bytes while rendering malformed and binary-tagged text safely' do
|
|
1323
|
+
Dir.mktmpdir('pwn-history-binary') do |dir|
|
|
1324
|
+
allow(Dir).to receive(:home).and_return(dir)
|
|
1325
|
+
["a#{'é' * 3000}".b, "a\xff#{'é' * 3000}"].each do |text|
|
|
1326
|
+
preview = described_class.send(:spill_tool_body, text: text)
|
|
1327
|
+
expect(preview.encoding).to eq(Encoding::UTF_8)
|
|
1328
|
+
expect(preview.valid_encoding?).to be(true)
|
|
1329
|
+
expect(preview).to include('é', '[compacted path=')
|
|
1330
|
+
path = preview[/\[compacted path=(.*?) sha256=/, 1]
|
|
1331
|
+
expect(File.binread(path)).to eq(text.b)
|
|
1332
|
+
end
|
|
1333
|
+
end
|
|
1334
|
+
end
|
|
1335
|
+
|
|
1336
|
+
it 'compacts existing malformed tool history without swallowing encoding errors' do
|
|
1337
|
+
messages = [{ role: 'system', content: 'sys' }, { role: 'user', content: 'goal' }]
|
|
1338
|
+
8.times do |n|
|
|
1339
|
+
messages << { role: 'assistant', tool_calls: [{ id: "c#{n}" }] }
|
|
1340
|
+
messages << { role: 'tool', tool_call_id: "c#{n}", content: "invalid\xff#{n}" }
|
|
1341
|
+
end
|
|
1342
|
+
expect { described_class.send(:compact_history!, messages: messages) }.not_to output(/compact_history swallowed/).to_stderr
|
|
1343
|
+
expect(messages.count { |msg| msg[:role] == 'tool' }).to eq(6)
|
|
1344
|
+
end
|
|
1345
|
+
|
|
1307
1346
|
it 'shrinks tool bodies when history is fat' do
|
|
1308
1347
|
msgs = [
|
|
1309
1348
|
{ role: 'system', content: 'sys' },
|
|
@@ -100,7 +100,12 @@ describe 'PWN::AI::Agent::PolicyEvaluation' do
|
|
|
100
100
|
File.unlink(live)
|
|
101
101
|
File.write(live, File.read(baseline))
|
|
102
102
|
result = evaluator.promote(enabled: true, quiescent: true, baseline: baseline, candidate: candidate, reports: reports, live_path: live)
|
|
103
|
-
expect(result).to include(promoted: true)
|
|
103
|
+
expect(result).to include(promoted: true, receipt_version: 1, change_kind: 'routing_policy')
|
|
104
|
+
expect(result[:acceptance_sha256]).to match(/\A[0-9a-f]{64}\z/)
|
|
105
|
+
[result.merge(promoted: false), result.merge(receipt_version: 2), result.except(:receipt_version), result.merge(change_kind: 'skill'), result.merge(acceptance_sha256: 'invalid')].each do |invalid|
|
|
106
|
+
expect(evaluator.rollback(enabled: true, quiescent: true, live_path: live, receipt: invalid)).to include(rolled_back: false, reason: /receipt/)
|
|
107
|
+
expect(File.binread(live)).to eq(File.binread(candidate))
|
|
108
|
+
end
|
|
104
109
|
expect(File.binread(live)).to eq(File.binread(candidate))
|
|
105
110
|
expect(File.binread(result[:rollback_path])).to eq(File.binread(baseline))
|
|
106
111
|
expect(result[:replayed_seeds]).to eq([0, 1])
|
|
@@ -4,6 +4,27 @@ require 'spec_helper'
|
|
|
4
4
|
require 'tmpdir'
|
|
5
5
|
|
|
6
6
|
describe PWN::AI::Agent::Reward do
|
|
7
|
+
describe 'completion accounting' do
|
|
8
|
+
include_context 'pwn tmp sandbox'
|
|
9
|
+
|
|
10
|
+
it 'preserves a refuted completion claim through resolution and durable learning' do
|
|
11
|
+
request = 'Write answer.txt'
|
|
12
|
+
report = PWN::AI::Agent::Verification.run(request: request, requirements: [request], root: @tmp,
|
|
13
|
+
checks: [{ requirement: request, kind: :file, path: 'answer.txt', expected: 'correct' }])
|
|
14
|
+
result = described_class.resolve_outcome(outcome: { score: 0.95, source: :llm_orm, claimed_completion: true, verification: report })
|
|
15
|
+
expect(result).to include(verified_completion: false, false_completion: true)
|
|
16
|
+
expect(described_class.resolve_outcome(outcome: result)).to eq(result)
|
|
17
|
+
row = PWN::AI::Agent::Learning.note_outcome(task: request, outcome: result)
|
|
18
|
+
expect(row).to include(claimed_completion: true, verified_completion: false, false_completion: true)
|
|
19
|
+
expect(PWN::AI::Agent::Learning.stats).to include(completion_claims: 1, false_completions: 1, verified_completions: 0)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'keeps unverified claims unknown rather than labeling them false or verified' do
|
|
23
|
+
result = described_class.resolve_outcome(outcome: { score: 0.95, source: :llm_orm, claimed_completion: true })
|
|
24
|
+
expect(result).to include(verified_completion: nil, false_completion: nil)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
7
28
|
describe 'labeled transcript calibration' do
|
|
8
29
|
include_context 'pwn tmp sandbox'
|
|
9
30
|
|
|
@@ -62,7 +62,7 @@ module HarnessEvaluation
|
|
|
62
62
|
passed ? 'PASS' : 'FAIL'
|
|
63
63
|
end
|
|
64
64
|
{ outcome: outcome, checks: checks, tool_timeouts: timeouts,
|
|
65
|
-
false_success: claimed &&
|
|
65
|
+
false_success: claimed && outcome != 'PASS',
|
|
66
66
|
repeated_effects: effects.tally.values.sum { |count| count - 1 }, observed_effects: effects }
|
|
67
67
|
end
|
|
68
68
|
|
data/third_party/pwn_rdoc.jsonl
CHANGED
|
@@ -357,6 +357,7 @@
|
|
|
357
357
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.reconcile_verdict_tags! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.reconcile_verdict_tags!`: "}]}
|
|
358
358
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.recover_predicted_from_session Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.recover_predicted_from_session`: "}]}
|
|
359
359
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.reflect Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.reflect`: Supported Method Parameters\n\nreport = PWN::AI::Agent::Learning.reflect(\n\nsession_id: 'required - PWN::Sessions id to analyse',\ndry_run: 'optional - when true, do not write to Memory/Skills (default false)'\n\n)\n\nUses PWN::AI::Agent::Reflect (when available) to LLM-summarise the session into structured lessons. Falls back to a heuristic extractor when module_reflection is disabled so learning never stops.\n"}]}
|
|
360
|
+
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.regression_task Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.regression_task`: "}]}
|
|
360
361
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.requeue_conflicted Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.requeue_conflicted`: "}]}
|
|
361
362
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.reset Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.reset`: Supported Method Parameters\n\nPWN::AI::Agent::Learning.reset\n"}]}
|
|
362
363
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.rl_skill_notes Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.rl_skill_notes`: "}]}
|
|
@@ -368,7 +369,7 @@
|
|
|
368
369
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.should_gc_stores? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.should_gc_stores?`: "}]}
|
|
369
370
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.skill_body_without_frontmatter Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.skill_body_without_frontmatter`: "}]}
|
|
370
371
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.skills_dir Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.skills_dir`: "}]}
|
|
371
|
-
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.stats Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.stats`:
|
|
372
|
+
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.stats Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.stats`: "}]}
|
|
372
373
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.to_context Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.to_context`: Supported Method Parameters\n\nctx = PWN::AI::Agent::Learning.to_context(\n\nlimit: 'optional - number of recent outcomes to surface (default 5)'\n\n)\n"}]}
|
|
373
374
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.transcript_text Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.transcript_text`: "}]}
|
|
374
375
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.update_skill Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.update_skill`: "}]}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.781
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
@@ -505,28 +505,28 @@ dependencies:
|
|
|
505
505
|
requirements:
|
|
506
506
|
- - '='
|
|
507
507
|
- !ruby/object:Gem::Version
|
|
508
|
-
version: 1.8.
|
|
508
|
+
version: 1.8.1
|
|
509
509
|
type: :runtime
|
|
510
510
|
prerelease: false
|
|
511
511
|
version_requirements: !ruby/object:Gem::Requirement
|
|
512
512
|
requirements:
|
|
513
513
|
- - '='
|
|
514
514
|
- !ruby/object:Gem::Version
|
|
515
|
-
version: 1.8.
|
|
515
|
+
version: 1.8.1
|
|
516
516
|
- !ruby/object:Gem::Dependency
|
|
517
517
|
name: meshtastic
|
|
518
518
|
requirement: !ruby/object:Gem::Requirement
|
|
519
519
|
requirements:
|
|
520
520
|
- - '='
|
|
521
521
|
- !ruby/object:Gem::Version
|
|
522
|
-
version: 0.0.
|
|
522
|
+
version: 0.0.189
|
|
523
523
|
type: :development
|
|
524
524
|
prerelease: false
|
|
525
525
|
version_requirements: !ruby/object:Gem::Requirement
|
|
526
526
|
requirements:
|
|
527
527
|
- - '='
|
|
528
528
|
- !ruby/object:Gem::Version
|
|
529
|
-
version: 0.0.
|
|
529
|
+
version: 0.0.189
|
|
530
530
|
- !ruby/object:Gem::Dependency
|
|
531
531
|
name: metasm
|
|
532
532
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -953,14 +953,14 @@ dependencies:
|
|
|
953
953
|
requirements:
|
|
954
954
|
- - '='
|
|
955
955
|
- !ruby/object:Gem::Version
|
|
956
|
-
version: 1.92.
|
|
956
|
+
version: 1.92.1
|
|
957
957
|
type: :runtime
|
|
958
958
|
prerelease: false
|
|
959
959
|
version_requirements: !ruby/object:Gem::Requirement
|
|
960
960
|
requirements:
|
|
961
961
|
- - '='
|
|
962
962
|
- !ruby/object:Gem::Version
|
|
963
|
-
version: 1.92.
|
|
963
|
+
version: 1.92.1
|
|
964
964
|
- !ruby/object:Gem::Dependency
|
|
965
965
|
name: rubocop-rake
|
|
966
966
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -1447,6 +1447,7 @@ files:
|
|
|
1447
1447
|
- documentation/Metasploit.md
|
|
1448
1448
|
- documentation/Mistakes.md
|
|
1449
1449
|
- documentation/NmapIt.md
|
|
1450
|
+
- documentation/Operability.md
|
|
1450
1451
|
- documentation/PWN.png
|
|
1451
1452
|
- documentation/Persistence.md
|
|
1452
1453
|
- documentation/Plugin-Degradation.md
|
|
@@ -6579,6 +6580,8 @@ files:
|
|
|
6579
6580
|
- spec/documentation/prompt_version_placeholder_spec.rb
|
|
6580
6581
|
- spec/fixtures/harness/adapters.json
|
|
6581
6582
|
- spec/fixtures/harness/adapters.json.sha256
|
|
6583
|
+
- spec/fixtures/harness/completion_regressions.json
|
|
6584
|
+
- spec/fixtures/harness/completion_regressions.json.sha256
|
|
6582
6585
|
- spec/fixtures/harness/experiment_gold.json
|
|
6583
6586
|
- spec/fixtures/harness/experiment_gold.json.sha256
|
|
6584
6587
|
- spec/fixtures/harness/experiment_tasks.json
|