mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-07-06 03:17:52 +02:00
3ca3f269ee
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>
61 lines
1.7 KiB
Rust
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,
|
|
}
|
|
}
|