test: regression tests for the scope/model/graph fixes + /sandbox dispatch

Lock in the bugs just fixed so they can't come back:
- scope: host-relative "METHOD /path" findings stay in scope; host_of strips
  a leading HTTP method (covered in scope.rs).
- graph_memory: a finding endpoint's method never becomes a HOST node.
- models/rectify: claude-opus-4-6 is in the anthropic catalog and resolves to
  itself instead of being corrected to claude-opus-4-8.
- repl: add /sandbox to ACCEPTED so the completable command is dispatchable
  (every_completable_command_is_accepted_by_the_dispatch now passes).

Full suite: 491 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
CyberSecurityUPandClaude Opus 4.8 committed 2026-10-15 18:05:29 -03:00
1 parent 2502907160
commit 68133f8eb0
4 files changed
+46 -1

No files matched your search

+14
View File
@@ -240,6 +240,20 @@ mod tests {
}
}
#[test]
fn a_known_model_variant_is_not_corrected_to_a_sibling() {
// Regression: claude-opus-4-6 and claude-opus-4-8 differ by one digit.
// Once 4-6 is a real catalog entry it must resolve to itself and never
// be silently rewritten to 4-8 (which is what starved the opus-4-6 run).
let catalog: Vec<String> = [
"anthropic:claude-opus-4-8",
"anthropic:claude-opus-4-6",
"anthropic:claude-sonnet-4-6",
].iter().map(|s| s.to_string()).collect();
assert_eq!(nearest_model("anthropic:claude-opus-4-6", &catalog), None, "4-6 is exact");
assert_eq!(nearest_model("anthropic:claude-opus-4-8", &catalog), None, "4-8 is exact");
}
#[test]
fn a_transposition_is_one_edit_away() {
assert_eq!(distance("/staus", "/status"), 1, "a dropped character");
+1 -1
View File
@@ -154,7 +154,7 @@ pub(crate) const ACCEPTED: &[&str] = &[
"/observe-only", "/offline",
"/onboard", "/only", "/oos", "/outofscope", "/policy", "/providers", "/proxy", "/class", "/classes", "/focus-class", "/compliance", "/comply", "/budget", "/research", "/quick", "/economy", "/eco", "/q", "/quit", "/recon",
"/pause", "/repo", "/report", "/results", "/resume", "/retest", "/revalidate", "/run", "/runs",
"/scope", "/scope-out", "/show", "/status", "/stop", "/sub", "/subscription", "/target",
"/sandbox", "/scope", "/scope-out", "/show", "/status", "/stop", "/sub", "/subscription", "/target",
"/temp-email", "/tempmail", "/theme", "/timeout", "/ua", "/url", "/useragent", "/validate",
"/votes",
];
@@ -2383,6 +2383,28 @@ mod tests {
}
}
#[test]
fn an_endpoint_method_is_not_treated_as_a_host() {
// Regression: "METHOD /path" endpoints must graph under the target host,
// never create a bogus HOST "get"/"post" node (which also split real
// findings off from the target and hid them from the report).
let finding = Finding {
id: "X1".into(),
title: "Search API exposes internals".into(),
cwe: "CWE-200".into(),
severity: "Medium".into(),
endpoint: "GET /api/search?q=x".into(),
review_status: "confirmed".into(),
validated: true,
confidence: 0.9,
..Default::default()
};
let b = build("https://www.evidelo.com.br", "r1", &[finding], None, None);
let dump = export_json(&b);
assert!(!dump.contains("\"get\""), "the HTTP method must not become a host node: {dump}");
assert!(dump.contains("evidelo.com.br"), "the finding must graph under the target host");
}
#[test]
fn secrets_never_become_properties() {
let mut x = f("F1", "SQLi dumps users", "CWE-89", "High", "https://app.test/search?q=1&token=SUPERSECRET", "admin password hash $2y$10$abc");
@@ -1037,6 +1037,15 @@ mod response_tests {
use super::*;
use serde_json::json;
#[test]
fn anthropic_catalog_lists_opus_4_6() {
// Regression: the web console offers claude-opus-4-6, so the harness
// catalog must list it too — otherwise the model id is "corrected" to a
// sibling and the requested model never runs.
let a = providers().into_iter().find(|p| p.key == "anthropic").expect("anthropic provider");
assert!(a.models.contains(&"claude-opus-4-6"), "catalog: {:?}", a.models);
}
#[test]
fn reasoning_models_get_more_headroom() {
for m in ["glm-5.3", "glm-4.6", "deepseek-v4.1", "z-ai/glm-5.3", "qwen3.8-max", "kimi-k3", "o3", "gpt-6-sol"] {