Files
NeuroSploit/neurosploit-rs/crates/harness/src/rl.rs
T
CyberSecurityUP 3ca3f269ee v3.4.x: intelligent agent selection, whitebox, recon/code agents, Gemini, artifacts, RL, XBOW GUI
Harness intelligence:
- After recon, the model SELECTS which specialist agents match the target
  (select_agents) — runs the relevant subset, not blindly top-N
- RL reward store (rl.rs): per-agent weights persist to data/rl_state_rs.json,
  reward validated findings (severity-weighted), decay idle, bias next run
- Run artifacts persisted as JSON + MD (recon, exploitation transcript,
  findings, html report) under runs/<target>-<ts>/ for reuse by other AIs

Whitebox mode:
- run_whitebox: walks a repo, builds bounded source context, runs code agents,
  validates by adversarial vote. CLI `whitebox <path>` + web "White-box" mode

Agents: +12 recon (subdomain/tech/js/api/secrets/dns/content/param/waf/cloud/
graphql/osint) and +24 code SAST reviewers (sqli/cmdi/path/ssrf/xss/deser/
secrets/crypto/authz/idor/xxe/redirect/ssti/race/eval/csrf/random/logging/
upload/mass-assign/jwt/cors). Loader gains recon/ + code/ categories → 249 total

Models: +Google Gemini provider (API + gemini CLI subscription); installed_cli_
backends now detects gemini; chat_cli handles gemini/codex/grok + optional
Playwright MCP (.mcp.json) on the subscription path with autonomy flags

GUI: full XBOW-style redesign — sidebar (Operate/Library), topbar status, mode
segment (black-box/white-box), model panel, live console, severity cards,
agent browser with category filters, models view; responsive + aligned

Verified: cargo build --release clean; CLI agents/whitebox; LIVE subscription
run shows model selecting 23→4 agents, RL update, artifacts written; GUI +
white-box toggle in Playwright.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 11:39:56 -03:00

61 lines
1.7 KiB
Rust

//! Lightweight reinforcement-learning reward store for the harness.
//!
//! Each agent carries a weight in [0.05, 1.0]; validated findings reward it,
//! idle runs decay it slightly. Weights bias agent ordering on future runs and
//! persist to a JSON file so the harness gets sharper over time.
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;
#[derive(Default, Serialize, Deserialize)]
pub struct RlState {
#[serde(default)]
pub weights: HashMap<String, f64>,
#[serde(default)]
pub runs: u64,
}
const ALPHA: f64 = 0.3;
const WMIN: f64 = 0.05;
const WMAX: f64 = 1.0;
impl RlState {
pub fn load(path: &Path) -> RlState {
std::fs::read_to_string(path)
.ok()
.and_then(|s| serde_json::from_str(&s).ok())
.unwrap_or_default()
}
pub fn weight(&self, agent: &str) -> f64 {
*self.weights.get(agent).unwrap_or(&0.5)
}
/// Reward in [-1, 1]; e.g. severity-weighted hits positive, idle negative.
pub fn update(&mut self, agent: &str, reward: f64) {
let w = self.weights.entry(agent.to_string()).or_insert(0.5);
*w = (*w + ALPHA * (reward - *w)).clamp(WMIN, WMAX);
}
pub fn save(&self, path: &Path) {
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Ok(s) = serde_json::to_string_pretty(self) {
let _ = std::fs::write(path, s);
}
}
}
/// Severity → reward weight.
pub fn severity_reward(sev: &str) -> f64 {
match sev {
"Critical" => 1.0,
"High" => 0.7,
"Medium" => 0.4,
"Low" => 0.2,
_ => 0.05,
}
}